mirror of
https://github.com/Abdulazizzn/n8n-enterprise-unlocked.git
synced 2025-12-16 09:36:44 +00:00
test: Migrate Langchain e2e tests to Playwright (#19161)
This commit is contained in:
@@ -1,280 +0,0 @@
|
|||||||
import type { ExecutionError } from 'n8n-workflow';
|
|
||||||
|
|
||||||
import * as logs from '../composables/logs';
|
|
||||||
import {
|
|
||||||
closeManualChatModal,
|
|
||||||
getManualChatMessages,
|
|
||||||
sendManualChatMessage,
|
|
||||||
} from '../composables/modals/chat-modal';
|
|
||||||
import { setCredentialValues } from '../composables/modals/credential-modal';
|
|
||||||
import {
|
|
||||||
clickCreateNewCredential,
|
|
||||||
clickExecuteNode,
|
|
||||||
clickGetBackToCanvas,
|
|
||||||
} from '../composables/ndv';
|
|
||||||
import {
|
|
||||||
addLanguageModelNodeToParent,
|
|
||||||
addMemoryNodeToParent,
|
|
||||||
addNodeToCanvas,
|
|
||||||
addToolNodeToParent,
|
|
||||||
navigateToNewWorkflowPage,
|
|
||||||
openNode,
|
|
||||||
} from '../composables/workflow';
|
|
||||||
import {
|
|
||||||
AGENT_NODE_NAME,
|
|
||||||
AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME,
|
|
||||||
AI_MEMORY_POSTGRES_NODE_NAME,
|
|
||||||
AI_TOOL_CALCULATOR_NODE_NAME,
|
|
||||||
CHAT_TRIGGER_NODE_DISPLAY_NAME,
|
|
||||||
MANUAL_CHAT_TRIGGER_NODE_NAME,
|
|
||||||
MANUAL_TRIGGER_NODE_DISPLAY_NAME,
|
|
||||||
MANUAL_TRIGGER_NODE_NAME,
|
|
||||||
} from '../constants';
|
|
||||||
import { NDV, WorkflowPage as WorkflowPageClass } from '../pages';
|
|
||||||
import { createMockNodeExecutionData, getVisibleSelect, runMockWorkflowExecution } from '../utils';
|
|
||||||
|
|
||||||
const ndv = new NDV();
|
|
||||||
const WorkflowPage = new WorkflowPageClass();
|
|
||||||
|
|
||||||
function createRunDataWithError(inputMessage: string) {
|
|
||||||
return [
|
|
||||||
createMockNodeExecutionData(MANUAL_CHAT_TRIGGER_NODE_NAME, {
|
|
||||||
jsonData: {
|
|
||||||
main: { input: inputMessage },
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
createMockNodeExecutionData(AI_MEMORY_POSTGRES_NODE_NAME, {
|
|
||||||
jsonData: {
|
|
||||||
ai_memory: {
|
|
||||||
json: {
|
|
||||||
action: 'loadMemoryVariables',
|
|
||||||
values: {
|
|
||||||
input: inputMessage,
|
|
||||||
system_message: 'You are a helpful assistant',
|
|
||||||
formatting_instructions:
|
|
||||||
'IMPORTANT: Always call `format_final_json_response` to format your final response!',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
inputOverride: {
|
|
||||||
ai_memory: [
|
|
||||||
[
|
|
||||||
{
|
|
||||||
json: {
|
|
||||||
action: 'loadMemoryVariables',
|
|
||||||
values: {
|
|
||||||
input: inputMessage,
|
|
||||||
system_message: 'You are a helpful assistant',
|
|
||||||
formatting_instructions:
|
|
||||||
'IMPORTANT: Always call `format_final_json_response` to format your final response!',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
],
|
|
||||||
},
|
|
||||||
source: [{ previousNode: AGENT_NODE_NAME, previousNodeRun: 0 }],
|
|
||||||
error: {
|
|
||||||
message: 'Internal error',
|
|
||||||
timestamp: 1722591723244,
|
|
||||||
name: 'NodeOperationError',
|
|
||||||
description: 'Internal error',
|
|
||||||
context: {},
|
|
||||||
cause: {
|
|
||||||
name: 'error',
|
|
||||||
severity: 'FATAL',
|
|
||||||
code: '3D000',
|
|
||||||
file: 'postinit.c',
|
|
||||||
line: '885',
|
|
||||||
routine: 'InitPostgres',
|
|
||||||
} as unknown as Error,
|
|
||||||
} as ExecutionError,
|
|
||||||
metadata: {
|
|
||||||
subRun: [
|
|
||||||
{
|
|
||||||
node: 'Postgres Chat Memory',
|
|
||||||
runIndex: 0,
|
|
||||||
},
|
|
||||||
],
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
createMockNodeExecutionData(AGENT_NODE_NAME, {
|
|
||||||
executionStatus: 'error',
|
|
||||||
error: {
|
|
||||||
level: 'error',
|
|
||||||
tags: {
|
|
||||||
packageName: 'workflow',
|
|
||||||
},
|
|
||||||
context: {},
|
|
||||||
functionality: 'configuration-node',
|
|
||||||
name: 'NodeOperationError',
|
|
||||||
timestamp: 1722591723244,
|
|
||||||
node: {
|
|
||||||
parameters: {
|
|
||||||
notice: '',
|
|
||||||
sessionIdType: 'fromInput',
|
|
||||||
tableName: 'n8n_chat_histories',
|
|
||||||
},
|
|
||||||
id: '6b9141da-0135-4e9d-94d1-2d658cbf48b5',
|
|
||||||
name: 'Postgres Chat Memory',
|
|
||||||
type: '@n8n/n8n-nodes-langchain.memoryPostgresChat',
|
|
||||||
typeVersion: 1,
|
|
||||||
position: [1140, 500],
|
|
||||||
credentials: {
|
|
||||||
postgres: {
|
|
||||||
id: 'RkyZetVpGsSfEAhQ',
|
|
||||||
name: 'Postgres account',
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
messages: ['database "chat11" does not exist'],
|
|
||||||
description: 'Internal error',
|
|
||||||
message: 'Internal error',
|
|
||||||
} as unknown as ExecutionError,
|
|
||||||
}),
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
function setupTestWorkflow(chatTrigger: boolean = false) {
|
|
||||||
// Setup test workflow with AI Agent, Postgres Memory Node (source of error), Calculator Tool, and OpenAI Chat Model
|
|
||||||
if (chatTrigger) {
|
|
||||||
addNodeToCanvas(MANUAL_CHAT_TRIGGER_NODE_NAME, true, false, undefined, true);
|
|
||||||
} else {
|
|
||||||
addNodeToCanvas(MANUAL_TRIGGER_NODE_NAME, true);
|
|
||||||
}
|
|
||||||
|
|
||||||
addNodeToCanvas(AGENT_NODE_NAME, true);
|
|
||||||
|
|
||||||
if (!chatTrigger) {
|
|
||||||
// Remove chat trigger
|
|
||||||
WorkflowPage.getters
|
|
||||||
.canvasNodeByName(CHAT_TRIGGER_NODE_DISPLAY_NAME)
|
|
||||||
.find('[data-test-id="delete-node-button"]')
|
|
||||||
.click({ force: true });
|
|
||||||
|
|
||||||
// Set manual trigger to output standard pinned data
|
|
||||||
openNode(MANUAL_TRIGGER_NODE_DISPLAY_NAME);
|
|
||||||
ndv.actions.editPinnedData();
|
|
||||||
ndv.actions.savePinnedData();
|
|
||||||
ndv.actions.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Calculator is added just to make OpenAI Chat Model work (tools can not be empty with OpenAI model)
|
|
||||||
addToolNodeToParent(AI_TOOL_CALCULATOR_NODE_NAME, AGENT_NODE_NAME);
|
|
||||||
clickGetBackToCanvas();
|
|
||||||
|
|
||||||
addMemoryNodeToParent(AI_MEMORY_POSTGRES_NODE_NAME, AGENT_NODE_NAME);
|
|
||||||
|
|
||||||
clickCreateNewCredential();
|
|
||||||
setCredentialValues({
|
|
||||||
password: 'testtesttest',
|
|
||||||
});
|
|
||||||
|
|
||||||
ndv.getters.parameterInput('sessionIdType').click();
|
|
||||||
getVisibleSelect().contains('Define below').click();
|
|
||||||
ndv.getters.parameterInput('sessionKey').type('asdasd');
|
|
||||||
|
|
||||||
clickGetBackToCanvas();
|
|
||||||
|
|
||||||
addLanguageModelNodeToParent(
|
|
||||||
AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME,
|
|
||||||
AGENT_NODE_NAME,
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
|
|
||||||
clickCreateNewCredential();
|
|
||||||
setCredentialValues({
|
|
||||||
apiKey: 'sk_test_123',
|
|
||||||
});
|
|
||||||
clickGetBackToCanvas();
|
|
||||||
|
|
||||||
WorkflowPage.actions.zoomToFit();
|
|
||||||
}
|
|
||||||
|
|
||||||
function checkMessages(inputMessage: string, outputMessage: string) {
|
|
||||||
const messages = getManualChatMessages();
|
|
||||||
messages.should('have.length', 2);
|
|
||||||
messages.should('contain', inputMessage);
|
|
||||||
messages.should('contain', outputMessage);
|
|
||||||
|
|
||||||
logs.getOverviewPanelBody().should('exist');
|
|
||||||
logs.getLogEntries().should('have.length', 2);
|
|
||||||
logs.getSelectedLogEntry().should('have.text', 'AI Agent');
|
|
||||||
logs.getOutputPanel().should('contain', AI_MEMORY_POSTGRES_NODE_NAME);
|
|
||||||
}
|
|
||||||
|
|
||||||
describe("AI-233 Make root node's logs pane active in case of an error in sub-nodes", () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
navigateToNewWorkflowPage();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should open logs tab by default when there was an error', () => {
|
|
||||||
setupTestWorkflow(true);
|
|
||||||
|
|
||||||
openNode(AGENT_NODE_NAME);
|
|
||||||
|
|
||||||
const inputMessage = 'Test the code tool';
|
|
||||||
|
|
||||||
clickExecuteNode();
|
|
||||||
runMockWorkflowExecution({
|
|
||||||
trigger: () => sendManualChatMessage(inputMessage),
|
|
||||||
runData: createRunDataWithError(inputMessage),
|
|
||||||
lastNodeExecuted: AGENT_NODE_NAME,
|
|
||||||
});
|
|
||||||
|
|
||||||
checkMessages(inputMessage, '[ERROR: Internal error]');
|
|
||||||
closeManualChatModal();
|
|
||||||
|
|
||||||
// Open the AI Agent node to see the logs
|
|
||||||
openNode(AGENT_NODE_NAME);
|
|
||||||
|
|
||||||
// Finally check that logs pane is opened by default
|
|
||||||
ndv.getters.outputDataContainer().should('be.visible');
|
|
||||||
|
|
||||||
ndv.getters.aiOutputModeToggle().should('be.visible');
|
|
||||||
ndv.getters
|
|
||||||
.aiOutputModeToggle()
|
|
||||||
.find('[role="radio"]')
|
|
||||||
.should('have.length', 2)
|
|
||||||
.eq(1)
|
|
||||||
.should('have.attr', 'aria-checked', 'true');
|
|
||||||
|
|
||||||
ndv.getters
|
|
||||||
.outputPanel()
|
|
||||||
.findChildByTestId('node-error-message')
|
|
||||||
.should('be.visible')
|
|
||||||
.should('contain', 'Error in sub-node');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should switch to logs tab on error, when NDV is already opened', () => {
|
|
||||||
setupTestWorkflow(false);
|
|
||||||
|
|
||||||
openNode(AGENT_NODE_NAME);
|
|
||||||
|
|
||||||
const inputMessage = 'Test the code tool';
|
|
||||||
|
|
||||||
runMockWorkflowExecution({
|
|
||||||
trigger: () => clickExecuteNode(),
|
|
||||||
runData: createRunDataWithError(inputMessage),
|
|
||||||
lastNodeExecuted: AGENT_NODE_NAME,
|
|
||||||
});
|
|
||||||
|
|
||||||
// Check that logs pane is opened by default
|
|
||||||
ndv.getters.outputDataContainer().should('be.visible');
|
|
||||||
|
|
||||||
ndv.getters.aiOutputModeToggle().should('be.visible');
|
|
||||||
ndv.getters
|
|
||||||
.aiOutputModeToggle()
|
|
||||||
.find('[role="radio"]')
|
|
||||||
.should('have.length', 2)
|
|
||||||
.eq(1)
|
|
||||||
.should('have.attr', 'aria-checked', 'true');
|
|
||||||
|
|
||||||
ndv.getters
|
|
||||||
.outputPanel()
|
|
||||||
.findChildByTestId('node-error-message')
|
|
||||||
.should('be.visible')
|
|
||||||
.should('contain', 'Error in sub-node');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
@@ -1,549 +0,0 @@
|
|||||||
import {
|
|
||||||
AGENT_NODE_NAME,
|
|
||||||
MANUAL_CHAT_TRIGGER_NODE_NAME,
|
|
||||||
AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME,
|
|
||||||
MANUAL_TRIGGER_NODE_NAME,
|
|
||||||
AI_MEMORY_WINDOW_BUFFER_MEMORY_NODE_NAME,
|
|
||||||
AI_TOOL_CALCULATOR_NODE_NAME,
|
|
||||||
AI_OUTPUT_PARSER_AUTO_FIXING_NODE_NAME,
|
|
||||||
AI_TOOL_CODE_NODE_NAME,
|
|
||||||
AI_TOOL_WIKIPEDIA_NODE_NAME,
|
|
||||||
BASIC_LLM_CHAIN_NODE_NAME,
|
|
||||||
EDIT_FIELDS_SET_NODE_NAME,
|
|
||||||
CHAT_TRIGGER_NODE_DISPLAY_NAME,
|
|
||||||
} from './../constants';
|
|
||||||
import * as logs from '../composables/logs';
|
|
||||||
import {
|
|
||||||
closeManualChatModal,
|
|
||||||
getManualChatInput,
|
|
||||||
getManualChatMessages,
|
|
||||||
getManualChatModal,
|
|
||||||
sendManualChatMessage,
|
|
||||||
} from '../composables/modals/chat-modal';
|
|
||||||
import { setCredentialValues } from '../composables/modals/credential-modal';
|
|
||||||
import * as ndv from '../composables/ndv';
|
|
||||||
import {
|
|
||||||
clickCreateNewCredential,
|
|
||||||
clickExecuteNode,
|
|
||||||
clickGetBackToCanvas,
|
|
||||||
getRunDataInfoCallout,
|
|
||||||
getOutputPanelTable,
|
|
||||||
checkParameterCheckboxInputByName,
|
|
||||||
} from '../composables/ndv';
|
|
||||||
import * as workflow from '../composables/workflow';
|
|
||||||
import {
|
|
||||||
addLanguageModelNodeToParent,
|
|
||||||
addMemoryNodeToParent,
|
|
||||||
addNodeToCanvas,
|
|
||||||
addOutputParserNodeToParent,
|
|
||||||
addToolNodeToParent,
|
|
||||||
clickExecuteWorkflowButton,
|
|
||||||
clickManualChatButton,
|
|
||||||
navigateToNewWorkflowPage,
|
|
||||||
getNodes,
|
|
||||||
openNode,
|
|
||||||
getConnectionBySourceAndTarget,
|
|
||||||
disableNode,
|
|
||||||
getExecuteWorkflowButton,
|
|
||||||
} from '../composables/workflow';
|
|
||||||
import { WorkflowPage } from '../pages';
|
|
||||||
import { createMockNodeExecutionData, runMockWorkflowExecution } from '../utils';
|
|
||||||
|
|
||||||
describe('Langchain Integration', () => {
|
|
||||||
beforeEach(() => {
|
|
||||||
navigateToNewWorkflowPage();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not open chat modal', () => {
|
|
||||||
addNodeToCanvas(MANUAL_TRIGGER_NODE_NAME, true);
|
|
||||||
addNodeToCanvas(EDIT_FIELDS_SET_NODE_NAME, true);
|
|
||||||
|
|
||||||
clickGetBackToCanvas();
|
|
||||||
|
|
||||||
addNodeToCanvas(AGENT_NODE_NAME, true, true);
|
|
||||||
clickGetBackToCanvas();
|
|
||||||
|
|
||||||
addLanguageModelNodeToParent(
|
|
||||||
AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME,
|
|
||||||
AGENT_NODE_NAME,
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
clickGetBackToCanvas();
|
|
||||||
|
|
||||||
clickExecuteWorkflowButton();
|
|
||||||
getManualChatModal().should('not.exist');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should remove test workflow button', () => {
|
|
||||||
addNodeToCanvas('Schedule Trigger', true);
|
|
||||||
addNodeToCanvas(EDIT_FIELDS_SET_NODE_NAME, true);
|
|
||||||
|
|
||||||
clickGetBackToCanvas();
|
|
||||||
|
|
||||||
addNodeToCanvas(AGENT_NODE_NAME, true, true);
|
|
||||||
clickGetBackToCanvas();
|
|
||||||
|
|
||||||
addLanguageModelNodeToParent(
|
|
||||||
AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME,
|
|
||||||
AGENT_NODE_NAME,
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
clickGetBackToCanvas();
|
|
||||||
|
|
||||||
disableNode('Schedule Trigger');
|
|
||||||
getExecuteWorkflowButton().should('not.exist');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add nodes to all Agent node input types', () => {
|
|
||||||
addNodeToCanvas(MANUAL_TRIGGER_NODE_NAME, true);
|
|
||||||
addNodeToCanvas(AGENT_NODE_NAME, true, true);
|
|
||||||
checkParameterCheckboxInputByName('hasOutputParser');
|
|
||||||
clickGetBackToCanvas();
|
|
||||||
|
|
||||||
addLanguageModelNodeToParent(
|
|
||||||
AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME,
|
|
||||||
AGENT_NODE_NAME,
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
clickGetBackToCanvas();
|
|
||||||
|
|
||||||
addMemoryNodeToParent(AI_MEMORY_WINDOW_BUFFER_MEMORY_NODE_NAME, AGENT_NODE_NAME);
|
|
||||||
clickGetBackToCanvas();
|
|
||||||
|
|
||||||
addToolNodeToParent(AI_TOOL_CALCULATOR_NODE_NAME, AGENT_NODE_NAME);
|
|
||||||
clickGetBackToCanvas();
|
|
||||||
|
|
||||||
addOutputParserNodeToParent(AI_OUTPUT_PARSER_AUTO_FIXING_NODE_NAME, AGENT_NODE_NAME);
|
|
||||||
clickGetBackToCanvas();
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add multiple tool nodes to Agent node tool input type', () => {
|
|
||||||
addNodeToCanvas(MANUAL_TRIGGER_NODE_NAME, true);
|
|
||||||
addNodeToCanvas(AGENT_NODE_NAME, true);
|
|
||||||
|
|
||||||
[
|
|
||||||
AI_TOOL_CALCULATOR_NODE_NAME,
|
|
||||||
AI_TOOL_CODE_NODE_NAME,
|
|
||||||
AI_TOOL_CODE_NODE_NAME,
|
|
||||||
AI_TOOL_CODE_NODE_NAME,
|
|
||||||
AI_TOOL_WIKIPEDIA_NODE_NAME,
|
|
||||||
].forEach((tool) => {
|
|
||||||
addToolNodeToParent(tool, AGENT_NODE_NAME);
|
|
||||||
clickGetBackToCanvas();
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be able to open and execute Basic LLM Chain node', () => {
|
|
||||||
addNodeToCanvas(MANUAL_CHAT_TRIGGER_NODE_NAME, true, false, undefined, true);
|
|
||||||
addNodeToCanvas(BASIC_LLM_CHAIN_NODE_NAME, true);
|
|
||||||
|
|
||||||
addLanguageModelNodeToParent(
|
|
||||||
AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME,
|
|
||||||
BASIC_LLM_CHAIN_NODE_NAME,
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
|
|
||||||
clickCreateNewCredential();
|
|
||||||
setCredentialValues({
|
|
||||||
apiKey: 'sk_test_123',
|
|
||||||
});
|
|
||||||
clickGetBackToCanvas();
|
|
||||||
|
|
||||||
openNode(BASIC_LLM_CHAIN_NODE_NAME);
|
|
||||||
const inputMessage = 'Hello!';
|
|
||||||
const outputMessage = 'Hi there! How can I assist you today?';
|
|
||||||
|
|
||||||
clickExecuteNode();
|
|
||||||
runMockWorkflowExecution({
|
|
||||||
trigger: () => sendManualChatMessage(inputMessage),
|
|
||||||
runData: [
|
|
||||||
createMockNodeExecutionData(BASIC_LLM_CHAIN_NODE_NAME, {
|
|
||||||
jsonData: {
|
|
||||||
main: { output: outputMessage },
|
|
||||||
},
|
|
||||||
metadata: {
|
|
||||||
subRun: [{ node: AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME, runIndex: 0 }],
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
],
|
|
||||||
lastNodeExecuted: BASIC_LLM_CHAIN_NODE_NAME,
|
|
||||||
});
|
|
||||||
|
|
||||||
getManualChatMessages().should('contain', outputMessage);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should be able to open and execute Agent node', () => {
|
|
||||||
addNodeToCanvas(MANUAL_CHAT_TRIGGER_NODE_NAME, true, false, undefined, 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();
|
|
||||||
|
|
||||||
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,
|
|
||||||
});
|
|
||||||
|
|
||||||
getManualChatMessages().should('contain', outputMessage);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should add and use Manual Chat Trigger node together with Agent node', () => {
|
|
||||||
addNodeToCanvas(MANUAL_CHAT_TRIGGER_NODE_NAME, true, false, undefined, 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();
|
|
||||||
|
|
||||||
clickManualChatButton();
|
|
||||||
|
|
||||||
const inputMessage = 'Hello!';
|
|
||||||
const outputMessage = 'Hi there! How can I assist you today?';
|
|
||||||
const runData = [
|
|
||||||
createMockNodeExecutionData(MANUAL_CHAT_TRIGGER_NODE_NAME, {
|
|
||||||
jsonData: {
|
|
||||||
main: { input: inputMessage },
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
createMockNodeExecutionData(AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME, {
|
|
||||||
jsonData: {
|
|
||||||
ai_languageModel: {
|
|
||||||
response: {
|
|
||||||
generations: [
|
|
||||||
{
|
|
||||||
text: `{
|
|
||||||
"action": "Final Answer",
|
|
||||||
"action_input": "${outputMessage}"
|
|
||||||
}`,
|
|
||||||
message: {
|
|
||||||
lc: 1,
|
|
||||||
type: 'constructor',
|
|
||||||
id: ['langchain', 'schema', 'AIMessage'],
|
|
||||||
kwargs: {
|
|
||||||
content: `{
|
|
||||||
"action": "Final Answer",
|
|
||||||
"action_input": "${outputMessage}"
|
|
||||||
}`,
|
|
||||||
additional_kwargs: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
generationInfo: { finish_reason: 'stop' },
|
|
||||||
},
|
|
||||||
],
|
|
||||||
llmOutput: {
|
|
||||||
tokenUsage: {
|
|
||||||
completionTokens: 26,
|
|
||||||
promptTokens: 519,
|
|
||||||
totalTokens: 545,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
metadata: {
|
|
||||||
subRun: [{ node: AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME, runIndex: 0 }],
|
|
||||||
},
|
|
||||||
source: [{ previousNode: AGENT_NODE_NAME, previousNodeRun: 0 }],
|
|
||||||
inputOverride: {
|
|
||||||
ai_languageModel: [
|
|
||||||
[
|
|
||||||
{
|
|
||||||
json: {
|
|
||||||
messages: [
|
|
||||||
{
|
|
||||||
lc: 1,
|
|
||||||
type: 'constructor',
|
|
||||||
id: ['langchain', 'schema', 'SystemMessage'],
|
|
||||||
kwargs: {
|
|
||||||
content:
|
|
||||||
'Assistant is a large language model trained by OpenAI.\n\nAssistant is designed to be able to assist with a wide range of tasks, from answering simple questions to providing in-depth explanations and discussions on a wide range of topics. As a language model, Assistant is able to generate human-like text based on the input it receives, allowing it to engage in natural-sounding conversations and provide responses that are coherent and relevant to the topic at hand.\n\nAssistant is constantly learning and improving, and its capabilities are constantly evolving. It is able to process and understand large amounts of text, and can use this knowledge to provide accurate and informative responses to a wide range of questions. Additionally, Assistant is able to generate its own text based on the input it receives, allowing it to engage in discussions and provide explanations and descriptions on a wide range of topics.\n\nOverall, Assistant is a powerful system that can help with a wide range of tasks and provide valuable insights and information on a wide range of topics. Whether you need help with a specific question or just want to have a conversation about a particular topic, Assistant is here to assist. However, above all else, all responses must adhere to the format of RESPONSE FORMAT INSTRUCTIONS.',
|
|
||||||
additional_kwargs: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
{
|
|
||||||
lc: 1,
|
|
||||||
type: 'constructor',
|
|
||||||
id: ['langchain', 'schema', 'HumanMessage'],
|
|
||||||
kwargs: {
|
|
||||||
content:
|
|
||||||
'TOOLS\n------\nAssistant can ask the user to use tools to look up information that may be helpful in answering the users original question. The tools the human can use are:\n\n\n\nRESPONSE FORMAT INSTRUCTIONS\n----------------------------\n\nOutput a JSON markdown code snippet containing a valid JSON object in one of two formats:\n\n**Option 1:**\nUse this if you want the human to use a tool.\nMarkdown code snippet formatted in the following schema:\n\n```json\n{\n "action": string, // The action to take. Must be one of []\n "action_input": string // The input to the action. May be a stringified object.\n}\n```\n\n**Option #2:**\nUse this if you want to respond directly and conversationally to the human. Markdown code snippet formatted in the following schema:\n\n```json\n{\n "action": "Final Answer",\n "action_input": string // You should put what you want to return to use here and make sure to use valid json newline characters.\n}\n```\n\nFor both options, remember to always include the surrounding markdown code snippet delimiters (begin with "```json" and end with "```")!\n\n\nUSER\'S INPUT\n--------------------\nHere is the user\'s input (remember to respond with a markdown code snippet of a json blob with a single action, and NOTHING else):\n\nHello!',
|
|
||||||
additional_kwargs: {},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
options: { stop: ['Observation:'], promptIndex: 0 },
|
|
||||||
},
|
|
||||||
},
|
|
||||||
],
|
|
||||||
],
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
createMockNodeExecutionData(AGENT_NODE_NAME, {
|
|
||||||
jsonData: {
|
|
||||||
main: { output: 'Hi there! How can I assist you today?' },
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
];
|
|
||||||
|
|
||||||
runMockWorkflowExecution({
|
|
||||||
trigger: () => {
|
|
||||||
sendManualChatMessage(inputMessage);
|
|
||||||
},
|
|
||||||
runData,
|
|
||||||
lastNodeExecuted: AGENT_NODE_NAME,
|
|
||||||
});
|
|
||||||
|
|
||||||
const messages = getManualChatMessages();
|
|
||||||
messages.should('have.length', 2);
|
|
||||||
messages.should('contain', inputMessage);
|
|
||||||
messages.should('contain', outputMessage);
|
|
||||||
|
|
||||||
logs.getOverviewPanel().should('be.visible');
|
|
||||||
logs.getLogEntries().should('have.length', 2);
|
|
||||||
logs.getLogEntries().eq(0).should('have.text', 'AI Agent');
|
|
||||||
logs.getLogEntries().eq(1).should('have.text', 'OpenAI Chat Model');
|
|
||||||
|
|
||||||
closeManualChatModal();
|
|
||||||
logs.getOverviewPanelBody().should('not.exist');
|
|
||||||
getManualChatInput().should('not.exist');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should auto-add chat trigger and basic LLM chain when adding LLM node', () => {
|
|
||||||
addNodeToCanvas(AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME, true);
|
|
||||||
|
|
||||||
getConnectionBySourceAndTarget(
|
|
||||||
CHAT_TRIGGER_NODE_DISPLAY_NAME,
|
|
||||||
BASIC_LLM_CHAIN_NODE_NAME,
|
|
||||||
).should('exist');
|
|
||||||
|
|
||||||
getConnectionBySourceAndTarget(
|
|
||||||
AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME,
|
|
||||||
BASIC_LLM_CHAIN_NODE_NAME,
|
|
||||||
).should('exist');
|
|
||||||
getNodes().should('have.length', 3);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should not auto-add nodes if AI nodes are already present', () => {
|
|
||||||
addNodeToCanvas(AGENT_NODE_NAME, true);
|
|
||||||
|
|
||||||
addNodeToCanvas(AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME, true);
|
|
||||||
getConnectionBySourceAndTarget(CHAT_TRIGGER_NODE_DISPLAY_NAME, AGENT_NODE_NAME).should('exist');
|
|
||||||
getNodes().should('have.length', 3);
|
|
||||||
});
|
|
||||||
it('should not auto-add nodes if ChatTrigger is already present', () => {
|
|
||||||
addNodeToCanvas(MANUAL_CHAT_TRIGGER_NODE_NAME, true, false, undefined, true);
|
|
||||||
addNodeToCanvas(AGENT_NODE_NAME, true);
|
|
||||||
|
|
||||||
addNodeToCanvas(AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME, true);
|
|
||||||
getConnectionBySourceAndTarget(CHAT_TRIGGER_NODE_DISPLAY_NAME, AGENT_NODE_NAME).should('exist');
|
|
||||||
getNodes().should('have.length', 3);
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should render runItems for sub-nodes and allow switching between them', () => {
|
|
||||||
const workflowPage = new WorkflowPage();
|
|
||||||
|
|
||||||
cy.visit(workflowPage.url);
|
|
||||||
cy.createFixtureWorkflow('In_memory_vector_store_fake_embeddings.json');
|
|
||||||
workflowPage.actions.zoomToFit();
|
|
||||||
workflowPage.actions.deselectAll();
|
|
||||||
|
|
||||||
workflowPage.actions.executeNode('Populate VS');
|
|
||||||
workflow.waitForSuccessBannerToAppear();
|
|
||||||
|
|
||||||
const assertInputOutputText = (text: string, assertion: 'exist' | 'not.exist') => {
|
|
||||||
ndv.getOutputPanel().contains(text).should(assertion);
|
|
||||||
ndv.getOutputPanel().contains(text).should(assertion);
|
|
||||||
};
|
|
||||||
|
|
||||||
workflowPage.actions.openNode('Character Text Splitter');
|
|
||||||
|
|
||||||
ndv.getOutputRunSelector().should('exist');
|
|
||||||
ndv.getInputRunSelector().should('exist');
|
|
||||||
ndv.getInputRunSelector().find('input').should('include.value', '3 of 3');
|
|
||||||
ndv.getOutputRunSelector().find('input').should('include.value', '3 of 3');
|
|
||||||
assertInputOutputText('Kyiv', 'exist');
|
|
||||||
assertInputOutputText('Berlin', 'not.exist');
|
|
||||||
assertInputOutputText('Prague', 'not.exist');
|
|
||||||
|
|
||||||
ndv.changeOutputRunSelector('2 of 3');
|
|
||||||
assertInputOutputText('Berlin', 'exist');
|
|
||||||
assertInputOutputText('Kyiv', 'not.exist');
|
|
||||||
assertInputOutputText('Prague', 'not.exist');
|
|
||||||
|
|
||||||
ndv.changeOutputRunSelector('1 of 3');
|
|
||||||
assertInputOutputText('Prague', 'exist');
|
|
||||||
assertInputOutputText('Berlin', 'not.exist');
|
|
||||||
assertInputOutputText('Kyiv', 'not.exist');
|
|
||||||
|
|
||||||
ndv.toggleInputRunLinking();
|
|
||||||
ndv.changeOutputRunSelector('2 of 3');
|
|
||||||
ndv.getInputRunSelector().find('input').should('include.value', '1 of 3');
|
|
||||||
ndv.getOutputRunSelector().find('input').should('include.value', '2 of 3');
|
|
||||||
ndv.getInputPanel().contains('Prague').should('exist');
|
|
||||||
ndv.getInputPanel().contains('Berlin').should('not.exist');
|
|
||||||
|
|
||||||
ndv.getOutputPanel().contains('Berlin').should('exist');
|
|
||||||
ndv.getOutputPanel().contains('Prague').should('not.exist');
|
|
||||||
|
|
||||||
ndv.toggleInputRunLinking();
|
|
||||||
ndv.getInputRunSelector().find('input').should('include.value', '1 of 3');
|
|
||||||
ndv.getOutputRunSelector().find('input').should('include.value', '1 of 3');
|
|
||||||
assertInputOutputText('Prague', 'exist');
|
|
||||||
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, false, undefined, 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, false, undefined, 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');
|
|
||||||
});
|
|
||||||
|
|
||||||
it('should execute up to Node 1 when using partial execution', () => {
|
|
||||||
const workflowPage = new WorkflowPage();
|
|
||||||
|
|
||||||
cy.visit(workflowPage.url);
|
|
||||||
cy.createFixtureWorkflow('Test_workflow_chat_partial_execution.json');
|
|
||||||
workflowPage.actions.zoomToFit();
|
|
||||||
|
|
||||||
getManualChatModal().find('main').should('not.exist');
|
|
||||||
openNode('Node 1');
|
|
||||||
ndv.clickExecuteNode();
|
|
||||||
|
|
||||||
getManualChatModal().find('main').should('exist');
|
|
||||||
sendManualChatMessage('Test');
|
|
||||||
|
|
||||||
getManualChatMessages().should('contain', 'this_my_field_1');
|
|
||||||
cy.getByTestId('refresh-session-button').click();
|
|
||||||
getManualChatMessages().should('not.exist');
|
|
||||||
|
|
||||||
sendManualChatMessage('Another test');
|
|
||||||
getManualChatMessages().should('contain', 'this_my_field_3');
|
|
||||||
getManualChatMessages().should('contain', 'this_my_field_4');
|
|
||||||
});
|
|
||||||
});
|
|
||||||
File diff suppressed because one or more lines are too long
@@ -1,77 +0,0 @@
|
|||||||
{
|
|
||||||
"nodes": [
|
|
||||||
{
|
|
||||||
"parameters": {
|
|
||||||
"options": {}
|
|
||||||
},
|
|
||||||
"id": "535fd3dd-e78f-4ffa-a085-79723fc81b38",
|
|
||||||
"name": "When chat message received",
|
|
||||||
"type": "@n8n/n8n-nodes-langchain.chatTrigger",
|
|
||||||
"typeVersion": 1.1,
|
|
||||||
"position": [
|
|
||||||
320,
|
|
||||||
-380
|
|
||||||
],
|
|
||||||
"webhookId": "4fb58136-3481-494a-a30f-d9e064dac186"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"parameters": {
|
|
||||||
"mode": "raw",
|
|
||||||
"jsonOutput": "{\n \"this_my_field_1\": \"value\",\n \"this_my_field_2\": 1\n}\n",
|
|
||||||
"options": {}
|
|
||||||
},
|
|
||||||
"id": "78201ec2-6def-40b7-85e5-97b580d7f642",
|
|
||||||
"name": "Node 1",
|
|
||||||
"type": "n8n-nodes-base.set",
|
|
||||||
"typeVersion": 3.4,
|
|
||||||
"position": [
|
|
||||||
580,
|
|
||||||
-380
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"parameters": {
|
|
||||||
"mode": "raw",
|
|
||||||
"jsonOutput": "{\n \"this_my_field_3\": \"value\",\n \"this_my_field_4\": 1\n}\n",
|
|
||||||
"options": {}
|
|
||||||
},
|
|
||||||
"id": "1cfca06d-3ec3-427f-89f7-1ef321e025ff",
|
|
||||||
"name": "Node 2",
|
|
||||||
"type": "n8n-nodes-base.set",
|
|
||||||
"typeVersion": 3.4,
|
|
||||||
"position": [
|
|
||||||
780,
|
|
||||||
-380
|
|
||||||
]
|
|
||||||
}
|
|
||||||
],
|
|
||||||
"connections": {
|
|
||||||
"When chat message received": {
|
|
||||||
"main": [
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"node": "Node 1",
|
|
||||||
"type": "main",
|
|
||||||
"index": 0
|
|
||||||
}
|
|
||||||
]
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"Node 1": {
|
|
||||||
"main": [
|
|
||||||
[
|
|
||||||
{
|
|
||||||
"node": "Node 2",
|
|
||||||
"type": "main",
|
|
||||||
"index": 0
|
|
||||||
}
|
|
||||||
]
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"pinData": {},
|
|
||||||
"meta": {
|
|
||||||
"templateCredsSetupCompleted": true,
|
|
||||||
"instanceId": "178ef8a5109fc76c716d40bcadb720c455319f7b7a3fd5a39e4f336a091f524a"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,80 @@
|
|||||||
|
{
|
||||||
|
"httpRequest": {
|
||||||
|
"method": "POST",
|
||||||
|
"path": "/v1/chat/completions",
|
||||||
|
"body": {
|
||||||
|
"contentType": "application/json",
|
||||||
|
"type": "JSON",
|
||||||
|
"json": {
|
||||||
|
"model": "gpt-4.1-mini",
|
||||||
|
"stream": false,
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"role": "user",
|
||||||
|
"content": "Hello!"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"rawBytes": "eyJtb2RlbCI6ImdwdC00LjEtbWluaSIsInN0cmVhbSI6ZmFsc2UsIm1lc3NhZ2VzIjpbeyJyb2xlIjoidXNlciIsImNvbnRlbnQiOiJIZWxsbyEifV19"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"httpResponse": {
|
||||||
|
"statusCode": 200,
|
||||||
|
"reasonPhrase": "OK",
|
||||||
|
"headers": {
|
||||||
|
"x-request-id": ["req_b8f45478a83a4dd2b6d3d6c0df25b482"],
|
||||||
|
"x-ratelimit-reset-tokens": ["0s"],
|
||||||
|
"x-ratelimit-reset-requests": ["2ms"],
|
||||||
|
"x-ratelimit-remaining-tokens": ["149999997"]
|
||||||
|
},
|
||||||
|
"body": {
|
||||||
|
"contentType": "application/json",
|
||||||
|
"type": "JSON",
|
||||||
|
"json": {
|
||||||
|
"id": "chatcmpl-CDWB6cgun4QRcijeXQYPQWTaqtLmN",
|
||||||
|
"object": "chat.completion",
|
||||||
|
"created": 1757337992,
|
||||||
|
"model": "gpt-4.1-mini-2025-04-14",
|
||||||
|
"choices": [
|
||||||
|
{
|
||||||
|
"index": 0,
|
||||||
|
"message": {
|
||||||
|
"role": "assistant",
|
||||||
|
"content": "Hello! How can I assist you today?",
|
||||||
|
"refusal": null,
|
||||||
|
"annotations": []
|
||||||
|
},
|
||||||
|
"logprobs": null,
|
||||||
|
"finish_reason": "stop"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"usage": {
|
||||||
|
"prompt_tokens": 9,
|
||||||
|
"completion_tokens": 9,
|
||||||
|
"total_tokens": 18,
|
||||||
|
"prompt_tokens_details": {
|
||||||
|
"cached_tokens": 0,
|
||||||
|
"audio_tokens": 0
|
||||||
|
},
|
||||||
|
"completion_tokens_details": {
|
||||||
|
"reasoning_tokens": 0,
|
||||||
|
"audio_tokens": 0,
|
||||||
|
"accepted_prediction_tokens": 0,
|
||||||
|
"rejected_prediction_tokens": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"service_tier": "default",
|
||||||
|
"system_fingerprint": "fp_6d7dcc9a98"
|
||||||
|
},
|
||||||
|
"rawBytes": "ewogICJpZCI6ICJjaGF0Y21wbC1DRFdCNmNndW40UVJjaWplWFFZUFFXVGFxdExtTiIsCiAgIm9iamVjdCI6ICJjaGF0LmNvbXBsZXRpb24iLAogICJjcmVhdGVkIjogMTc1NzMzNzk5MiwKICAibW9kZWwiOiAiZ3B0LTQuMS1taW5pLTIwMjUtMDQtMTQiLAogICJjaG9pY2VzIjogWwogICAgewogICAgICAiaW5kZXgiOiAwLAogICAgICAibWVzc2FnZSI6IHsKICAgICAgICAicm9sZSI6ICJhc3Npc3RhbnQiLAogICAgICAgICJjb250ZW50IjogIkhlbGxvISBIb3cgY2FuIEkgYXNzaXN0IHlvdSB0b2RheT8iLAogICAgICAgICJyZWZ1c2FsIjogbnVsbCwKICAgICAgICAiYW5ub3RhdGlvbnMiOiBbXQogICAgICB9LAogICAgICAibG9ncHJvYnMiOiBudWxsLAogICAgICAiZmluaXNoX3JlYXNvbiI6ICJzdG9wIgogICAgfQogIF0sCiAgInVzYWdlIjogewogICAgInByb21wdF90b2tlbnMiOiA5LAogICAgImNvbXBsZXRpb25fdG9rZW5zIjogOSwKICAgICJ0b3RhbF90b2tlbnMiOiAxOCwKICAgICJwcm9tcHRfdG9rZW5zX2RldGFpbHMiOiB7CiAgICAgICJjYWNoZWRfdG9rZW5zIjogMCwKICAgICAgImF1ZGlvX3Rva2VucyI6IDAKICAgIH0sCiAgICAiY29tcGxldGlvbl90b2tlbnNfZGV0YWlscyI6IHsKICAgICAgInJlYXNvbmluZ190b2tlbnMiOiAwLAogICAgICAiYXVkaW9fdG9rZW5zIjogMCwKICAgICAgImFjY2VwdGVkX3ByZWRpY3Rpb25fdG9rZW5zIjogMCwKICAgICAgInJlamVjdGVkX3ByZWRpY3Rpb25fdG9rZW5zIjogMAogICAgfQogIH0sCiAgInNlcnZpY2VfdGllciI6ICJkZWZhdWx0IiwKICAic3lzdGVtX2ZpbmdlcnByaW50IjogImZwXzZkN2RjYzlhOTgiCn0K"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"id": "1757337994261-unknown-host-POST-_v1_chat_completions-1561df08.json",
|
||||||
|
"priority": 0,
|
||||||
|
"timeToLive": {
|
||||||
|
"unlimited": true
|
||||||
|
},
|
||||||
|
"times": {
|
||||||
|
"unlimited": true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
{
|
||||||
|
"httpRequest": {
|
||||||
|
"method": "POST",
|
||||||
|
"path": "/v1/chat/completions",
|
||||||
|
"body": {
|
||||||
|
"contentType": "application/json",
|
||||||
|
"type": "JSON",
|
||||||
|
"json": {
|
||||||
|
"model": "gpt-4.1-mini",
|
||||||
|
"stream": false,
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"role": "user",
|
||||||
|
"content": "Hello!"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"rawBytes": "eyJtb2RlbCI6ImdwdC00LjEtbWluaSIsInN0cmVhbSI6ZmFsc2UsIm1lc3NhZ2VzIjpbeyJyb2xlIjoidXNlciIsImNvbnRlbnQiOiJIZWxsbyEifV19"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"httpResponse": {
|
||||||
|
"statusCode": 200,
|
||||||
|
"reasonPhrase": "OK",
|
||||||
|
"headers": {
|
||||||
|
"x-request-id": ["req_11f2fb25bd0b4a758224bba6f1e68e50"],
|
||||||
|
"x-ratelimit-reset-tokens": ["0s"],
|
||||||
|
"x-ratelimit-reset-requests": ["2ms"],
|
||||||
|
"x-ratelimit-remaining-tokens": ["149999995"],
|
||||||
|
"x-ratelimit-remaining-requests": ["29999"],
|
||||||
|
"x-ratelimit-limit-tokens": ["150000000"]
|
||||||
|
},
|
||||||
|
"body": {
|
||||||
|
"contentType": "application/json",
|
||||||
|
"type": "JSON",
|
||||||
|
"json": {
|
||||||
|
"id": "chatcmpl-CDWB7f4flZjMHmcuet4JNe5pRTfVM",
|
||||||
|
"object": "chat.completion",
|
||||||
|
"created": 1757337993,
|
||||||
|
"model": "gpt-4.1-mini-2025-04-14",
|
||||||
|
"choices": [
|
||||||
|
{
|
||||||
|
"index": 0,
|
||||||
|
"message": {
|
||||||
|
"role": "assistant",
|
||||||
|
"content": "Hello! How can I assist you today?",
|
||||||
|
"refusal": null,
|
||||||
|
"annotations": []
|
||||||
|
},
|
||||||
|
"logprobs": null,
|
||||||
|
"finish_reason": "stop"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"usage": {
|
||||||
|
"prompt_tokens": 9,
|
||||||
|
"completion_tokens": 9,
|
||||||
|
"total_tokens": 18,
|
||||||
|
"prompt_tokens_details": {
|
||||||
|
"cached_tokens": 0,
|
||||||
|
"audio_tokens": 0
|
||||||
|
},
|
||||||
|
"completion_tokens_details": {
|
||||||
|
"reasoning_tokens": 0,
|
||||||
|
"audio_tokens": 0,
|
||||||
|
"accepted_prediction_tokens": 0,
|
||||||
|
"rejected_prediction_tokens": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"service_tier": "default",
|
||||||
|
"system_fingerprint": "fp_4fce0778af"
|
||||||
|
},
|
||||||
|
"rawBytes": "ewogICJpZCI6ICJjaGF0Y21wbC1DRFdCN2Y0Zmxaak1IbWN1ZXQ0Sk5lNXBSVGZWTSIsCiAgIm9iamVjdCI6ICJjaGF0LmNvbXBsZXRpb24iLAogICJjcmVhdGVkIjogMTc1NzMzNzk5MywKICAibW9kZWwiOiAiZ3B0LTQuMS1taW5pLTIwMjUtMDQtMTQiLAogICJjaG9pY2VzIjogWwogICAgewogICAgICAiaW5kZXgiOiAwLAogICAgICAibWVzc2FnZSI6IHsKICAgICAgICAicm9sZSI6ICJhc3Npc3RhbnQiLAogICAgICAgICJjb250ZW50IjogIkhlbGxvISBIb3cgY2FuIEkgYXNzaXN0IHlvdSB0b2RheT8iLAogICAgICAgICJyZWZ1c2FsIjogbnVsbCwKICAgICAgICAiYW5ub3RhdGlvbnMiOiBbXQogICAgICB9LAogICAgICAibG9ncHJvYnMiOiBudWxsLAogICAgICAiZmluaXNoX3JlYXNvbiI6ICJzdG9wIgogICAgfQogIF0sCiAgInVzYWdlIjogewogICAgInByb21wdF90b2tlbnMiOiA5LAogICAgImNvbXBsZXRpb25fdG9rZW5zIjogOSwKICAgICJ0b3RhbF90b2tlbnMiOiAxOCwKICAgICJwcm9tcHRfdG9rZW5zX2RldGFpbHMiOiB7CiAgICAgICJjYWNoZWRfdG9rZW5zIjogMCwKICAgICAgImF1ZGlvX3Rva2VucyI6IDAKICAgIH0sCiAgICAiY29tcGxldGlvbl90b2tlbnNfZGV0YWlscyI6IHsKICAgICAgInJlYXNvbmluZ190b2tlbnMiOiAwLAogICAgICAiYXVkaW9fdG9rZW5zIjogMCwKICAgICAgImFjY2VwdGVkX3ByZWRpY3Rpb25fdG9rZW5zIjogMCwKICAgICAgInJlamVjdGVkX3ByZWRpY3Rpb25fdG9rZW5zIjogMAogICAgfQogIH0sCiAgInNlcnZpY2VfdGllciI6ICJkZWZhdWx0IiwKICAic3lzdGVtX2ZpbmdlcnByaW50IjogImZwXzRmY2UwNzc4YWYiCn0K"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"id": "1757337994532-unknown-host-POST-_v1_chat_completions-1561df08.json",
|
||||||
|
"priority": 0,
|
||||||
|
"timeToLive": {
|
||||||
|
"unlimited": true
|
||||||
|
},
|
||||||
|
"times": {
|
||||||
|
"unlimited": true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,82 @@
|
|||||||
|
{
|
||||||
|
"httpRequest": {
|
||||||
|
"method": "POST",
|
||||||
|
"path": "/v1/chat/completions",
|
||||||
|
"body": {
|
||||||
|
"contentType": "application/json",
|
||||||
|
"type": "JSON",
|
||||||
|
"json": {
|
||||||
|
"model": "gpt-4.1-mini",
|
||||||
|
"stream": false,
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"role": "user",
|
||||||
|
"content": "Hello!"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"rawBytes": "eyJtb2RlbCI6ImdwdC00LjEtbWluaSIsInN0cmVhbSI6ZmFsc2UsIm1lc3NhZ2VzIjpbeyJyb2xlIjoidXNlciIsImNvbnRlbnQiOiJIZWxsbyEifV19"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"httpResponse": {
|
||||||
|
"statusCode": 200,
|
||||||
|
"reasonPhrase": "OK",
|
||||||
|
"headers": {
|
||||||
|
"x-request-id": ["req_2476c446b9a74442be397d438277a7c1"],
|
||||||
|
"x-ratelimit-reset-tokens": ["0s"],
|
||||||
|
"x-ratelimit-reset-requests": ["2ms"],
|
||||||
|
"x-ratelimit-remaining-tokens": ["149999995"],
|
||||||
|
"x-ratelimit-remaining-requests": ["29999"],
|
||||||
|
"x-ratelimit-limit-tokens": ["150000000"]
|
||||||
|
},
|
||||||
|
"body": {
|
||||||
|
"contentType": "application/json",
|
||||||
|
"type": "JSON",
|
||||||
|
"json": {
|
||||||
|
"id": "chatcmpl-CDWB6wRC1FBoWeZr36clt56dB1EzT",
|
||||||
|
"object": "chat.completion",
|
||||||
|
"created": 1757337992,
|
||||||
|
"model": "gpt-4.1-mini-2025-04-14",
|
||||||
|
"choices": [
|
||||||
|
{
|
||||||
|
"index": 0,
|
||||||
|
"message": {
|
||||||
|
"role": "assistant",
|
||||||
|
"content": "Hello! How can I assist you today?",
|
||||||
|
"refusal": null,
|
||||||
|
"annotations": []
|
||||||
|
},
|
||||||
|
"logprobs": null,
|
||||||
|
"finish_reason": "stop"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"usage": {
|
||||||
|
"prompt_tokens": 9,
|
||||||
|
"completion_tokens": 9,
|
||||||
|
"total_tokens": 18,
|
||||||
|
"prompt_tokens_details": {
|
||||||
|
"cached_tokens": 0,
|
||||||
|
"audio_tokens": 0
|
||||||
|
},
|
||||||
|
"completion_tokens_details": {
|
||||||
|
"reasoning_tokens": 0,
|
||||||
|
"audio_tokens": 0,
|
||||||
|
"accepted_prediction_tokens": 0,
|
||||||
|
"rejected_prediction_tokens": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"service_tier": "default",
|
||||||
|
"system_fingerprint": "fp_4fce0778af"
|
||||||
|
},
|
||||||
|
"rawBytes": "ewogICJpZCI6ICJjaGF0Y21wbC1DRFdCNndSQzFGQm9XZVpyMzZjbHQ1NmRCMUV6VCIsCiAgIm9iamVjdCI6ICJjaGF0LmNvbXBsZXRpb24iLAogICJjcmVhdGVkIjogMTc1NzMzNzk5MiwKICAibW9kZWwiOiAiZ3B0LTQuMS1taW5pLTIwMjUtMDQtMTQiLAogICJjaG9pY2VzIjogWwogICAgewogICAgICAiaW5kZXgiOiAwLAogICAgICAibWVzc2FnZSI6IHsKICAgICAgICAicm9sZSI6ICJhc3Npc3RhbnQiLAogICAgICAgICJjb250ZW50IjogIkhlbGxvISBIb3cgY2FuIEkgYXNzaXN0IHlvdSB0b2RheT8iLAogICAgICAgICJyZWZ1c2FsIjogbnVsbCwKICAgICAgICAiYW5ub3RhdGlvbnMiOiBbXQogICAgICB9LAogICAgICAibG9ncHJvYnMiOiBudWxsLAogICAgICAiZmluaXNoX3JlYXNvbiI6ICJzdG9wIgogICAgfQogIF0sCiAgInVzYWdlIjogewogICAgInByb21wdF90b2tlbnMiOiA5LAogICAgImNvbXBsZXRpb25fdG9rZW5zIjogOSwKICAgICJ0b3RhbF90b2tlbnMiOiAxOCwKICAgICJwcm9tcHRfdG9rZW5zX2RldGFpbHMiOiB7CiAgICAgICJjYWNoZWRfdG9rZW5zIjogMCwKICAgICAgImF1ZGlvX3Rva2VucyI6IDAKICAgIH0sCiAgICAiY29tcGxldGlvbl90b2tlbnNfZGV0YWlscyI6IHsKICAgICAgInJlYXNvbmluZ190b2tlbnMiOiAwLAogICAgICAiYXVkaW9fdG9rZW5zIjogMCwKICAgICAgImFjY2VwdGVkX3ByZWRpY3Rpb25fdG9rZW5zIjogMCwKICAgICAgInJlamVjdGVkX3ByZWRpY3Rpb25fdG9rZW5zIjogMAogICAgfQogIH0sCiAgInNlcnZpY2VfdGllciI6ICJkZWZhdWx0IiwKICAic3lzdGVtX2ZpbmdlcnByaW50IjogImZwXzRmY2UwNzc4YWYiCn0K"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"id": "1757337995023-unknown-host-POST-_v1_chat_completions-1561df08.json",
|
||||||
|
"priority": 0,
|
||||||
|
"timeToLive": {
|
||||||
|
"unlimited": true
|
||||||
|
},
|
||||||
|
"times": {
|
||||||
|
"unlimited": true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
{
|
||||||
|
"httpRequest": {
|
||||||
|
"method": "POST",
|
||||||
|
"path": "/v1/chat/completions",
|
||||||
|
"body": {
|
||||||
|
"contentType": "application/json",
|
||||||
|
"type": "JSON",
|
||||||
|
"json": {
|
||||||
|
"model": "gpt-4.1-mini",
|
||||||
|
"stream": false,
|
||||||
|
"tools": [
|
||||||
|
{
|
||||||
|
"type": "function",
|
||||||
|
"function": {
|
||||||
|
"name": "calculator",
|
||||||
|
"description": "Useful for getting the result of a math expression. The input to this tool should be a valid mathematical expression that could be executed by a simple calculator.",
|
||||||
|
"parameters": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"input": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false,
|
||||||
|
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"role": "user",
|
||||||
|
"content": "Hello!"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"rawBytes": "eyJtb2RlbCI6ImdwdC00LjEtbWluaSIsInN0cmVhbSI6ZmFsc2UsInRvb2xzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiY2FsY3VsYXRvciIsImRlc2NyaXB0aW9uIjoiVXNlZnVsIGZvciBnZXR0aW5nIHRoZSByZXN1bHQgb2YgYSBtYXRoIGV4cHJlc3Npb24uIFRoZSBpbnB1dCB0byB0aGlzIHRvb2wgc2hvdWxkIGJlIGEgdmFsaWQgbWF0aGVtYXRpY2FsIGV4cHJlc3Npb24gdGhhdCBjb3VsZCBiZSBleGVjdXRlZCBieSBhIHNpbXBsZSBjYWxjdWxhdG9yLiIsInBhcmFtZXRlcnMiOnsidHlwZSI6Im9iamVjdCIsInByb3BlcnRpZXMiOnsiaW5wdXQiOnsidHlwZSI6InN0cmluZyJ9fSwiYWRkaXRpb25hbFByb3BlcnRpZXMiOmZhbHNlLCIkc2NoZW1hIjoiaHR0cDovL2pzb24tc2NoZW1hLm9yZy9kcmFmdC0wNy9zY2hlbWEjIn19fV0sIm1lc3NhZ2VzIjpbeyJyb2xlIjoidXNlciIsImNvbnRlbnQiOiJIZWxsbyEifV19"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"httpResponse": {
|
||||||
|
"statusCode": 200,
|
||||||
|
"reasonPhrase": "OK",
|
||||||
|
"headers": {
|
||||||
|
"x-request-id": ["req_b9dd655cc0ac465980074d2301a4f058"],
|
||||||
|
"x-ratelimit-reset-tokens": ["0s"],
|
||||||
|
"x-ratelimit-reset-requests": ["2ms"],
|
||||||
|
"x-ratelimit-remaining-tokens": ["149999995"],
|
||||||
|
"x-ratelimit-remaining-requests": ["29999"],
|
||||||
|
"x-ratelimit-limit-tokens": ["150000000"]
|
||||||
|
},
|
||||||
|
"body": {
|
||||||
|
"contentType": "application/json",
|
||||||
|
"type": "JSON",
|
||||||
|
"json": {
|
||||||
|
"id": "chatcmpl-CDWBAps4xOl2Ps9V9GQ7RwmRWYGnU",
|
||||||
|
"object": "chat.completion",
|
||||||
|
"created": 1757337996,
|
||||||
|
"model": "gpt-4.1-mini-2025-04-14",
|
||||||
|
"choices": [
|
||||||
|
{
|
||||||
|
"index": 0,
|
||||||
|
"message": {
|
||||||
|
"role": "assistant",
|
||||||
|
"content": "Hello! How can I assist you today?",
|
||||||
|
"refusal": null,
|
||||||
|
"annotations": []
|
||||||
|
},
|
||||||
|
"logprobs": null,
|
||||||
|
"finish_reason": "stop"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"usage": {
|
||||||
|
"prompt_tokens": 68,
|
||||||
|
"completion_tokens": 10,
|
||||||
|
"total_tokens": 78,
|
||||||
|
"prompt_tokens_details": {
|
||||||
|
"cached_tokens": 0,
|
||||||
|
"audio_tokens": 0
|
||||||
|
},
|
||||||
|
"completion_tokens_details": {
|
||||||
|
"reasoning_tokens": 0,
|
||||||
|
"audio_tokens": 0,
|
||||||
|
"accepted_prediction_tokens": 0,
|
||||||
|
"rejected_prediction_tokens": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"service_tier": "default",
|
||||||
|
"system_fingerprint": "fp_4fce0778af"
|
||||||
|
},
|
||||||
|
"rawBytes": "ewogICJpZCI6ICJjaGF0Y21wbC1DRFdCQXBzNHhPbDJQczlWOUdRN1J3bVJXWUduVSIsCiAgIm9iamVjdCI6ICJjaGF0LmNvbXBsZXRpb24iLAogICJjcmVhdGVkIjogMTc1NzMzNzk5NiwKICAibW9kZWwiOiAiZ3B0LTQuMS1taW5pLTIwMjUtMDQtMTQiLAogICJjaG9pY2VzIjogWwogICAgewogICAgICAiaW5kZXgiOiAwLAogICAgICAibWVzc2FnZSI6IHsKICAgICAgICAicm9sZSI6ICJhc3Npc3RhbnQiLAogICAgICAgICJjb250ZW50IjogIkhlbGxvISBIb3cgY2FuIEkgYXNzaXN0IHlvdSB0b2RheT8iLAogICAgICAgICJyZWZ1c2FsIjogbnVsbCwKICAgICAgICAiYW5ub3RhdGlvbnMiOiBbXQogICAgICB9LAogICAgICAibG9ncHJvYnMiOiBudWxsLAogICAgICAiZmluaXNoX3JlYXNvbiI6ICJzdG9wIgogICAgfQogIF0sCiAgInVzYWdlIjogewogICAgInByb21wdF90b2tlbnMiOiA2OCwKICAgICJjb21wbGV0aW9uX3Rva2VucyI6IDEwLAogICAgInRvdGFsX3Rva2VucyI6IDc4LAogICAgInByb21wdF90b2tlbnNfZGV0YWlscyI6IHsKICAgICAgImNhY2hlZF90b2tlbnMiOiAwLAogICAgICAiYXVkaW9fdG9rZW5zIjogMAogICAgfSwKICAgICJjb21wbGV0aW9uX3Rva2Vuc19kZXRhaWxzIjogewogICAgICAicmVhc29uaW5nX3Rva2VucyI6IDAsCiAgICAgICJhdWRpb190b2tlbnMiOiAwLAogICAgICAiYWNjZXB0ZWRfcHJlZGljdGlvbl90b2tlbnMiOiAwLAogICAgICAicmVqZWN0ZWRfcHJlZGljdGlvbl90b2tlbnMiOiAwCiAgICB9CiAgfSwKICAic2VydmljZV90aWVyIjogImRlZmF1bHQiLAogICJzeXN0ZW1fZmluZ2VycHJpbnQiOiAiZnBfNGZjZTA3NzhhZiIKfQo="
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"id": "1757338000172-unknown-host-POST-_v1_chat_completions-fdac7829.json",
|
||||||
|
"priority": 0,
|
||||||
|
"timeToLive": {
|
||||||
|
"unlimited": true
|
||||||
|
},
|
||||||
|
"times": {
|
||||||
|
"unlimited": true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,111 @@
|
|||||||
|
{
|
||||||
|
"httpRequest": {
|
||||||
|
"method": "POST",
|
||||||
|
"path": "/v1/chat/completions",
|
||||||
|
"body": {
|
||||||
|
"contentType": "application/json",
|
||||||
|
"type": "JSON",
|
||||||
|
"json": {
|
||||||
|
"model": "gpt-4.1-mini",
|
||||||
|
"stream": false,
|
||||||
|
"tools": [
|
||||||
|
{
|
||||||
|
"type": "function",
|
||||||
|
"function": {
|
||||||
|
"name": "calculator",
|
||||||
|
"description": "Useful for getting the result of a math expression. The input to this tool should be a valid mathematical expression that could be executed by a simple calculator.",
|
||||||
|
"parameters": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"input": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false,
|
||||||
|
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"role": "user",
|
||||||
|
"content": "What is 1000 * 10?"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"rawBytes": "eyJtb2RlbCI6ImdwdC00LjEtbWluaSIsInN0cmVhbSI6ZmFsc2UsInRvb2xzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiY2FsY3VsYXRvciIsImRlc2NyaXB0aW9uIjoiVXNlZnVsIGZvciBnZXR0aW5nIHRoZSByZXN1bHQgb2YgYSBtYXRoIGV4cHJlc3Npb24uIFRoZSBpbnB1dCB0byB0aGlzIHRvb2wgc2hvdWxkIGJlIGEgdmFsaWQgbWF0aGVtYXRpY2FsIGV4cHJlc3Npb24gdGhhdCBjb3VsZCBiZSBleGVjdXRlZCBieSBhIHNpbXBsZSBjYWxjdWxhdG9yLiIsInBhcmFtZXRlcnMiOnsidHlwZSI6Im9iamVjdCIsInByb3BlcnRpZXMiOnsiaW5wdXQiOnsidHlwZSI6InN0cmluZyJ9fSwiYWRkaXRpb25hbFByb3BlcnRpZXMiOmZhbHNlLCIkc2NoZW1hIjoiaHR0cDovL2pzb24tc2NoZW1hLm9yZy9kcmFmdC0wNy9zY2hlbWEjIn19fV0sIm1lc3NhZ2VzIjpbeyJyb2xlIjoidXNlciIsImNvbnRlbnQiOiJXaGF0IGlzIDEwMDAgKiAxMD8ifV19"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"httpResponse": {
|
||||||
|
"statusCode": 200,
|
||||||
|
"reasonPhrase": "OK",
|
||||||
|
"headers": {
|
||||||
|
"x-request-id": ["req_56023c245be3448c8373ff3aad21f7c4"],
|
||||||
|
"x-ratelimit-reset-tokens": ["0s"],
|
||||||
|
"x-ratelimit-reset-requests": ["2ms"],
|
||||||
|
"x-ratelimit-remaining-tokens": ["149999992"],
|
||||||
|
"x-ratelimit-remaining-requests": ["29999"],
|
||||||
|
"x-ratelimit-limit-tokens": ["150000000"]
|
||||||
|
},
|
||||||
|
"body": {
|
||||||
|
"contentType": "application/json",
|
||||||
|
"type": "JSON",
|
||||||
|
"json": {
|
||||||
|
"id": "chatcmpl-CDWBDR6zMgzDe9t4hkJ0Xq3dxsK3y",
|
||||||
|
"object": "chat.completion",
|
||||||
|
"created": 1757337999,
|
||||||
|
"model": "gpt-4.1-mini-2025-04-14",
|
||||||
|
"choices": [
|
||||||
|
{
|
||||||
|
"index": 0,
|
||||||
|
"message": {
|
||||||
|
"role": "assistant",
|
||||||
|
"content": null,
|
||||||
|
"tool_calls": [
|
||||||
|
{
|
||||||
|
"id": "call_88I326c3cCx7lOEXL3Wpp30c",
|
||||||
|
"type": "function",
|
||||||
|
"function": {
|
||||||
|
"name": "calculator",
|
||||||
|
"arguments": "{\"input\":\"1000 * 10\"}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"refusal": null,
|
||||||
|
"annotations": []
|
||||||
|
},
|
||||||
|
"logprobs": null,
|
||||||
|
"finish_reason": "tool_calls"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"usage": {
|
||||||
|
"prompt_tokens": 75,
|
||||||
|
"completion_tokens": 18,
|
||||||
|
"total_tokens": 93,
|
||||||
|
"prompt_tokens_details": {
|
||||||
|
"cached_tokens": 0,
|
||||||
|
"audio_tokens": 0
|
||||||
|
},
|
||||||
|
"completion_tokens_details": {
|
||||||
|
"reasoning_tokens": 0,
|
||||||
|
"audio_tokens": 0,
|
||||||
|
"accepted_prediction_tokens": 0,
|
||||||
|
"rejected_prediction_tokens": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"service_tier": "default",
|
||||||
|
"system_fingerprint": "fp_4fce0778af"
|
||||||
|
},
|
||||||
|
"rawBytes": "ewogICJpZCI6ICJjaGF0Y21wbC1DRFdCRFI2ek1nekRlOXQ0aGtKMFhxM2R4c0szeSIsCiAgIm9iamVjdCI6ICJjaGF0LmNvbXBsZXRpb24iLAogICJjcmVhdGVkIjogMTc1NzMzNzk5OSwKICAibW9kZWwiOiAiZ3B0LTQuMS1taW5pLTIwMjUtMDQtMTQiLAogICJjaG9pY2VzIjogWwogICAgewogICAgICAiaW5kZXgiOiAwLAogICAgICAibWVzc2FnZSI6IHsKICAgICAgICAicm9sZSI6ICJhc3Npc3RhbnQiLAogICAgICAgICJjb250ZW50IjogbnVsbCwKICAgICAgICAidG9vbF9jYWxscyI6IFsKICAgICAgICAgIHsKICAgICAgICAgICAgImlkIjogImNhbGxfODhJMzI2YzNjQ3g3bE9FWEwzV3BwMzBjIiwKICAgICAgICAgICAgInR5cGUiOiAiZnVuY3Rpb24iLAogICAgICAgICAgICAiZnVuY3Rpb24iOiB7CiAgICAgICAgICAgICAgIm5hbWUiOiAiY2FsY3VsYXRvciIsCiAgICAgICAgICAgICAgImFyZ3VtZW50cyI6ICJ7XCJpbnB1dFwiOlwiMTAwMCAqIDEwXCJ9IgogICAgICAgICAgICB9CiAgICAgICAgICB9CiAgICAgICAgXSwKICAgICAgICAicmVmdXNhbCI6IG51bGwsCiAgICAgICAgImFubm90YXRpb25zIjogW10KICAgICAgfSwKICAgICAgImxvZ3Byb2JzIjogbnVsbCwKICAgICAgImZpbmlzaF9yZWFzb24iOiAidG9vbF9jYWxscyIKICAgIH0KICBdLAogICJ1c2FnZSI6IHsKICAgICJwcm9tcHRfdG9rZW5zIjogNzUsCiAgICAiY29tcGxldGlvbl90b2tlbnMiOiAxOCwKICAgICJ0b3RhbF90b2tlbnMiOiA5MywKICAgICJwcm9tcHRfdG9rZW5zX2RldGFpbHMiOiB7CiAgICAgICJjYWNoZWRfdG9rZW5zIjogMCwKICAgICAgImF1ZGlvX3Rva2VucyI6IDAKICAgIH0sCiAgICAiY29tcGxldGlvbl90b2tlbnNfZGV0YWlscyI6IHsKICAgICAgInJlYXNvbmluZ190b2tlbnMiOiAwLAogICAgICAiYXVkaW9fdG9rZW5zIjogMCwKICAgICAgImFjY2VwdGVkX3ByZWRpY3Rpb25fdG9rZW5zIjogMCwKICAgICAgInJlamVjdGVkX3ByZWRpY3Rpb25fdG9rZW5zIjogMAogICAgfQogIH0sCiAgInNlcnZpY2VfdGllciI6ICJkZWZhdWx0IiwKICAic3lzdGVtX2ZpbmdlcnByaW50IjogImZwXzRmY2UwNzc4YWYiCn0K"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"id": "1757338002750-unknown-host-POST-_v1_chat_completions-9d7fafef.json",
|
||||||
|
"priority": 0,
|
||||||
|
"timeToLive": {
|
||||||
|
"unlimited": true
|
||||||
|
},
|
||||||
|
"times": {
|
||||||
|
"unlimited": true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,120 @@
|
|||||||
|
{
|
||||||
|
"httpRequest": {
|
||||||
|
"method": "POST",
|
||||||
|
"path": "/v1/chat/completions",
|
||||||
|
"body": {
|
||||||
|
"contentType": "application/json",
|
||||||
|
"type": "JSON",
|
||||||
|
"json": {
|
||||||
|
"model": "gpt-4.1-mini",
|
||||||
|
"stream": false,
|
||||||
|
"tools": [
|
||||||
|
{
|
||||||
|
"type": "function",
|
||||||
|
"function": {
|
||||||
|
"name": "calculator",
|
||||||
|
"description": "Useful for getting the result of a math expression. The input to this tool should be a valid mathematical expression that could be executed by a simple calculator.",
|
||||||
|
"parameters": {
|
||||||
|
"type": "object",
|
||||||
|
"properties": {
|
||||||
|
"input": {
|
||||||
|
"type": "string"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"additionalProperties": false,
|
||||||
|
"$schema": "http://json-schema.org/draft-07/schema#"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"messages": [
|
||||||
|
{
|
||||||
|
"role": "user",
|
||||||
|
"content": "What is 1000 * 10?"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "assistant",
|
||||||
|
"content": "",
|
||||||
|
"tool_calls": [
|
||||||
|
{
|
||||||
|
"id": "call_88I326c3cCx7lOEXL3Wpp30c",
|
||||||
|
"type": "function",
|
||||||
|
"function": {
|
||||||
|
"name": "calculator",
|
||||||
|
"arguments": "{\"input\":\"1000 * 10\"}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"role": "tool",
|
||||||
|
"content": "10000",
|
||||||
|
"tool_call_id": "call_88I326c3cCx7lOEXL3Wpp30c"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"rawBytes": "eyJtb2RlbCI6ImdwdC00LjEtbWluaSIsInN0cmVhbSI6ZmFsc2UsInRvb2xzIjpbeyJ0eXBlIjoiZnVuY3Rpb24iLCJmdW5jdGlvbiI6eyJuYW1lIjoiY2FsY3VsYXRvciIsImRlc2NyaXB0aW9uIjoiVXNlZnVsIGZvciBnZXR0aW5nIHRoZSByZXN1bHQgb2YgYSBtYXRoIGV4cHJlc3Npb24uIFRoZSBpbnB1dCB0byB0aGlzIHRvb2wgc2hvdWxkIGJlIGEgdmFsaWQgbWF0aGVtYXRpY2FsIGV4cHJlc3Npb24gdGhhdCBjb3VsZCBiZSBleGVjdXRlZCBieSBhIHNpbXBsZSBjYWxjdWxhdG9yLiIsInBhcmFtZXRlcnMiOnsidHlwZSI6Im9iamVjdCIsInByb3BlcnRpZXMiOnsiaW5wdXQiOnsidHlwZSI6InN0cmluZyJ9fSwiYWRkaXRpb25hbFByb3BlcnRpZXMiOmZhbHNlLCIkc2NoZW1hIjoiaHR0cDovL2pzb24tc2NoZW1hLm9yZy9kcmFmdC0wNy9zY2hlbWEjIn19fV0sIm1lc3NhZ2VzIjpbeyJyb2xlIjoidXNlciIsImNvbnRlbnQiOiJXaGF0IGlzIDEwMDAgKiAxMD8ifSx7InJvbGUiOiJhc3Npc3RhbnQiLCJjb250ZW50IjoiIiwidG9vbF9jYWxscyI6W3siaWQiOiJjYWxsXzg4STMyNmMzY0N4N2xPRVhMM1dwcDMwYyIsInR5cGUiOiJmdW5jdGlvbiIsImZ1bmN0aW9uIjp7Im5hbWUiOiJjYWxjdWxhdG9yIiwiYXJndW1lbnRzIjoie1wiaW5wdXRcIjpcIjEwMDAgKiAxMFwifSJ9fV19LHsicm9sZSI6InRvb2wiLCJjb250ZW50IjoiMTAwMDAiLCJ0b29sX2NhbGxfaWQiOiJjYWxsXzg4STMyNmMzY0N4N2xPRVhMM1dwcDMwYyJ9XX0="
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"httpResponse": {
|
||||||
|
"statusCode": 200,
|
||||||
|
"reasonPhrase": "OK",
|
||||||
|
"headers": {
|
||||||
|
"x-request-id": ["req_65b7f6b5aad740e0965555ae8df92d43"],
|
||||||
|
"x-ratelimit-reset-tokens": ["0s"],
|
||||||
|
"x-ratelimit-reset-requests": ["2ms"],
|
||||||
|
"x-ratelimit-remaining-tokens": ["149999992"],
|
||||||
|
"x-ratelimit-remaining-requests": ["29999"],
|
||||||
|
"x-ratelimit-limit-tokens": ["150000000"]
|
||||||
|
},
|
||||||
|
"body": {
|
||||||
|
"contentType": "application/json",
|
||||||
|
"type": "JSON",
|
||||||
|
"json": {
|
||||||
|
"id": "chatcmpl-CDWBEPUWN3El2oq4aRaezkvUlRjv8",
|
||||||
|
"object": "chat.completion",
|
||||||
|
"created": 1757338000,
|
||||||
|
"model": "gpt-4.1-mini-2025-04-14",
|
||||||
|
"choices": [
|
||||||
|
{
|
||||||
|
"index": 0,
|
||||||
|
"message": {
|
||||||
|
"role": "assistant",
|
||||||
|
"content": "1000 multiplied by 10 equals 10,000.",
|
||||||
|
"refusal": null,
|
||||||
|
"annotations": []
|
||||||
|
},
|
||||||
|
"logprobs": null,
|
||||||
|
"finish_reason": "stop"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"usage": {
|
||||||
|
"prompt_tokens": 102,
|
||||||
|
"completion_tokens": 13,
|
||||||
|
"total_tokens": 115,
|
||||||
|
"prompt_tokens_details": {
|
||||||
|
"cached_tokens": 0,
|
||||||
|
"audio_tokens": 0
|
||||||
|
},
|
||||||
|
"completion_tokens_details": {
|
||||||
|
"reasoning_tokens": 0,
|
||||||
|
"audio_tokens": 0,
|
||||||
|
"accepted_prediction_tokens": 0,
|
||||||
|
"rejected_prediction_tokens": 0
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"service_tier": "default",
|
||||||
|
"system_fingerprint": "fp_4fce0778af"
|
||||||
|
},
|
||||||
|
"rawBytes": "ewogICJpZCI6ICJjaGF0Y21wbC1DRFdCRVBVV04zRWwyb3E0YVJhZXprdlVsUmp2OCIsCiAgIm9iamVjdCI6ICJjaGF0LmNvbXBsZXRpb24iLAogICJjcmVhdGVkIjogMTc1NzMzODAwMCwKICAibW9kZWwiOiAiZ3B0LTQuMS1taW5pLTIwMjUtMDQtMTQiLAogICJjaG9pY2VzIjogWwogICAgewogICAgICAiaW5kZXgiOiAwLAogICAgICAibWVzc2FnZSI6IHsKICAgICAgICAicm9sZSI6ICJhc3Npc3RhbnQiLAogICAgICAgICJjb250ZW50IjogIjEwMDAgbXVsdGlwbGllZCBieSAxMCBlcXVhbHMgMTAsMDAwLiIsCiAgICAgICAgInJlZnVzYWwiOiBudWxsLAogICAgICAgICJhbm5vdGF0aW9ucyI6IFtdCiAgICAgIH0sCiAgICAgICJsb2dwcm9icyI6IG51bGwsCiAgICAgICJmaW5pc2hfcmVhc29uIjogInN0b3AiCiAgICB9CiAgXSwKICAidXNhZ2UiOiB7CiAgICAicHJvbXB0X3Rva2VucyI6IDEwMiwKICAgICJjb21wbGV0aW9uX3Rva2VucyI6IDEzLAogICAgInRvdGFsX3Rva2VucyI6IDExNSwKICAgICJwcm9tcHRfdG9rZW5zX2RldGFpbHMiOiB7CiAgICAgICJjYWNoZWRfdG9rZW5zIjogMCwKICAgICAgImF1ZGlvX3Rva2VucyI6IDAKICAgIH0sCiAgICAiY29tcGxldGlvbl90b2tlbnNfZGV0YWlscyI6IHsKICAgICAgInJlYXNvbmluZ190b2tlbnMiOiAwLAogICAgICAiYXVkaW9fdG9rZW5zIjogMCwKICAgICAgImFjY2VwdGVkX3ByZWRpY3Rpb25fdG9rZW5zIjogMCwKICAgICAgInJlamVjdGVkX3ByZWRpY3Rpb25fdG9rZW5zIjogMAogICAgfQogIH0sCiAgInNlcnZpY2VfdGllciI6ICJkZWZhdWx0IiwKICAic3lzdGVtX2ZpbmdlcnByaW50IjogImZwXzRmY2UwNzc4YWYiCn0K"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"id": "1757338002751-unknown-host-POST-_v1_chat_completions-e8887e9d.json",
|
||||||
|
"priority": 0,
|
||||||
|
"timeToLive": {
|
||||||
|
"unlimited": true
|
||||||
|
},
|
||||||
|
"times": {
|
||||||
|
"unlimited": true
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -34,6 +34,7 @@
|
|||||||
"n8n-containers": "workspace:*",
|
"n8n-containers": "workspace:*",
|
||||||
"n8n-core": "workspace:*",
|
"n8n-core": "workspace:*",
|
||||||
"n8n-workflow": "workspace:*",
|
"n8n-workflow": "workspace:*",
|
||||||
|
"flatted": "catalog:",
|
||||||
"nanoid": "catalog:",
|
"nanoid": "catalog:",
|
||||||
"tsx": "catalog:",
|
"tsx": "catalog:",
|
||||||
"mockserver-client": "^5.15.0",
|
"mockserver-client": "^5.15.0",
|
||||||
|
|||||||
@@ -541,6 +541,28 @@ export class CanvasPage extends BasePage {
|
|||||||
await this.clickContextMenuAction('execute');
|
await this.clickContextMenuAction('execute');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async clearExecutionData(): Promise<void> {
|
||||||
|
await this.page.getByTestId('clear-execution-data-button').click();
|
||||||
|
}
|
||||||
|
|
||||||
|
getManualChatModal(): Locator {
|
||||||
|
return this.page.getByTestId('canvas-chat');
|
||||||
|
}
|
||||||
|
|
||||||
|
getManualChatInput(): Locator {
|
||||||
|
return this.getManualChatModal().locator('.chat-inputs textarea');
|
||||||
|
}
|
||||||
|
|
||||||
|
getManualChatMessages(): Locator {
|
||||||
|
return this.getManualChatModal().locator('.chat-messages-list .chat-message');
|
||||||
|
}
|
||||||
|
|
||||||
|
getManualChatLatestBotMessage(): Locator {
|
||||||
|
return this.getManualChatModal()
|
||||||
|
.locator('.chat-messages-list .chat-message.chat-message-from-bot')
|
||||||
|
.last();
|
||||||
|
}
|
||||||
|
|
||||||
getNodesWithSpinner(): Locator {
|
getNodesWithSpinner(): Locator {
|
||||||
return this.page.getByTestId('canvas-node').filter({
|
return this.page.getByTestId('canvas-node').filter({
|
||||||
has: this.page.locator('[data-icon=refresh-cw]'),
|
has: this.page.locator('[data-icon=refresh-cw]'),
|
||||||
@@ -560,6 +582,67 @@ export class CanvasPage extends BasePage {
|
|||||||
return this.page.locator('[data-test-id="canvas-node"].selected');
|
return this.page.locator('[data-test-id="canvas-node"].selected');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Disable node via context menu
|
||||||
|
async disableNodeFromContextMenu(nodeName: string): Promise<void> {
|
||||||
|
await this.rightClickNode(nodeName);
|
||||||
|
await this.page
|
||||||
|
.getByTestId('context-menu')
|
||||||
|
.getByTestId('context-menu-item-toggle_activation')
|
||||||
|
.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chat open/close buttons (manual chat)
|
||||||
|
async clickManualChatButton(): Promise<void> {
|
||||||
|
await this.page.getByTestId('workflow-chat-button').click();
|
||||||
|
await this.getManualChatModal().waitFor({ state: 'visible' });
|
||||||
|
}
|
||||||
|
|
||||||
|
async closeManualChatModal(): Promise<void> {
|
||||||
|
// Same toggle button closes the chat
|
||||||
|
await this.page.getByTestId('workflow-chat-button').click();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Input plus endpoints (to add supplemental nodes to parent inputs)
|
||||||
|
getInputPlusEndpointByType(nodeName: string, endpointType: string) {
|
||||||
|
return this.page
|
||||||
|
.locator(
|
||||||
|
`[data-test-id="canvas-node-input-handle"][data-connection-type="${endpointType}"][data-node-name="${nodeName}"] [data-test-id="canvas-handle-plus"]`,
|
||||||
|
)
|
||||||
|
.first();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Generic supplemental node addition, then wrappers for specific types
|
||||||
|
async addSupplementalNodeToParent(
|
||||||
|
childNodeName: string,
|
||||||
|
endpointType:
|
||||||
|
| 'main'
|
||||||
|
| 'ai_chain'
|
||||||
|
| 'ai_document'
|
||||||
|
| 'ai_embedding'
|
||||||
|
| 'ai_languageModel'
|
||||||
|
| 'ai_memory'
|
||||||
|
| 'ai_outputParser'
|
||||||
|
| 'ai_tool'
|
||||||
|
| 'ai_retriever'
|
||||||
|
| 'ai_textSplitter'
|
||||||
|
| 'ai_vectorRetriever'
|
||||||
|
| 'ai_vectorStore',
|
||||||
|
parentNodeName: string,
|
||||||
|
{ closeNDV = false, exactMatch = false }: { closeNDV?: boolean; exactMatch?: boolean } = {},
|
||||||
|
): Promise<void> {
|
||||||
|
await this.getInputPlusEndpointByType(parentNodeName, endpointType).click();
|
||||||
|
|
||||||
|
if (exactMatch) {
|
||||||
|
await this.nodeCreatorNodeItems().getByText(childNodeName, { exact: true }).click();
|
||||||
|
} else {
|
||||||
|
await this.nodeCreatorNodeItems().filter({ hasText: childNodeName }).first().click();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (closeNDV) {
|
||||||
|
await this.page.keyboard.press('Escape');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
async openExecutions() {
|
async openExecutions() {
|
||||||
await this.page.getByTestId('radio-button-executions').click();
|
await this.page.getByTestId('radio-button-executions').click();
|
||||||
}
|
}
|
||||||
|
|||||||
67
packages/testing/playwright/pages/CredentialsEditModal.ts
Normal file
67
packages/testing/playwright/pages/CredentialsEditModal.ts
Normal file
@@ -0,0 +1,67 @@
|
|||||||
|
import type { Locator, Page } from '@playwright/test';
|
||||||
|
import { expect } from '@playwright/test';
|
||||||
|
|
||||||
|
import { BasePage } from './BasePage';
|
||||||
|
|
||||||
|
export class CredentialsEditModal extends BasePage {
|
||||||
|
constructor(page: Page) {
|
||||||
|
super(page);
|
||||||
|
}
|
||||||
|
|
||||||
|
getModal(): Locator {
|
||||||
|
return this.page.getByTestId('editCredential-modal');
|
||||||
|
}
|
||||||
|
|
||||||
|
async waitForModal(): Promise<void> {
|
||||||
|
await this.getModal().waitFor({ state: 'visible' });
|
||||||
|
}
|
||||||
|
|
||||||
|
async fillField(key: string, value: string): Promise<void> {
|
||||||
|
const input = this.page.getByTestId(`parameter-input-${key}`).locator('input, textarea');
|
||||||
|
await input.fill(value);
|
||||||
|
await expect(input).toHaveValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
async fillAllFields(values: Record<string, string>): Promise<void> {
|
||||||
|
for (const [key, val] of Object.entries(values)) {
|
||||||
|
await this.fillField(key, val);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
getSaveButton(): Locator {
|
||||||
|
return this.page.getByTestId('credential-save-button');
|
||||||
|
}
|
||||||
|
|
||||||
|
async save(): Promise<void> {
|
||||||
|
const saveBtn = this.getSaveButton();
|
||||||
|
await saveBtn.click();
|
||||||
|
await saveBtn.waitFor({ state: 'visible' });
|
||||||
|
|
||||||
|
// Saved state changes the button text to "Saved"
|
||||||
|
// Defensive wait for text when UI updates
|
||||||
|
try {
|
||||||
|
await saveBtn
|
||||||
|
.getByText('Saved', { exact: true })
|
||||||
|
.waitFor({ state: 'visible', timeout: 3000 });
|
||||||
|
} catch {
|
||||||
|
// ignore if text assertion is flaky; modal close below will still ensure flow continues
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async close(): Promise<void> {
|
||||||
|
const closeBtn = this.getModal().locator('.el-dialog__close').first();
|
||||||
|
if (await closeBtn.isVisible()) {
|
||||||
|
await closeBtn.click();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async setValues(values: Record<string, string>, save: boolean = true): Promise<void> {
|
||||||
|
await this.waitForModal();
|
||||||
|
await this.fillAllFields(values);
|
||||||
|
|
||||||
|
if (save) {
|
||||||
|
await this.save();
|
||||||
|
await this.close();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -52,10 +52,18 @@ export class NodeDetailsViewPage extends BasePage {
|
|||||||
await this.clickByTestId('node-execute-button');
|
await this.clickByTestId('node-execute-button');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getOutputPanel() {
|
||||||
|
return this.page.getByTestId('output-panel');
|
||||||
|
}
|
||||||
|
|
||||||
getContainer() {
|
getContainer() {
|
||||||
return this.page.getByTestId('ndv');
|
return this.page.getByTestId('ndv');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getInputPanel() {
|
||||||
|
return this.page.getByTestId('ndv-input-panel');
|
||||||
|
}
|
||||||
|
|
||||||
getParameterExpressionPreviewValue() {
|
getParameterExpressionPreviewValue() {
|
||||||
return this.page.getByTestId('parameter-expression-preview-value');
|
return this.page.getByTestId('parameter-expression-preview-value');
|
||||||
}
|
}
|
||||||
@@ -81,6 +89,14 @@ export class NodeDetailsViewPage extends BasePage {
|
|||||||
return this.page.getByTestId('run-data-pane-header');
|
return this.page.getByTestId('run-data-pane-header');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getOutputTable() {
|
||||||
|
return this.getOutputPanel().getByTestId('ndv-data-container').locator('table');
|
||||||
|
}
|
||||||
|
|
||||||
|
getOutputDataContainer() {
|
||||||
|
return this.getOutputPanel().getByTestId('ndv-data-container');
|
||||||
|
}
|
||||||
|
|
||||||
async setPinnedData(data: object | string) {
|
async setPinnedData(data: object | string) {
|
||||||
const pinnedData = typeof data === 'string' ? data : JSON.stringify(data);
|
const pinnedData = typeof data === 'string' ? data : JSON.stringify(data);
|
||||||
await this.getEditPinnedDataButton().click();
|
await this.getEditPinnedDataButton().click();
|
||||||
@@ -373,6 +389,14 @@ export class NodeDetailsViewPage extends BasePage {
|
|||||||
await this.page.getByRole('option', { name: nodeName }).click();
|
await this.page.getByRole('option', { name: nodeName }).click();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getInputTableHeader(index: number = 0) {
|
||||||
|
return this.getInputPanel().locator('table th').nth(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
getInputTbodyCell(row: number, col: number) {
|
||||||
|
return this.getInputPanel().locator('table tbody tr').nth(row).locator('td').nth(col);
|
||||||
|
}
|
||||||
|
|
||||||
getAssignmentName(paramName: string, index = 0) {
|
getAssignmentName(paramName: string, index = 0) {
|
||||||
return this.getAssignmentCollectionContainer(paramName)
|
return this.getAssignmentCollectionContainer(paramName)
|
||||||
.getByTestId('assignment')
|
.getByTestId('assignment')
|
||||||
@@ -457,6 +481,14 @@ export class NodeDetailsViewPage extends BasePage {
|
|||||||
await input.type(content);
|
await input.type(content);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getInputTable() {
|
||||||
|
return this.getInputPanel().locator('table');
|
||||||
|
}
|
||||||
|
|
||||||
|
getInputTableCellSpan(row: number, col: number, dataName: string) {
|
||||||
|
return this.getInputTbodyCell(row, col).locator(`span[data-name="${dataName}"]`).first();
|
||||||
|
}
|
||||||
|
|
||||||
getAddFieldToSortByButton() {
|
getAddFieldToSortByButton() {
|
||||||
return this.getNodeParameters().getByText('Add Field To Sort By');
|
return this.getNodeParameters().getByText('Add Field To Sort By');
|
||||||
}
|
}
|
||||||
@@ -493,6 +525,46 @@ export class NodeDetailsViewPage extends BasePage {
|
|||||||
await input.fill(value);
|
await input.fill(value);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async clickGetBackToCanvas(): Promise<void> {
|
||||||
|
await this.clickBackToCanvasButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
getRunDataInfoCallout() {
|
||||||
|
return this.page.getByTestId('run-data-callout');
|
||||||
|
}
|
||||||
|
|
||||||
|
getOutputPanelTable() {
|
||||||
|
return this.getOutputTable();
|
||||||
|
}
|
||||||
|
|
||||||
|
async checkParameterCheckboxInputByName(name: string): Promise<void> {
|
||||||
|
const checkbox = this.getParameterInput(name).locator('.el-switch.switch-input');
|
||||||
|
await checkbox.click();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Credentials modal helpers
|
||||||
|
async clickCreateNewCredential(eq: number = 0): Promise<void> {
|
||||||
|
await this.page.getByTestId('node-credentials-select').nth(eq).click();
|
||||||
|
await this.page.getByTestId('node-credentials-select-item-new').click();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Run selector and linking helpers
|
||||||
|
getInputRunSelector() {
|
||||||
|
return this.page.locator('[data-test-id="ndv-input-panel"] [data-test-id="run-selector"]');
|
||||||
|
}
|
||||||
|
|
||||||
|
getOutputRunSelector() {
|
||||||
|
return this.page.locator('[data-test-id="output-panel"] [data-test-id="run-selector"]');
|
||||||
|
}
|
||||||
|
|
||||||
|
getInputRunSelectorInput() {
|
||||||
|
return this.getInputRunSelector().locator('input');
|
||||||
|
}
|
||||||
|
|
||||||
|
async toggleInputRunLinking(): Promise<void> {
|
||||||
|
await this.getInputPanel().getByTestId('link-run').click();
|
||||||
|
}
|
||||||
|
|
||||||
getNodeRunErrorMessage() {
|
getNodeRunErrorMessage() {
|
||||||
return this.page.getByTestId('node-error-message');
|
return this.page.getByTestId('node-error-message');
|
||||||
}
|
}
|
||||||
@@ -725,6 +797,19 @@ export class NodeDetailsViewPage extends BasePage {
|
|||||||
getInputSelect() {
|
getInputSelect() {
|
||||||
return this.page.getByTestId('ndv-input-select').locator('input');
|
return this.page.getByTestId('ndv-input-select').locator('input');
|
||||||
}
|
}
|
||||||
|
|
||||||
|
getInputTableRows() {
|
||||||
|
return this.getInputTable().locator('tr');
|
||||||
|
}
|
||||||
|
|
||||||
|
getOutputRunSelectorInput() {
|
||||||
|
return this.getOutputPanel().locator('[data-test-id="run-selector"] input');
|
||||||
|
}
|
||||||
|
|
||||||
|
getAiOutputModeToggle() {
|
||||||
|
return this.page.getByTestId('ai-output-mode-select');
|
||||||
|
}
|
||||||
|
|
||||||
getCredentialLabel(credentialType: string) {
|
getCredentialLabel(credentialType: string) {
|
||||||
return this.page.getByText(credentialType);
|
return this.page.getByText(credentialType);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import { AIAssistantPage } from './AIAssistantPage';
|
|||||||
import { BecomeCreatorCTAPage } from './BecomeCreatorCTAPage';
|
import { BecomeCreatorCTAPage } from './BecomeCreatorCTAPage';
|
||||||
import { CanvasPage } from './CanvasPage';
|
import { CanvasPage } from './CanvasPage';
|
||||||
import { CommunityNodesPage } from './CommunityNodesPage';
|
import { CommunityNodesPage } from './CommunityNodesPage';
|
||||||
|
import { CredentialsEditModal } from './CredentialsEditModal';
|
||||||
import { CredentialsPage } from './CredentialsPage';
|
import { CredentialsPage } from './CredentialsPage';
|
||||||
import { DemoPage } from './DemoPage';
|
import { DemoPage } from './DemoPage';
|
||||||
import { ExecutionsPage } from './ExecutionsPage';
|
import { ExecutionsPage } from './ExecutionsPage';
|
||||||
@@ -59,6 +60,7 @@ export class n8nPage {
|
|||||||
readonly workflowActivationModal: WorkflowActivationModal;
|
readonly workflowActivationModal: WorkflowActivationModal;
|
||||||
readonly workflowSettingsModal: WorkflowSettingsModal;
|
readonly workflowSettingsModal: WorkflowSettingsModal;
|
||||||
readonly workflowSharingModal: WorkflowSharingModal;
|
readonly workflowSharingModal: WorkflowSharingModal;
|
||||||
|
readonly credentialsModal: CredentialsEditModal;
|
||||||
|
|
||||||
// Composables
|
// Composables
|
||||||
readonly workflowComposer: WorkflowComposer;
|
readonly workflowComposer: WorkflowComposer;
|
||||||
@@ -98,6 +100,7 @@ export class n8nPage {
|
|||||||
// Modals
|
// Modals
|
||||||
this.workflowActivationModal = new WorkflowActivationModal(page);
|
this.workflowActivationModal = new WorkflowActivationModal(page);
|
||||||
this.workflowSettingsModal = new WorkflowSettingsModal(page);
|
this.workflowSettingsModal = new WorkflowSettingsModal(page);
|
||||||
|
this.credentialsModal = new CredentialsEditModal(page);
|
||||||
|
|
||||||
// Composables
|
// Composables
|
||||||
this.workflowComposer = new WorkflowComposer(this);
|
this.workflowComposer = new WorkflowComposer(this);
|
||||||
|
|||||||
534
packages/testing/playwright/tests/ui/30-langchain.spec.ts
Normal file
534
packages/testing/playwright/tests/ui/30-langchain.spec.ts
Normal file
@@ -0,0 +1,534 @@
|
|||||||
|
import {
|
||||||
|
AGENT_NODE_NAME,
|
||||||
|
EDIT_FIELDS_SET_NODE_NAME,
|
||||||
|
MANUAL_CHAT_TRIGGER_NODE_NAME,
|
||||||
|
AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME,
|
||||||
|
AI_MEMORY_WINDOW_BUFFER_MEMORY_NODE_NAME,
|
||||||
|
AI_MEMORY_POSTGRES_NODE_NAME,
|
||||||
|
AI_TOOL_CALCULATOR_NODE_NAME,
|
||||||
|
AI_OUTPUT_PARSER_AUTO_FIXING_NODE_NAME,
|
||||||
|
AI_TOOL_CODE_NODE_NAME,
|
||||||
|
AI_TOOL_WIKIPEDIA_NODE_NAME,
|
||||||
|
BASIC_LLM_CHAIN_NODE_NAME,
|
||||||
|
CHAT_TRIGGER_NODE_DISPLAY_NAME,
|
||||||
|
SCHEDULE_TRIGGER_NODE_NAME,
|
||||||
|
} from '../../config/constants';
|
||||||
|
import { test, expect } from '../../fixtures/base';
|
||||||
|
import type { n8nPage } from '../../pages/n8nPage';
|
||||||
|
|
||||||
|
// Helper functions for common operations
|
||||||
|
async function addOpenAILanguageModelWithCredentials(
|
||||||
|
n8n: n8nPage,
|
||||||
|
parentNode: string,
|
||||||
|
options: { exactMatch?: boolean; closeNDV?: boolean } = { exactMatch: true, closeNDV: false },
|
||||||
|
) {
|
||||||
|
await n8n.canvas.addSupplementalNodeToParent(
|
||||||
|
AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME,
|
||||||
|
'ai_languageModel',
|
||||||
|
parentNode,
|
||||||
|
options,
|
||||||
|
);
|
||||||
|
|
||||||
|
await n8n.ndv.clickCreateNewCredential();
|
||||||
|
await n8n.credentialsModal.setValues({
|
||||||
|
apiKey: 'abcd',
|
||||||
|
});
|
||||||
|
await n8n.ndv.clickBackToCanvasButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
async function waitForWorkflowSuccess(n8n: n8nPage, timeout = 3000) {
|
||||||
|
await n8n.notifications.waitForNotificationAndClose('Workflow executed successfully', {
|
||||||
|
timeout,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
async function executeChatAndWaitForResponse(n8n: n8nPage, message: string) {
|
||||||
|
await n8n.canvas.logsPanel.sendManualChatMessage(message);
|
||||||
|
await waitForWorkflowSuccess(n8n);
|
||||||
|
}
|
||||||
|
|
||||||
|
async function verifyChatMessages(n8n: n8nPage, expectedCount: number, inputMessage?: string) {
|
||||||
|
const messages = n8n.canvas.getManualChatMessages();
|
||||||
|
await expect(messages).toHaveCount(expectedCount);
|
||||||
|
if (inputMessage) {
|
||||||
|
await expect(messages.first()).toContainText(inputMessage);
|
||||||
|
}
|
||||||
|
await expect(messages.last()).toBeVisible();
|
||||||
|
return messages;
|
||||||
|
}
|
||||||
|
|
||||||
|
async function verifyLogsPanelEntries(n8n: n8nPage, expectedEntries: string[]) {
|
||||||
|
await expect(n8n.canvas.logsPanel.getLogEntries().first()).toBeVisible();
|
||||||
|
await expect(n8n.canvas.logsPanel.getLogEntries()).toHaveCount(expectedEntries.length);
|
||||||
|
for (let i = 0; i < expectedEntries.length; i++) {
|
||||||
|
await expect(n8n.canvas.logsPanel.getLogEntries().nth(i)).toHaveText(expectedEntries[i]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
async function setupBasicAgentWorkflow(n8n: n8nPage, additionalNodes: string[] = []) {
|
||||||
|
await n8n.canvas.addNode(AGENT_NODE_NAME, { closeNDV: true });
|
||||||
|
|
||||||
|
// Add additional nodes if specified
|
||||||
|
for (const nodeName of additionalNodes) {
|
||||||
|
await n8n.canvas.addSupplementalNodeToParent(nodeName, 'ai_tool', AGENT_NODE_NAME, {
|
||||||
|
closeNDV: true,
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
// Always add OpenAI Language Model
|
||||||
|
await addOpenAILanguageModelWithCredentials(n8n, AGENT_NODE_NAME);
|
||||||
|
}
|
||||||
|
|
||||||
|
test.describe('Langchain Integration @capability:proxy', () => {
|
||||||
|
test.beforeEach(async ({ n8n, proxyServer }) => {
|
||||||
|
await proxyServer.clearAllExpectations();
|
||||||
|
await proxyServer.loadExpectations('langchain');
|
||||||
|
await n8n.canvas.openNewWorkflow();
|
||||||
|
});
|
||||||
|
|
||||||
|
test.describe('Workflow Execution Behavior', () => {
|
||||||
|
test('should not open chat modal', async ({ n8n }) => {
|
||||||
|
await n8n.canvas.addNode(EDIT_FIELDS_SET_NODE_NAME, { closeNDV: true });
|
||||||
|
|
||||||
|
await n8n.canvas.addNode(AGENT_NODE_NAME, { closeNDV: true });
|
||||||
|
|
||||||
|
await n8n.canvas.addSupplementalNodeToParent(
|
||||||
|
AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME,
|
||||||
|
'ai_languageModel',
|
||||||
|
AGENT_NODE_NAME,
|
||||||
|
{ exactMatch: true, closeNDV: true },
|
||||||
|
);
|
||||||
|
|
||||||
|
await n8n.canvas.clickExecuteWorkflowButton();
|
||||||
|
await expect(n8n.canvas.getManualChatModal()).toBeHidden();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should remove test workflow button', async ({ n8n }) => {
|
||||||
|
await n8n.canvas.addNode(SCHEDULE_TRIGGER_NODE_NAME, { closeNDV: true });
|
||||||
|
|
||||||
|
await n8n.canvas.addNode(EDIT_FIELDS_SET_NODE_NAME, { closeNDV: true });
|
||||||
|
|
||||||
|
await n8n.canvas.addNode(AGENT_NODE_NAME, { closeNDV: true });
|
||||||
|
|
||||||
|
await n8n.canvas.addSupplementalNodeToParent(
|
||||||
|
AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME,
|
||||||
|
'ai_languageModel',
|
||||||
|
AGENT_NODE_NAME,
|
||||||
|
{ exactMatch: true, closeNDV: true },
|
||||||
|
);
|
||||||
|
|
||||||
|
await n8n.canvas.disableNodeFromContextMenu(SCHEDULE_TRIGGER_NODE_NAME);
|
||||||
|
await expect(n8n.canvas.getExecuteWorkflowButton()).toBeHidden();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test.describe('Node Connection and Configuration', () => {
|
||||||
|
test('should add nodes to all Agent node input types', async ({ n8n }) => {
|
||||||
|
const agentSubNodes = [
|
||||||
|
AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME,
|
||||||
|
AI_MEMORY_WINDOW_BUFFER_MEMORY_NODE_NAME,
|
||||||
|
AI_TOOL_CALCULATOR_NODE_NAME,
|
||||||
|
AI_OUTPUT_PARSER_AUTO_FIXING_NODE_NAME,
|
||||||
|
];
|
||||||
|
await n8n.canvas.addNode(AGENT_NODE_NAME, { closeNDV: false });
|
||||||
|
|
||||||
|
await n8n.ndv.checkParameterCheckboxInputByName('hasOutputParser');
|
||||||
|
await n8n.ndv.clickBackToCanvasButton();
|
||||||
|
await n8n.canvas.addSupplementalNodeToParent(
|
||||||
|
AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME,
|
||||||
|
'ai_languageModel',
|
||||||
|
AGENT_NODE_NAME,
|
||||||
|
{ exactMatch: true, closeNDV: true },
|
||||||
|
);
|
||||||
|
|
||||||
|
await n8n.canvas.addSupplementalNodeToParent(
|
||||||
|
AI_MEMORY_WINDOW_BUFFER_MEMORY_NODE_NAME,
|
||||||
|
'ai_memory',
|
||||||
|
AGENT_NODE_NAME,
|
||||||
|
{ closeNDV: true },
|
||||||
|
);
|
||||||
|
|
||||||
|
await n8n.canvas.addSupplementalNodeToParent(
|
||||||
|
AI_TOOL_CALCULATOR_NODE_NAME,
|
||||||
|
'ai_tool',
|
||||||
|
AGENT_NODE_NAME,
|
||||||
|
{ closeNDV: true },
|
||||||
|
);
|
||||||
|
|
||||||
|
await n8n.canvas.addSupplementalNodeToParent(
|
||||||
|
AI_OUTPUT_PARSER_AUTO_FIXING_NODE_NAME,
|
||||||
|
'ai_outputParser',
|
||||||
|
AGENT_NODE_NAME,
|
||||||
|
{ closeNDV: true },
|
||||||
|
);
|
||||||
|
for (const nodeName of agentSubNodes) {
|
||||||
|
await expect(n8n.canvas.connectionBetweenNodes(nodeName, AGENT_NODE_NAME)).toBeAttached();
|
||||||
|
}
|
||||||
|
await expect(n8n.canvas.getCanvasNodes()).toHaveCount(2 + agentSubNodes.length); // Chat Trigger + Agent + 4 inputs
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should add multiple tool nodes to Agent node tool input type', async ({ n8n }) => {
|
||||||
|
await n8n.canvas.addNode(AGENT_NODE_NAME, { closeNDV: true });
|
||||||
|
|
||||||
|
const tools = [
|
||||||
|
AI_TOOL_CALCULATOR_NODE_NAME,
|
||||||
|
AI_TOOL_CODE_NODE_NAME,
|
||||||
|
AI_TOOL_CODE_NODE_NAME,
|
||||||
|
AI_TOOL_WIKIPEDIA_NODE_NAME,
|
||||||
|
];
|
||||||
|
|
||||||
|
for (const tool of tools) {
|
||||||
|
await n8n.canvas.addSupplementalNodeToParent(tool, 'ai_tool', AGENT_NODE_NAME, {
|
||||||
|
closeNDV: true,
|
||||||
|
});
|
||||||
|
await expect(n8n.canvas.connectionBetweenNodes(tool, AGENT_NODE_NAME)).toBeAttached();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Chat Trigger + Agent + Tools
|
||||||
|
await expect(n8n.canvas.getCanvasNodes()).toHaveCount(2 + tools.length);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test.describe('Auto-add Behavior', () => {
|
||||||
|
test('should auto-add chat trigger and basic LLM chain when adding LLM node', async ({
|
||||||
|
n8n,
|
||||||
|
}) => {
|
||||||
|
await n8n.canvas.addNode(AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME, { closeNDV: true });
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
n8n.canvas.connectionBetweenNodes(
|
||||||
|
CHAT_TRIGGER_NODE_DISPLAY_NAME,
|
||||||
|
BASIC_LLM_CHAIN_NODE_NAME,
|
||||||
|
),
|
||||||
|
).toBeAttached();
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
n8n.canvas.connectionBetweenNodes(
|
||||||
|
AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME,
|
||||||
|
BASIC_LLM_CHAIN_NODE_NAME,
|
||||||
|
),
|
||||||
|
).toBeAttached();
|
||||||
|
|
||||||
|
await expect(n8n.canvas.getCanvasNodes()).toHaveCount(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should not auto-add nodes if AI nodes are already present', async ({ n8n }) => {
|
||||||
|
await n8n.canvas.addNode(AGENT_NODE_NAME, { closeNDV: true });
|
||||||
|
|
||||||
|
await n8n.canvas.addNode(AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME, { closeNDV: true });
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
n8n.canvas.connectionBetweenNodes(CHAT_TRIGGER_NODE_DISPLAY_NAME, AGENT_NODE_NAME),
|
||||||
|
).toBeAttached();
|
||||||
|
|
||||||
|
await expect(n8n.canvas.getCanvasNodes()).toHaveCount(3);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should not auto-add nodes if ChatTrigger is already present', async ({ n8n }) => {
|
||||||
|
await n8n.canvas.addNode(MANUAL_CHAT_TRIGGER_NODE_NAME, { closeNDV: true });
|
||||||
|
|
||||||
|
await n8n.canvas.addNode(AGENT_NODE_NAME, { closeNDV: true });
|
||||||
|
|
||||||
|
await n8n.canvas.addNode(AI_LANGUAGE_MODEL_OPENAI_CHAT_MODEL_NODE_NAME, { closeNDV: true });
|
||||||
|
|
||||||
|
await expect(
|
||||||
|
n8n.canvas.connectionBetweenNodes(CHAT_TRIGGER_NODE_DISPLAY_NAME, AGENT_NODE_NAME),
|
||||||
|
).toBeAttached();
|
||||||
|
|
||||||
|
await expect(n8n.canvas.getCanvasNodes()).toHaveCount(3);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test.describe('Chat Execution and Interaction', () => {
|
||||||
|
test('should be able to open and execute Basic LLM Chain node', async ({ n8n }) => {
|
||||||
|
await n8n.canvas.addNode(BASIC_LLM_CHAIN_NODE_NAME, { closeNDV: true });
|
||||||
|
|
||||||
|
await addOpenAILanguageModelWithCredentials(n8n, BASIC_LLM_CHAIN_NODE_NAME);
|
||||||
|
|
||||||
|
await n8n.canvas.openNode(BASIC_LLM_CHAIN_NODE_NAME);
|
||||||
|
const inputMessage = 'Hello!';
|
||||||
|
|
||||||
|
await n8n.ndv.execute();
|
||||||
|
await executeChatAndWaitForResponse(n8n, inputMessage);
|
||||||
|
|
||||||
|
// Verify chat message appears
|
||||||
|
await expect(n8n.canvas.getManualChatLatestBotMessage()).toBeVisible();
|
||||||
|
});
|
||||||
|
test('should be able to open and execute Agent node', async ({ n8n }) => {
|
||||||
|
await setupBasicAgentWorkflow(n8n);
|
||||||
|
|
||||||
|
const inputMessage = 'Hello!';
|
||||||
|
await n8n.canvas.clickManualChatButton();
|
||||||
|
await executeChatAndWaitForResponse(n8n, inputMessage);
|
||||||
|
|
||||||
|
// Verify chat message appears
|
||||||
|
await expect(n8n.canvas.getManualChatLatestBotMessage()).toBeVisible();
|
||||||
|
});
|
||||||
|
test('should add and use Manual Chat Trigger node together with Agent node', async ({
|
||||||
|
n8n,
|
||||||
|
}) => {
|
||||||
|
await setupBasicAgentWorkflow(n8n);
|
||||||
|
|
||||||
|
const inputMessage = 'Hello!';
|
||||||
|
await n8n.canvas.clickManualChatButton();
|
||||||
|
await executeChatAndWaitForResponse(n8n, inputMessage);
|
||||||
|
|
||||||
|
await verifyChatMessages(n8n, 2, inputMessage);
|
||||||
|
await verifyLogsPanelEntries(n8n, [
|
||||||
|
'When chat message received',
|
||||||
|
'AI Agent',
|
||||||
|
'OpenAI Chat Model',
|
||||||
|
]);
|
||||||
|
|
||||||
|
await n8n.canvas.closeManualChatModal();
|
||||||
|
await expect(n8n.canvas.logsPanel.getLogEntries()).toBeHidden();
|
||||||
|
await expect(n8n.canvas.getManualChatInput()).toBeHidden();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test.describe('Tool Usage Notifications', () => {
|
||||||
|
test('should show tool info notice if no existing tools were used during execution', async ({
|
||||||
|
n8n,
|
||||||
|
}) => {
|
||||||
|
await setupBasicAgentWorkflow(n8n, [AI_TOOL_CALCULATOR_NODE_NAME]);
|
||||||
|
await n8n.canvas.openNode(AGENT_NODE_NAME);
|
||||||
|
|
||||||
|
const inputMessage = 'Hello!';
|
||||||
|
await n8n.ndv.execute();
|
||||||
|
await executeChatAndWaitForResponse(n8n, inputMessage);
|
||||||
|
|
||||||
|
await n8n.canvas.closeManualChatModal();
|
||||||
|
await n8n.canvas.openNode(AGENT_NODE_NAME);
|
||||||
|
|
||||||
|
await expect(n8n.ndv.getRunDataInfoCallout()).toBeVisible();
|
||||||
|
});
|
||||||
|
test('should not show tool info notice if tools were used during execution', async ({
|
||||||
|
n8n,
|
||||||
|
}) => {
|
||||||
|
await n8n.canvas.addNode(MANUAL_CHAT_TRIGGER_NODE_NAME, { closeNDV: true });
|
||||||
|
await n8n.canvas.addNode(AGENT_NODE_NAME, { closeNDV: false });
|
||||||
|
await expect(n8n.ndv.getRunDataInfoCallout()).toBeHidden();
|
||||||
|
await n8n.ndv.clickBackToCanvasButton();
|
||||||
|
|
||||||
|
await addOpenAILanguageModelWithCredentials(n8n, AGENT_NODE_NAME);
|
||||||
|
|
||||||
|
await n8n.canvas.addSupplementalNodeToParent(
|
||||||
|
AI_TOOL_CALCULATOR_NODE_NAME,
|
||||||
|
'ai_tool',
|
||||||
|
AGENT_NODE_NAME,
|
||||||
|
{ closeNDV: true },
|
||||||
|
);
|
||||||
|
|
||||||
|
const inputMessage = 'What is 1000 * 10?';
|
||||||
|
await n8n.canvas.clickManualChatButton();
|
||||||
|
await executeChatAndWaitForResponse(n8n, inputMessage);
|
||||||
|
|
||||||
|
await n8n.canvas.closeManualChatModal();
|
||||||
|
await n8n.canvas.openNode(AGENT_NODE_NAME);
|
||||||
|
|
||||||
|
await expect(n8n.ndv.getRunDataInfoCallout()).toBeHidden();
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test.describe('Error Handling and Logs Display', () => {
|
||||||
|
// Helper function to set up the agent workflow with Postgres error configuration
|
||||||
|
async function setupAgentWorkflowWithPostgresError(n8n: n8nPage) {
|
||||||
|
await n8n.canvas.addNode(AGENT_NODE_NAME, { closeNDV: true });
|
||||||
|
|
||||||
|
// Add Calculator Tool (required for OpenAI model)
|
||||||
|
await n8n.canvas.addSupplementalNodeToParent(
|
||||||
|
AI_TOOL_CALCULATOR_NODE_NAME,
|
||||||
|
'ai_tool',
|
||||||
|
AGENT_NODE_NAME,
|
||||||
|
{ closeNDV: true },
|
||||||
|
);
|
||||||
|
|
||||||
|
// Add and configure Postgres Memory
|
||||||
|
await n8n.canvas.addSupplementalNodeToParent(
|
||||||
|
AI_MEMORY_POSTGRES_NODE_NAME,
|
||||||
|
'ai_memory',
|
||||||
|
AGENT_NODE_NAME,
|
||||||
|
{ closeNDV: false },
|
||||||
|
);
|
||||||
|
|
||||||
|
await n8n.ndv.clickCreateNewCredential();
|
||||||
|
await n8n.credentialsModal.setValues({
|
||||||
|
password: 'testtesttest',
|
||||||
|
});
|
||||||
|
|
||||||
|
await n8n.ndv.getParameterInput('sessionIdType').click();
|
||||||
|
await n8n.page.getByRole('option', { name: 'Define below' }).click();
|
||||||
|
await n8n.ndv.getParameterInput('sessionKey').locator('input').fill('asdasd');
|
||||||
|
await n8n.ndv.clickBackToCanvasButton();
|
||||||
|
|
||||||
|
// Add and configure OpenAI Language Model
|
||||||
|
await addOpenAILanguageModelWithCredentials(n8n, AGENT_NODE_NAME);
|
||||||
|
|
||||||
|
await n8n.canvas.clickZoomToFitButton();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to assert logs tab is active
|
||||||
|
async function assertLogsTabIsActive(n8n: n8nPage) {
|
||||||
|
await expect(n8n.ndv.getOutputDataContainer()).toBeVisible();
|
||||||
|
await expect(n8n.ndv.getAiOutputModeToggle()).toBeVisible();
|
||||||
|
|
||||||
|
const radioButtons = n8n.ndv.getAiOutputModeToggle().locator('[role="radio"]');
|
||||||
|
await expect(radioButtons).toHaveCount(2);
|
||||||
|
await expect(radioButtons.nth(1)).toHaveAttribute('aria-checked', 'true');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Helper function to assert error message is visible
|
||||||
|
async function assertErrorMessageVisible(n8n: n8nPage) {
|
||||||
|
await expect(
|
||||||
|
n8n.ndv.getOutputPanel().getByTestId('node-error-message').first(),
|
||||||
|
).toBeVisible();
|
||||||
|
await expect(
|
||||||
|
n8n.ndv.getOutputPanel().getByTestId('node-error-message').first(),
|
||||||
|
).toContainText('Error in sub-node');
|
||||||
|
}
|
||||||
|
|
||||||
|
test('should open logs tab by default when there was an error', async ({ n8n }) => {
|
||||||
|
await setupAgentWorkflowWithPostgresError(n8n);
|
||||||
|
|
||||||
|
const inputMessage = 'Test the code tool';
|
||||||
|
|
||||||
|
// Execute workflow with chat trigger
|
||||||
|
await n8n.canvas.clickManualChatButton();
|
||||||
|
await executeChatAndWaitForResponse(n8n, inputMessage);
|
||||||
|
|
||||||
|
// Check that messages and logs are displayed
|
||||||
|
const messages = await verifyChatMessages(n8n, 2, inputMessage);
|
||||||
|
await expect(messages.last()).toContainText(
|
||||||
|
'[ERROR: The service refused the connection - perhaps it is offline]',
|
||||||
|
);
|
||||||
|
|
||||||
|
await expect(n8n.canvas.logsPanel.getLogEntries().first()).toBeVisible();
|
||||||
|
await expect(n8n.canvas.logsPanel.getLogEntries()).toHaveCount(3);
|
||||||
|
await expect(n8n.canvas.logsPanel.getSelectedLogEntry()).toHaveText('AI Agent');
|
||||||
|
await expect(n8n.canvas.logsPanel.outputPanel.get()).toContainText(
|
||||||
|
AI_MEMORY_POSTGRES_NODE_NAME,
|
||||||
|
);
|
||||||
|
|
||||||
|
await n8n.canvas.closeManualChatModal();
|
||||||
|
|
||||||
|
// Open the AI Agent node to see the logs
|
||||||
|
await n8n.canvas.openNode(AGENT_NODE_NAME);
|
||||||
|
|
||||||
|
// Assert that logs tab is active and error is displayed
|
||||||
|
await assertLogsTabIsActive(n8n);
|
||||||
|
await assertErrorMessageVisible(n8n);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should switch to logs tab on error, when NDV is already opened', async ({ n8n }) => {
|
||||||
|
// Remove the auto-added chat trigger
|
||||||
|
await n8n.canvas.addNode(MANUAL_CHAT_TRIGGER_NODE_NAME, { closeNDV: false });
|
||||||
|
|
||||||
|
// Set manual trigger to output standard pinned data
|
||||||
|
await n8n.ndv.getEditPinnedDataButton().click();
|
||||||
|
await n8n.ndv.savePinnedData();
|
||||||
|
await n8n.ndv.close();
|
||||||
|
|
||||||
|
// Set up the same workflow components but with manual trigger
|
||||||
|
await setupAgentWorkflowWithPostgresError(n8n);
|
||||||
|
|
||||||
|
// Open the AI Agent node
|
||||||
|
await n8n.canvas.openNode(AGENT_NODE_NAME);
|
||||||
|
await n8n.ndv.getParameterInput('promptType').click();
|
||||||
|
await n8n.page.getByRole('option', { name: 'Define below' }).click();
|
||||||
|
await n8n.ndv.getParameterInput('text').locator('textarea').fill('Some text');
|
||||||
|
await n8n.ndv.execute();
|
||||||
|
await waitForWorkflowSuccess(n8n);
|
||||||
|
|
||||||
|
// Assert that logs tab is active and error is displayed
|
||||||
|
await assertLogsTabIsActive(n8n);
|
||||||
|
await assertErrorMessageVisible(n8n);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
test.describe('Advanced Workflow Features', () => {
|
||||||
|
test('should render runItems for sub-nodes and allow switching between them', async ({
|
||||||
|
n8n,
|
||||||
|
}) => {
|
||||||
|
await n8n.start.fromImportedWorkflow('In_memory_vector_store_fake_embeddings.json');
|
||||||
|
await n8n.canvas.clickZoomToFitButton();
|
||||||
|
await n8n.canvas.deselectAll();
|
||||||
|
|
||||||
|
await n8n.canvas.executeNode('Populate VS');
|
||||||
|
await waitForWorkflowSuccess(n8n);
|
||||||
|
|
||||||
|
const assertInputOutputTextExists = async (text: string) => {
|
||||||
|
await expect(n8n.ndv.getOutputPanel()).toContainText(text);
|
||||||
|
await expect(n8n.ndv.getInputPanel()).toContainText(text);
|
||||||
|
};
|
||||||
|
|
||||||
|
const assertInputOutputTextNotExists = async (text: string) => {
|
||||||
|
await expect(n8n.ndv.getOutputPanel()).not.toContainText(text);
|
||||||
|
await expect(n8n.ndv.getInputPanel()).not.toContainText(text);
|
||||||
|
};
|
||||||
|
|
||||||
|
await n8n.canvas.openNode('Character Text Splitter');
|
||||||
|
|
||||||
|
await expect(n8n.ndv.getOutputRunSelector()).toBeVisible();
|
||||||
|
await expect(n8n.ndv.getInputRunSelector()).toBeVisible();
|
||||||
|
await expect(n8n.ndv.getInputRunSelectorInput()).toHaveValue('3 of 3');
|
||||||
|
await expect(n8n.ndv.getOutputRunSelectorInput()).toHaveValue('3 of 3');
|
||||||
|
await assertInputOutputTextExists('Kyiv');
|
||||||
|
await assertInputOutputTextNotExists('Berlin');
|
||||||
|
await assertInputOutputTextNotExists('Prague');
|
||||||
|
|
||||||
|
await n8n.ndv.changeOutputRunSelector('2 of 3');
|
||||||
|
await assertInputOutputTextExists('Berlin');
|
||||||
|
await assertInputOutputTextNotExists('Kyiv');
|
||||||
|
await assertInputOutputTextNotExists('Prague');
|
||||||
|
|
||||||
|
await n8n.ndv.changeOutputRunSelector('1 of 3');
|
||||||
|
await assertInputOutputTextExists('Prague');
|
||||||
|
await assertInputOutputTextNotExists('Berlin');
|
||||||
|
await assertInputOutputTextNotExists('Kyiv');
|
||||||
|
|
||||||
|
await n8n.ndv.toggleInputRunLinking();
|
||||||
|
await n8n.ndv.changeOutputRunSelector('2 of 3');
|
||||||
|
await expect(n8n.ndv.getInputRunSelectorInput()).toHaveValue('1 of 3');
|
||||||
|
await expect(n8n.ndv.getOutputRunSelectorInput()).toHaveValue('2 of 3');
|
||||||
|
await expect(n8n.ndv.getInputPanel()).toContainText('Prague');
|
||||||
|
await expect(n8n.ndv.getInputPanel()).not.toContainText('Berlin');
|
||||||
|
|
||||||
|
await expect(n8n.ndv.getOutputPanel()).toContainText('Berlin');
|
||||||
|
await expect(n8n.ndv.getOutputPanel()).not.toContainText('Prague');
|
||||||
|
|
||||||
|
await n8n.ndv.toggleInputRunLinking();
|
||||||
|
await expect(n8n.ndv.getInputRunSelectorInput()).toHaveValue('1 of 3');
|
||||||
|
await expect(n8n.ndv.getOutputRunSelectorInput()).toHaveValue('1 of 3');
|
||||||
|
await assertInputOutputTextExists('Prague');
|
||||||
|
await assertInputOutputTextNotExists('Berlin');
|
||||||
|
await assertInputOutputTextNotExists('Kyiv');
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should execute up to Node 1 when using partial execution', async ({ n8n }) => {
|
||||||
|
await n8n.start.fromImportedWorkflow('Test_workflow_chat_partial_execution.json');
|
||||||
|
await n8n.canvas.clickZoomToFitButton();
|
||||||
|
|
||||||
|
// Check that chat modal is not initially visible
|
||||||
|
await expect(n8n.canvas.getManualChatModal().locator('main')).toBeHidden();
|
||||||
|
|
||||||
|
// Open Node 1 and execute it
|
||||||
|
await n8n.canvas.openNode('Node 1');
|
||||||
|
await n8n.ndv.execute();
|
||||||
|
// Chat modal should now be visible
|
||||||
|
await expect(n8n.canvas.getManualChatModal().locator('main')).toBeVisible();
|
||||||
|
|
||||||
|
// Send first message
|
||||||
|
await n8n.canvas.logsPanel.sendManualChatMessage('Test');
|
||||||
|
await expect(n8n.canvas.getManualChatLatestBotMessage()).toContainText('this_my_field_1');
|
||||||
|
|
||||||
|
// Refresh session
|
||||||
|
await n8n.page.getByTestId('refresh-session-button').click();
|
||||||
|
await expect(n8n.canvas.getManualChatMessages()).not.toBeAttached();
|
||||||
|
|
||||||
|
// Send another message
|
||||||
|
await n8n.canvas.logsPanel.sendManualChatMessage('Another test');
|
||||||
|
await expect(n8n.canvas.getManualChatLatestBotMessage()).toContainText('this_my_field_3');
|
||||||
|
await expect(n8n.canvas.getManualChatLatestBotMessage()).toContainText('this_my_field_4');
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,68 @@
|
|||||||
|
{
|
||||||
|
"nodes": [
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"id": "535fd3dd-e78f-4ffa-a085-79723fc81b38",
|
||||||
|
"name": "When chat message received",
|
||||||
|
"type": "@n8n/n8n-nodes-langchain.chatTrigger",
|
||||||
|
"typeVersion": 1.1,
|
||||||
|
"position": [320, -380],
|
||||||
|
"webhookId": "4fb58136-3481-494a-a30f-d9e064dac186"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"mode": "raw",
|
||||||
|
"jsonOutput": "{\n \"this_my_field_1\": \"value\",\n \"this_my_field_2\": 1\n}\n",
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"id": "78201ec2-6def-40b7-85e5-97b580d7f642",
|
||||||
|
"name": "Node 1",
|
||||||
|
"type": "n8n-nodes-base.set",
|
||||||
|
"typeVersion": 3.4,
|
||||||
|
"position": [580, -380]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"parameters": {
|
||||||
|
"mode": "raw",
|
||||||
|
"jsonOutput": "{\n \"this_my_field_3\": \"value\",\n \"this_my_field_4\": 1\n}\n",
|
||||||
|
"options": {}
|
||||||
|
},
|
||||||
|
"id": "1cfca06d-3ec3-427f-89f7-1ef321e025ff",
|
||||||
|
"name": "Node 2",
|
||||||
|
"type": "n8n-nodes-base.set",
|
||||||
|
"typeVersion": 3.4,
|
||||||
|
"position": [780, -380]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"connections": {
|
||||||
|
"When chat message received": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Node 1",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"Node 1": {
|
||||||
|
"main": [
|
||||||
|
[
|
||||||
|
{
|
||||||
|
"node": "Node 2",
|
||||||
|
"type": "main",
|
||||||
|
"index": 0
|
||||||
|
}
|
||||||
|
]
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"pinData": {},
|
||||||
|
"meta": {
|
||||||
|
"templateCredsSetupCompleted": true,
|
||||||
|
"instanceId": "178ef8a5109fc76c716d40bcadb720c455319f7b7a3fd5a39e4f336a091f524a"
|
||||||
|
}
|
||||||
|
}
|
||||||
243
pnpm-lock.yaml
generated
243
pnpm-lock.yaml
generated
@@ -3162,6 +3162,9 @@ importers:
|
|||||||
eslint-plugin-playwright:
|
eslint-plugin-playwright:
|
||||||
specifier: 2.2.2
|
specifier: 2.2.2
|
||||||
version: 2.2.2(eslint@9.29.0(jiti@1.21.7))
|
version: 2.2.2(eslint@9.29.0(jiti@1.21.7))
|
||||||
|
flatted:
|
||||||
|
specifier: 'catalog:'
|
||||||
|
version: 3.2.7
|
||||||
generate-schema:
|
generate-schema:
|
||||||
specifier: 2.6.0
|
specifier: 2.6.0
|
||||||
version: 2.6.0
|
version: 2.6.0
|
||||||
@@ -6385,201 +6388,101 @@ packages:
|
|||||||
rollup:
|
rollup:
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@rollup/rollup-android-arm-eabi@4.46.2':
|
|
||||||
resolution: {integrity: sha512-Zj3Hl6sN34xJtMv7Anwb5Gu01yujyE/cLBDB2gnHTAHaWS1Z38L7kuSG+oAh0giZMqG060f/YBStXtMH6FvPMA==}
|
|
||||||
cpu: [arm]
|
|
||||||
os: [android]
|
|
||||||
|
|
||||||
'@rollup/rollup-android-arm-eabi@4.49.0':
|
'@rollup/rollup-android-arm-eabi@4.49.0':
|
||||||
resolution: {integrity: sha512-rlKIeL854Ed0e09QGYFlmDNbka6I3EQFw7iZuugQjMb11KMpJCLPFL4ZPbMfaEhLADEL1yx0oujGkBQ7+qW3eA==}
|
resolution: {integrity: sha512-rlKIeL854Ed0e09QGYFlmDNbka6I3EQFw7iZuugQjMb11KMpJCLPFL4ZPbMfaEhLADEL1yx0oujGkBQ7+qW3eA==}
|
||||||
cpu: [arm]
|
cpu: [arm]
|
||||||
os: [android]
|
os: [android]
|
||||||
|
|
||||||
'@rollup/rollup-android-arm64@4.46.2':
|
|
||||||
resolution: {integrity: sha512-nTeCWY83kN64oQ5MGz3CgtPx8NSOhC5lWtsjTs+8JAJNLcP3QbLCtDDgUKQc/Ro/frpMq4SHUaHN6AMltcEoLQ==}
|
|
||||||
cpu: [arm64]
|
|
||||||
os: [android]
|
|
||||||
|
|
||||||
'@rollup/rollup-android-arm64@4.49.0':
|
'@rollup/rollup-android-arm64@4.49.0':
|
||||||
resolution: {integrity: sha512-cqPpZdKUSQYRtLLr6R4X3sD4jCBO1zUmeo3qrWBCqYIeH8Q3KRL4F3V7XJ2Rm8/RJOQBZuqzQGWPjjvFUcYa/w==}
|
resolution: {integrity: sha512-cqPpZdKUSQYRtLLr6R4X3sD4jCBO1zUmeo3qrWBCqYIeH8Q3KRL4F3V7XJ2Rm8/RJOQBZuqzQGWPjjvFUcYa/w==}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [android]
|
os: [android]
|
||||||
|
|
||||||
'@rollup/rollup-darwin-arm64@4.46.2':
|
|
||||||
resolution: {integrity: sha512-HV7bW2Fb/F5KPdM/9bApunQh68YVDU8sO8BvcW9OngQVN3HHHkw99wFupuUJfGR9pYLLAjcAOA6iO+evsbBaPQ==}
|
|
||||||
cpu: [arm64]
|
|
||||||
os: [darwin]
|
|
||||||
|
|
||||||
'@rollup/rollup-darwin-arm64@4.49.0':
|
'@rollup/rollup-darwin-arm64@4.49.0':
|
||||||
resolution: {integrity: sha512-99kMMSMQT7got6iYX3yyIiJfFndpojBmkHfTc1rIje8VbjhmqBXE+nb7ZZP3A5skLyujvT0eIUCUsxAe6NjWbw==}
|
resolution: {integrity: sha512-99kMMSMQT7got6iYX3yyIiJfFndpojBmkHfTc1rIje8VbjhmqBXE+nb7ZZP3A5skLyujvT0eIUCUsxAe6NjWbw==}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [darwin]
|
os: [darwin]
|
||||||
|
|
||||||
'@rollup/rollup-darwin-x64@4.46.2':
|
|
||||||
resolution: {integrity: sha512-SSj8TlYV5nJixSsm/y3QXfhspSiLYP11zpfwp6G/YDXctf3Xkdnk4woJIF5VQe0of2OjzTt8EsxnJDCdHd2xMA==}
|
|
||||||
cpu: [x64]
|
|
||||||
os: [darwin]
|
|
||||||
|
|
||||||
'@rollup/rollup-darwin-x64@4.49.0':
|
'@rollup/rollup-darwin-x64@4.49.0':
|
||||||
resolution: {integrity: sha512-y8cXoD3wdWUDpjOLMKLx6l+NFz3NlkWKcBCBfttUn+VGSfgsQ5o/yDUGtzE9HvsodkP0+16N0P4Ty1VuhtRUGg==}
|
resolution: {integrity: sha512-y8cXoD3wdWUDpjOLMKLx6l+NFz3NlkWKcBCBfttUn+VGSfgsQ5o/yDUGtzE9HvsodkP0+16N0P4Ty1VuhtRUGg==}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [darwin]
|
os: [darwin]
|
||||||
|
|
||||||
'@rollup/rollup-freebsd-arm64@4.46.2':
|
|
||||||
resolution: {integrity: sha512-ZyrsG4TIT9xnOlLsSSi9w/X29tCbK1yegE49RYm3tu3wF1L/B6LVMqnEWyDB26d9Ecx9zrmXCiPmIabVuLmNSg==}
|
|
||||||
cpu: [arm64]
|
|
||||||
os: [freebsd]
|
|
||||||
|
|
||||||
'@rollup/rollup-freebsd-arm64@4.49.0':
|
'@rollup/rollup-freebsd-arm64@4.49.0':
|
||||||
resolution: {integrity: sha512-3mY5Pr7qv4GS4ZvWoSP8zha8YoiqrU+e0ViPvB549jvliBbdNLrg2ywPGkgLC3cmvN8ya3za+Q2xVyT6z+vZqA==}
|
resolution: {integrity: sha512-3mY5Pr7qv4GS4ZvWoSP8zha8YoiqrU+e0ViPvB549jvliBbdNLrg2ywPGkgLC3cmvN8ya3za+Q2xVyT6z+vZqA==}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [freebsd]
|
os: [freebsd]
|
||||||
|
|
||||||
'@rollup/rollup-freebsd-x64@4.46.2':
|
|
||||||
resolution: {integrity: sha512-pCgHFoOECwVCJ5GFq8+gR8SBKnMO+xe5UEqbemxBpCKYQddRQMgomv1104RnLSg7nNvgKy05sLsY51+OVRyiVw==}
|
|
||||||
cpu: [x64]
|
|
||||||
os: [freebsd]
|
|
||||||
|
|
||||||
'@rollup/rollup-freebsd-x64@4.49.0':
|
'@rollup/rollup-freebsd-x64@4.49.0':
|
||||||
resolution: {integrity: sha512-C9KzzOAQU5gU4kG8DTk+tjdKjpWhVWd5uVkinCwwFub2m7cDYLOdtXoMrExfeBmeRy9kBQMkiyJ+HULyF1yj9w==}
|
resolution: {integrity: sha512-C9KzzOAQU5gU4kG8DTk+tjdKjpWhVWd5uVkinCwwFub2m7cDYLOdtXoMrExfeBmeRy9kBQMkiyJ+HULyF1yj9w==}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [freebsd]
|
os: [freebsd]
|
||||||
|
|
||||||
'@rollup/rollup-linux-arm-gnueabihf@4.46.2':
|
|
||||||
resolution: {integrity: sha512-EtP8aquZ0xQg0ETFcxUbU71MZlHaw9MChwrQzatiE8U/bvi5uv/oChExXC4mWhjiqK7azGJBqU0tt5H123SzVA==}
|
|
||||||
cpu: [arm]
|
|
||||||
os: [linux]
|
|
||||||
|
|
||||||
'@rollup/rollup-linux-arm-gnueabihf@4.49.0':
|
'@rollup/rollup-linux-arm-gnueabihf@4.49.0':
|
||||||
resolution: {integrity: sha512-OVSQgEZDVLnTbMq5NBs6xkmz3AADByCWI4RdKSFNlDsYXdFtlxS59J+w+LippJe8KcmeSSM3ba+GlsM9+WwC1w==}
|
resolution: {integrity: sha512-OVSQgEZDVLnTbMq5NBs6xkmz3AADByCWI4RdKSFNlDsYXdFtlxS59J+w+LippJe8KcmeSSM3ba+GlsM9+WwC1w==}
|
||||||
cpu: [arm]
|
cpu: [arm]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
'@rollup/rollup-linux-arm-musleabihf@4.46.2':
|
|
||||||
resolution: {integrity: sha512-qO7F7U3u1nfxYRPM8HqFtLd+raev2K137dsV08q/LRKRLEc7RsiDWihUnrINdsWQxPR9jqZ8DIIZ1zJJAm5PjQ==}
|
|
||||||
cpu: [arm]
|
|
||||||
os: [linux]
|
|
||||||
|
|
||||||
'@rollup/rollup-linux-arm-musleabihf@4.49.0':
|
'@rollup/rollup-linux-arm-musleabihf@4.49.0':
|
||||||
resolution: {integrity: sha512-ZnfSFA7fDUHNa4P3VwAcfaBLakCbYaxCk0jUnS3dTou9P95kwoOLAMlT3WmEJDBCSrOEFFV0Y1HXiwfLYJuLlA==}
|
resolution: {integrity: sha512-ZnfSFA7fDUHNa4P3VwAcfaBLakCbYaxCk0jUnS3dTou9P95kwoOLAMlT3WmEJDBCSrOEFFV0Y1HXiwfLYJuLlA==}
|
||||||
cpu: [arm]
|
cpu: [arm]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
'@rollup/rollup-linux-arm64-gnu@4.46.2':
|
|
||||||
resolution: {integrity: sha512-3dRaqLfcOXYsfvw5xMrxAk9Lb1f395gkoBYzSFcc/scgRFptRXL9DOaDpMiehf9CO8ZDRJW2z45b6fpU5nwjng==}
|
|
||||||
cpu: [arm64]
|
|
||||||
os: [linux]
|
|
||||||
|
|
||||||
'@rollup/rollup-linux-arm64-gnu@4.49.0':
|
'@rollup/rollup-linux-arm64-gnu@4.49.0':
|
||||||
resolution: {integrity: sha512-Z81u+gfrobVK2iV7GqZCBfEB1y6+I61AH466lNK+xy1jfqFLiQ9Qv716WUM5fxFrYxwC7ziVdZRU9qvGHkYIJg==}
|
resolution: {integrity: sha512-Z81u+gfrobVK2iV7GqZCBfEB1y6+I61AH466lNK+xy1jfqFLiQ9Qv716WUM5fxFrYxwC7ziVdZRU9qvGHkYIJg==}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
'@rollup/rollup-linux-arm64-musl@4.46.2':
|
|
||||||
resolution: {integrity: sha512-fhHFTutA7SM+IrR6lIfiHskxmpmPTJUXpWIsBXpeEwNgZzZZSg/q4i6FU4J8qOGyJ0TR+wXBwx/L7Ho9z0+uDg==}
|
|
||||||
cpu: [arm64]
|
|
||||||
os: [linux]
|
|
||||||
|
|
||||||
'@rollup/rollup-linux-arm64-musl@4.49.0':
|
'@rollup/rollup-linux-arm64-musl@4.49.0':
|
||||||
resolution: {integrity: sha512-zoAwS0KCXSnTp9NH/h9aamBAIve0DXeYpll85shf9NJ0URjSTzzS+Z9evmolN+ICfD3v8skKUPyk2PO0uGdFqg==}
|
resolution: {integrity: sha512-zoAwS0KCXSnTp9NH/h9aamBAIve0DXeYpll85shf9NJ0URjSTzzS+Z9evmolN+ICfD3v8skKUPyk2PO0uGdFqg==}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
'@rollup/rollup-linux-loongarch64-gnu@4.46.2':
|
|
||||||
resolution: {integrity: sha512-i7wfGFXu8x4+FRqPymzjD+Hyav8l95UIZ773j7J7zRYc3Xsxy2wIn4x+llpunexXe6laaO72iEjeeGyUFmjKeA==}
|
|
||||||
cpu: [loong64]
|
|
||||||
os: [linux]
|
|
||||||
|
|
||||||
'@rollup/rollup-linux-loongarch64-gnu@4.49.0':
|
'@rollup/rollup-linux-loongarch64-gnu@4.49.0':
|
||||||
resolution: {integrity: sha512-2QyUyQQ1ZtwZGiq0nvODL+vLJBtciItC3/5cYN8ncDQcv5avrt2MbKt1XU/vFAJlLta5KujqyHdYtdag4YEjYQ==}
|
resolution: {integrity: sha512-2QyUyQQ1ZtwZGiq0nvODL+vLJBtciItC3/5cYN8ncDQcv5avrt2MbKt1XU/vFAJlLta5KujqyHdYtdag4YEjYQ==}
|
||||||
cpu: [loong64]
|
cpu: [loong64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
'@rollup/rollup-linux-ppc64-gnu@4.46.2':
|
|
||||||
resolution: {integrity: sha512-B/l0dFcHVUnqcGZWKcWBSV2PF01YUt0Rvlurci5P+neqY/yMKchGU8ullZvIv5e8Y1C6wOn+U03mrDylP5q9Yw==}
|
|
||||||
cpu: [ppc64]
|
|
||||||
os: [linux]
|
|
||||||
|
|
||||||
'@rollup/rollup-linux-ppc64-gnu@4.49.0':
|
'@rollup/rollup-linux-ppc64-gnu@4.49.0':
|
||||||
resolution: {integrity: sha512-k9aEmOWt+mrMuD3skjVJSSxHckJp+SiFzFG+v8JLXbc/xi9hv2icSkR3U7uQzqy+/QbbYY7iNB9eDTwrELo14g==}
|
resolution: {integrity: sha512-k9aEmOWt+mrMuD3skjVJSSxHckJp+SiFzFG+v8JLXbc/xi9hv2icSkR3U7uQzqy+/QbbYY7iNB9eDTwrELo14g==}
|
||||||
cpu: [ppc64]
|
cpu: [ppc64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
'@rollup/rollup-linux-riscv64-gnu@4.46.2':
|
|
||||||
resolution: {integrity: sha512-32k4ENb5ygtkMwPMucAb8MtV8olkPT03oiTxJbgkJa7lJ7dZMr0GCFJlyvy+K8iq7F/iuOr41ZdUHaOiqyR3iQ==}
|
|
||||||
cpu: [riscv64]
|
|
||||||
os: [linux]
|
|
||||||
|
|
||||||
'@rollup/rollup-linux-riscv64-gnu@4.49.0':
|
'@rollup/rollup-linux-riscv64-gnu@4.49.0':
|
||||||
resolution: {integrity: sha512-rDKRFFIWJ/zJn6uk2IdYLc09Z7zkE5IFIOWqpuU0o6ZpHcdniAyWkwSUWE/Z25N/wNDmFHHMzin84qW7Wzkjsw==}
|
resolution: {integrity: sha512-rDKRFFIWJ/zJn6uk2IdYLc09Z7zkE5IFIOWqpuU0o6ZpHcdniAyWkwSUWE/Z25N/wNDmFHHMzin84qW7Wzkjsw==}
|
||||||
cpu: [riscv64]
|
cpu: [riscv64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
'@rollup/rollup-linux-riscv64-musl@4.46.2':
|
|
||||||
resolution: {integrity: sha512-t5B2loThlFEauloaQkZg9gxV05BYeITLvLkWOkRXogP4qHXLkWSbSHKM9S6H1schf/0YGP/qNKtiISlxvfmmZw==}
|
|
||||||
cpu: [riscv64]
|
|
||||||
os: [linux]
|
|
||||||
|
|
||||||
'@rollup/rollup-linux-riscv64-musl@4.49.0':
|
'@rollup/rollup-linux-riscv64-musl@4.49.0':
|
||||||
resolution: {integrity: sha512-FkkhIY/hYFVnOzz1WeV3S9Bd1h0hda/gRqvZCMpHWDHdiIHn6pqsY3b5eSbvGccWHMQ1uUzgZTKS4oGpykf8Tw==}
|
resolution: {integrity: sha512-FkkhIY/hYFVnOzz1WeV3S9Bd1h0hda/gRqvZCMpHWDHdiIHn6pqsY3b5eSbvGccWHMQ1uUzgZTKS4oGpykf8Tw==}
|
||||||
cpu: [riscv64]
|
cpu: [riscv64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
'@rollup/rollup-linux-s390x-gnu@4.46.2':
|
|
||||||
resolution: {integrity: sha512-YKjekwTEKgbB7n17gmODSmJVUIvj8CX7q5442/CK80L8nqOUbMtf8b01QkG3jOqyr1rotrAnW6B/qiHwfcuWQA==}
|
|
||||||
cpu: [s390x]
|
|
||||||
os: [linux]
|
|
||||||
|
|
||||||
'@rollup/rollup-linux-s390x-gnu@4.49.0':
|
'@rollup/rollup-linux-s390x-gnu@4.49.0':
|
||||||
resolution: {integrity: sha512-gRf5c+A7QiOG3UwLyOOtyJMD31JJhMjBvpfhAitPAoqZFcOeK3Kc1Veg1z/trmt+2P6F/biT02fU19GGTS529A==}
|
resolution: {integrity: sha512-gRf5c+A7QiOG3UwLyOOtyJMD31JJhMjBvpfhAitPAoqZFcOeK3Kc1Veg1z/trmt+2P6F/biT02fU19GGTS529A==}
|
||||||
cpu: [s390x]
|
cpu: [s390x]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
'@rollup/rollup-linux-x64-gnu@4.46.2':
|
|
||||||
resolution: {integrity: sha512-Jj5a9RUoe5ra+MEyERkDKLwTXVu6s3aACP51nkfnK9wJTraCC8IMe3snOfALkrjTYd2G1ViE1hICj0fZ7ALBPA==}
|
|
||||||
cpu: [x64]
|
|
||||||
os: [linux]
|
|
||||||
|
|
||||||
'@rollup/rollup-linux-x64-gnu@4.49.0':
|
'@rollup/rollup-linux-x64-gnu@4.49.0':
|
||||||
resolution: {integrity: sha512-BR7+blScdLW1h/2hB/2oXM+dhTmpW3rQt1DeSiCP9mc2NMMkqVgjIN3DDsNpKmezffGC9R8XKVOLmBkRUcK/sA==}
|
resolution: {integrity: sha512-BR7+blScdLW1h/2hB/2oXM+dhTmpW3rQt1DeSiCP9mc2NMMkqVgjIN3DDsNpKmezffGC9R8XKVOLmBkRUcK/sA==}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
'@rollup/rollup-linux-x64-musl@4.46.2':
|
|
||||||
resolution: {integrity: sha512-7kX69DIrBeD7yNp4A5b81izs8BqoZkCIaxQaOpumcJ1S/kmqNFjPhDu1LHeVXv0SexfHQv5cqHsxLOjETuqDuA==}
|
|
||||||
cpu: [x64]
|
|
||||||
os: [linux]
|
|
||||||
|
|
||||||
'@rollup/rollup-linux-x64-musl@4.49.0':
|
'@rollup/rollup-linux-x64-musl@4.49.0':
|
||||||
resolution: {integrity: sha512-hDMOAe+6nX3V5ei1I7Au3wcr9h3ktKzDvF2ne5ovX8RZiAHEtX1A5SNNk4zt1Qt77CmnbqT+upb/umzoPMWiPg==}
|
resolution: {integrity: sha512-hDMOAe+6nX3V5ei1I7Au3wcr9h3ktKzDvF2ne5ovX8RZiAHEtX1A5SNNk4zt1Qt77CmnbqT+upb/umzoPMWiPg==}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
os: [linux]
|
os: [linux]
|
||||||
|
|
||||||
'@rollup/rollup-win32-arm64-msvc@4.46.2':
|
|
||||||
resolution: {integrity: sha512-wiJWMIpeaak/jsbaq2HMh/rzZxHVW1rU6coyeNNpMwk5isiPjSTx0a4YLSlYDwBH/WBvLz+EtsNqQScZTLJy3g==}
|
|
||||||
cpu: [arm64]
|
|
||||||
os: [win32]
|
|
||||||
|
|
||||||
'@rollup/rollup-win32-arm64-msvc@4.49.0':
|
'@rollup/rollup-win32-arm64-msvc@4.49.0':
|
||||||
resolution: {integrity: sha512-wkNRzfiIGaElC9kXUT+HLx17z7D0jl+9tGYRKwd8r7cUqTL7GYAvgUY++U2hK6Ar7z5Z6IRRoWC8kQxpmM7TDA==}
|
resolution: {integrity: sha512-wkNRzfiIGaElC9kXUT+HLx17z7D0jl+9tGYRKwd8r7cUqTL7GYAvgUY++U2hK6Ar7z5Z6IRRoWC8kQxpmM7TDA==}
|
||||||
cpu: [arm64]
|
cpu: [arm64]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
|
|
||||||
'@rollup/rollup-win32-ia32-msvc@4.46.2':
|
|
||||||
resolution: {integrity: sha512-gBgaUDESVzMgWZhcyjfs9QFK16D8K6QZpwAaVNJxYDLHWayOta4ZMjGm/vsAEy3hvlS2GosVFlBlP9/Wb85DqQ==}
|
|
||||||
cpu: [ia32]
|
|
||||||
os: [win32]
|
|
||||||
|
|
||||||
'@rollup/rollup-win32-ia32-msvc@4.49.0':
|
'@rollup/rollup-win32-ia32-msvc@4.49.0':
|
||||||
resolution: {integrity: sha512-gq5aW/SyNpjp71AAzroH37DtINDcX1Qw2iv9Chyz49ZgdOP3NV8QCyKZUrGsYX9Yyggj5soFiRCgsL3HwD8TdA==}
|
resolution: {integrity: sha512-gq5aW/SyNpjp71AAzroH37DtINDcX1Qw2iv9Chyz49ZgdOP3NV8QCyKZUrGsYX9Yyggj5soFiRCgsL3HwD8TdA==}
|
||||||
cpu: [ia32]
|
cpu: [ia32]
|
||||||
os: [win32]
|
os: [win32]
|
||||||
|
|
||||||
'@rollup/rollup-win32-x64-msvc@4.46.2':
|
|
||||||
resolution: {integrity: sha512-CvUo2ixeIQGtF6WvuB87XWqPQkoFAFqW+HUo/WzHwuHDvIwZCtjdWXoYCcr06iKGydiqTclC4jU/TNObC/xKZg==}
|
|
||||||
cpu: [x64]
|
|
||||||
os: [win32]
|
|
||||||
|
|
||||||
'@rollup/rollup-win32-x64-msvc@4.49.0':
|
'@rollup/rollup-win32-x64-msvc@4.49.0':
|
||||||
resolution: {integrity: sha512-gEtqFbzmZLFk2xKh7g0Rlo8xzho8KrEFEkzvHbfUGkrgXOpZ4XagQ6n+wIZFNh1nTb8UD16J4nFSFKXYgnbdBg==}
|
resolution: {integrity: sha512-gEtqFbzmZLFk2xKh7g0Rlo8xzho8KrEFEkzvHbfUGkrgXOpZ4XagQ6n+wIZFNh1nTb8UD16J4nFSFKXYgnbdBg==}
|
||||||
cpu: [x64]
|
cpu: [x64]
|
||||||
@@ -14333,7 +14236,6 @@ packages:
|
|||||||
resolution: {integrity: sha512-gv6vLGcmAOg96/fgo3d9tvA4dJNZL3fMyBqVRrGxQ+Q/o4k9QzbJ3NQF9cOO/71wRodoXhaPgphvMFU68qVAJQ==}
|
resolution: {integrity: sha512-gv6vLGcmAOg96/fgo3d9tvA4dJNZL3fMyBqVRrGxQ+Q/o4k9QzbJ3NQF9cOO/71wRodoXhaPgphvMFU68qVAJQ==}
|
||||||
deprecated: |-
|
deprecated: |-
|
||||||
You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other.
|
You or someone you depend on is using Q, the JavaScript Promise library that gave JavaScript developers strong feelings about promises. They can almost certainly migrate to the native JavaScript promise now. Thank you literally everyone for joining me in this bet against the odds. Be excellent to each other.
|
||||||
|
|
||||||
(For a CapTP with native promises, see @endo/eventual-send and @endo/captp)
|
(For a CapTP with native promises, see @endo/eventual-send and @endo/captp)
|
||||||
|
|
||||||
qrcode.vue@3.3.4:
|
qrcode.vue@3.3.4:
|
||||||
@@ -14723,11 +14625,6 @@ packages:
|
|||||||
rndm@1.2.0:
|
rndm@1.2.0:
|
||||||
resolution: {integrity: sha512-fJhQQI5tLrQvYIYFpOnFinzv9dwmR7hRnUz1XqP3OJ1jIweTNOd6aTO4jwQSgcBSFUB+/KHJxuGneime+FdzOw==}
|
resolution: {integrity: sha512-fJhQQI5tLrQvYIYFpOnFinzv9dwmR7hRnUz1XqP3OJ1jIweTNOd6aTO4jwQSgcBSFUB+/KHJxuGneime+FdzOw==}
|
||||||
|
|
||||||
rollup@4.46.2:
|
|
||||||
resolution: {integrity: sha512-WMmLFI+Boh6xbop+OAGo9cQ3OgX9MIg7xOQjn+pTCwOkk+FNDAeAemXkJ3HzDJrVXleLOFVa1ipuc1AmEx1Dwg==}
|
|
||||||
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
|
|
||||||
hasBin: true
|
|
||||||
|
|
||||||
rollup@4.49.0:
|
rollup@4.49.0:
|
||||||
resolution: {integrity: sha512-3IVq0cGJ6H7fKXXEdVt+RcYvRCt8beYY9K1760wGQwSAHZcS9eot1zDG5axUbcp/kWRi5zKIIDX8MoKv/TzvZA==}
|
resolution: {integrity: sha512-3IVq0cGJ6H7fKXXEdVt+RcYvRCt8beYY9K1760wGQwSAHZcS9eot1zDG5axUbcp/kWRi5zKIIDX8MoKv/TzvZA==}
|
||||||
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
|
engines: {node: '>=18.0.0', npm: '>=8.0.0'}
|
||||||
@@ -19663,7 +19560,7 @@ snapshots:
|
|||||||
'@jest/console@29.6.2':
|
'@jest/console@29.6.2':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@jest/types': 29.6.1
|
'@jest/types': 29.6.1
|
||||||
'@types/node': 20.19.10
|
'@types/node': 20.19.11
|
||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
jest-message-util: 29.6.2
|
jest-message-util: 29.6.2
|
||||||
jest-util: 29.6.2
|
jest-util: 29.6.2
|
||||||
@@ -19783,7 +19680,7 @@ snapshots:
|
|||||||
'@jest/transform': 29.6.2
|
'@jest/transform': 29.6.2
|
||||||
'@jest/types': 29.6.1
|
'@jest/types': 29.6.1
|
||||||
'@jridgewell/trace-mapping': 0.3.30
|
'@jridgewell/trace-mapping': 0.3.30
|
||||||
'@types/node': 20.19.10
|
'@types/node': 20.19.11
|
||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
collect-v8-coverage: 1.0.1
|
collect-v8-coverage: 1.0.1
|
||||||
exit: 0.1.2
|
exit: 0.1.2
|
||||||
@@ -21083,123 +20980,63 @@ snapshots:
|
|||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
rollup: 4.49.0
|
rollup: 4.49.0
|
||||||
|
|
||||||
'@rollup/rollup-android-arm-eabi@4.46.2':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@rollup/rollup-android-arm-eabi@4.49.0':
|
'@rollup/rollup-android-arm-eabi@4.49.0':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@rollup/rollup-android-arm64@4.46.2':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@rollup/rollup-android-arm64@4.49.0':
|
'@rollup/rollup-android-arm64@4.49.0':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@rollup/rollup-darwin-arm64@4.46.2':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@rollup/rollup-darwin-arm64@4.49.0':
|
'@rollup/rollup-darwin-arm64@4.49.0':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@rollup/rollup-darwin-x64@4.46.2':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@rollup/rollup-darwin-x64@4.49.0':
|
'@rollup/rollup-darwin-x64@4.49.0':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@rollup/rollup-freebsd-arm64@4.46.2':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@rollup/rollup-freebsd-arm64@4.49.0':
|
'@rollup/rollup-freebsd-arm64@4.49.0':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@rollup/rollup-freebsd-x64@4.46.2':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@rollup/rollup-freebsd-x64@4.49.0':
|
'@rollup/rollup-freebsd-x64@4.49.0':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@rollup/rollup-linux-arm-gnueabihf@4.46.2':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@rollup/rollup-linux-arm-gnueabihf@4.49.0':
|
'@rollup/rollup-linux-arm-gnueabihf@4.49.0':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@rollup/rollup-linux-arm-musleabihf@4.46.2':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@rollup/rollup-linux-arm-musleabihf@4.49.0':
|
'@rollup/rollup-linux-arm-musleabihf@4.49.0':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@rollup/rollup-linux-arm64-gnu@4.46.2':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@rollup/rollup-linux-arm64-gnu@4.49.0':
|
'@rollup/rollup-linux-arm64-gnu@4.49.0':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@rollup/rollup-linux-arm64-musl@4.46.2':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@rollup/rollup-linux-arm64-musl@4.49.0':
|
'@rollup/rollup-linux-arm64-musl@4.49.0':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@rollup/rollup-linux-loongarch64-gnu@4.46.2':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@rollup/rollup-linux-loongarch64-gnu@4.49.0':
|
'@rollup/rollup-linux-loongarch64-gnu@4.49.0':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@rollup/rollup-linux-ppc64-gnu@4.46.2':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@rollup/rollup-linux-ppc64-gnu@4.49.0':
|
'@rollup/rollup-linux-ppc64-gnu@4.49.0':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@rollup/rollup-linux-riscv64-gnu@4.46.2':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@rollup/rollup-linux-riscv64-gnu@4.49.0':
|
'@rollup/rollup-linux-riscv64-gnu@4.49.0':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@rollup/rollup-linux-riscv64-musl@4.46.2':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@rollup/rollup-linux-riscv64-musl@4.49.0':
|
'@rollup/rollup-linux-riscv64-musl@4.49.0':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@rollup/rollup-linux-s390x-gnu@4.46.2':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@rollup/rollup-linux-s390x-gnu@4.49.0':
|
'@rollup/rollup-linux-s390x-gnu@4.49.0':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@rollup/rollup-linux-x64-gnu@4.46.2':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@rollup/rollup-linux-x64-gnu@4.49.0':
|
'@rollup/rollup-linux-x64-gnu@4.49.0':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@rollup/rollup-linux-x64-musl@4.46.2':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@rollup/rollup-linux-x64-musl@4.49.0':
|
'@rollup/rollup-linux-x64-musl@4.49.0':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@rollup/rollup-win32-arm64-msvc@4.46.2':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@rollup/rollup-win32-arm64-msvc@4.49.0':
|
'@rollup/rollup-win32-arm64-msvc@4.49.0':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@rollup/rollup-win32-ia32-msvc@4.46.2':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@rollup/rollup-win32-ia32-msvc@4.49.0':
|
'@rollup/rollup-win32-ia32-msvc@4.49.0':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@rollup/rollup-win32-x64-msvc@4.46.2':
|
|
||||||
optional: true
|
|
||||||
|
|
||||||
'@rollup/rollup-win32-x64-msvc@4.49.0':
|
'@rollup/rollup-win32-x64-msvc@4.49.0':
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
@@ -22309,7 +22146,7 @@ snapshots:
|
|||||||
|
|
||||||
'@types/basic-auth@1.1.3':
|
'@types/basic-auth@1.1.3':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 20.19.10
|
'@types/node': 20.19.11
|
||||||
|
|
||||||
'@types/bcryptjs@2.4.2': {}
|
'@types/bcryptjs@2.4.2': {}
|
||||||
|
|
||||||
@@ -22318,7 +22155,7 @@ snapshots:
|
|||||||
'@types/body-parser@1.19.2':
|
'@types/body-parser@1.19.2':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/connect': 3.4.38
|
'@types/connect': 3.4.38
|
||||||
'@types/node': 20.19.10
|
'@types/node': 20.19.11
|
||||||
|
|
||||||
'@types/caseless@0.12.5': {}
|
'@types/caseless@0.12.5': {}
|
||||||
|
|
||||||
@@ -22336,7 +22173,7 @@ snapshots:
|
|||||||
|
|
||||||
'@types/connect@3.4.38':
|
'@types/connect@3.4.38':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 20.19.10
|
'@types/node': 20.19.11
|
||||||
|
|
||||||
'@types/convict@6.1.1':
|
'@types/convict@6.1.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -22376,7 +22213,7 @@ snapshots:
|
|||||||
|
|
||||||
'@types/express-serve-static-core@5.0.6(patch_hash=d602248fcd302cf5a794d1e85a411633ba9635ea5d566d6f2e0429c7ae0fa3eb)':
|
'@types/express-serve-static-core@5.0.6(patch_hash=d602248fcd302cf5a794d1e85a411633ba9635ea5d566d6f2e0429c7ae0fa3eb)':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 20.19.10
|
'@types/node': 20.19.11
|
||||||
'@types/qs': 6.9.15
|
'@types/qs': 6.9.15
|
||||||
'@types/range-parser': 1.2.4
|
'@types/range-parser': 1.2.4
|
||||||
'@types/send': 0.17.4
|
'@types/send': 0.17.4
|
||||||
@@ -22480,7 +22317,7 @@ snapshots:
|
|||||||
'@types/jsonwebtoken@9.0.9':
|
'@types/jsonwebtoken@9.0.9':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/ms': 2.1.0
|
'@types/ms': 2.1.0
|
||||||
'@types/node': 20.19.10
|
'@types/node': 20.19.11
|
||||||
|
|
||||||
'@types/k6@0.52.0': {}
|
'@types/k6@0.52.0': {}
|
||||||
|
|
||||||
@@ -22548,7 +22385,7 @@ snapshots:
|
|||||||
|
|
||||||
'@types/mysql@2.15.26':
|
'@types/mysql@2.15.26':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 20.19.10
|
'@types/node': 20.19.11
|
||||||
|
|
||||||
'@types/node-fetch@2.6.13':
|
'@types/node-fetch@2.6.13':
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -22587,7 +22424,7 @@ snapshots:
|
|||||||
|
|
||||||
'@types/pg@8.6.1':
|
'@types/pg@8.6.1':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 20.19.10
|
'@types/node': 20.19.11
|
||||||
pg-protocol: 1.6.1
|
pg-protocol: 1.6.1
|
||||||
pg-types: 2.2.0
|
pg-types: 2.2.0
|
||||||
|
|
||||||
@@ -22624,7 +22461,7 @@ snapshots:
|
|||||||
|
|
||||||
'@types/readable-stream@4.0.10':
|
'@types/readable-stream@4.0.10':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 20.19.10
|
'@types/node': 20.19.11
|
||||||
safe-buffer: 5.1.2
|
safe-buffer: 5.1.2
|
||||||
|
|
||||||
'@types/replacestream@4.0.1': {}
|
'@types/replacestream@4.0.1': {}
|
||||||
@@ -22632,7 +22469,7 @@ snapshots:
|
|||||||
'@types/request@2.48.12':
|
'@types/request@2.48.12':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/caseless': 0.12.5
|
'@types/caseless': 0.12.5
|
||||||
'@types/node': 20.19.10
|
'@types/node': 20.19.11
|
||||||
'@types/tough-cookie': 4.0.5
|
'@types/tough-cookie': 4.0.5
|
||||||
form-data: 4.0.4
|
form-data: 4.0.4
|
||||||
|
|
||||||
@@ -22653,12 +22490,12 @@ snapshots:
|
|||||||
'@types/send@0.17.4':
|
'@types/send@0.17.4':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/mime': 1.3.5
|
'@types/mime': 1.3.5
|
||||||
'@types/node': 20.19.10
|
'@types/node': 20.19.11
|
||||||
|
|
||||||
'@types/serve-static@1.15.0':
|
'@types/serve-static@1.15.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/mime': 3.0.1
|
'@types/mime': 3.0.1
|
||||||
'@types/node': 20.19.10
|
'@types/node': 20.19.11
|
||||||
|
|
||||||
'@types/shelljs@0.8.11':
|
'@types/shelljs@0.8.11':
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -22722,7 +22559,7 @@ snapshots:
|
|||||||
|
|
||||||
'@types/tedious@4.0.14':
|
'@types/tedious@4.0.14':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 20.19.10
|
'@types/node': 20.19.11
|
||||||
|
|
||||||
'@types/tedious@4.0.9':
|
'@types/tedious@4.0.9':
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -22776,7 +22613,7 @@ snapshots:
|
|||||||
|
|
||||||
'@types/xml2js@0.4.14':
|
'@types/xml2js@0.4.14':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 20.19.10
|
'@types/node': 20.19.11
|
||||||
|
|
||||||
'@types/yamljs@0.2.31': {}
|
'@types/yamljs@0.2.31': {}
|
||||||
|
|
||||||
@@ -22788,7 +22625,7 @@ snapshots:
|
|||||||
|
|
||||||
'@types/yauzl@2.10.0':
|
'@types/yauzl@2.10.0':
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/node': 20.19.10
|
'@types/node': 20.19.11
|
||||||
optional: true
|
optional: true
|
||||||
|
|
||||||
'@typescript-eslint/eslint-plugin@8.35.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.29.0(jiti@1.21.7))(typescript@5.9.2)':
|
'@typescript-eslint/eslint-plugin@8.35.0(@typescript-eslint/parser@8.35.0(eslint@9.29.0(jiti@1.21.7))(typescript@5.9.2))(eslint@9.29.0(jiti@1.21.7))(typescript@5.9.2)':
|
||||||
@@ -26540,7 +26377,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
magic-string: 0.30.17
|
magic-string: 0.30.17
|
||||||
mlly: 1.7.4
|
mlly: 1.7.4
|
||||||
rollup: 4.46.2
|
rollup: 4.49.0
|
||||||
|
|
||||||
flat-cache@4.0.1:
|
flat-cache@4.0.1:
|
||||||
dependencies:
|
dependencies:
|
||||||
@@ -28036,7 +27873,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@jest/types': 29.6.1
|
'@jest/types': 29.6.1
|
||||||
'@types/graceful-fs': 4.1.6
|
'@types/graceful-fs': 4.1.6
|
||||||
'@types/node': 20.19.10
|
'@types/node': 20.19.11
|
||||||
anymatch: 3.1.3
|
anymatch: 3.1.3
|
||||||
fb-watchman: 2.0.2
|
fb-watchman: 2.0.2
|
||||||
graceful-fs: 4.2.11
|
graceful-fs: 4.2.11
|
||||||
@@ -28148,7 +27985,7 @@ snapshots:
|
|||||||
'@jest/test-result': 29.6.2
|
'@jest/test-result': 29.6.2
|
||||||
'@jest/transform': 29.6.2
|
'@jest/transform': 29.6.2
|
||||||
'@jest/types': 29.6.1
|
'@jest/types': 29.6.1
|
||||||
'@types/node': 20.19.10
|
'@types/node': 20.19.11
|
||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
emittery: 0.13.1
|
emittery: 0.13.1
|
||||||
graceful-fs: 4.2.11
|
graceful-fs: 4.2.11
|
||||||
@@ -28176,7 +28013,7 @@ snapshots:
|
|||||||
'@jest/test-result': 29.6.2
|
'@jest/test-result': 29.6.2
|
||||||
'@jest/transform': 29.6.2
|
'@jest/transform': 29.6.2
|
||||||
'@jest/types': 29.6.1
|
'@jest/types': 29.6.1
|
||||||
'@types/node': 20.19.10
|
'@types/node': 20.19.11
|
||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
cjs-module-lexer: 1.2.2
|
cjs-module-lexer: 1.2.2
|
||||||
collect-v8-coverage: 1.0.1
|
collect-v8-coverage: 1.0.1
|
||||||
@@ -28250,7 +28087,7 @@ snapshots:
|
|||||||
dependencies:
|
dependencies:
|
||||||
'@jest/test-result': 29.6.2
|
'@jest/test-result': 29.6.2
|
||||||
'@jest/types': 29.6.1
|
'@jest/types': 29.6.1
|
||||||
'@types/node': 20.19.10
|
'@types/node': 20.19.11
|
||||||
ansi-escapes: 4.3.2
|
ansi-escapes: 4.3.2
|
||||||
chalk: 4.1.2
|
chalk: 4.1.2
|
||||||
emittery: 0.13.1
|
emittery: 0.13.1
|
||||||
@@ -31430,32 +31267,6 @@ snapshots:
|
|||||||
|
|
||||||
rndm@1.2.0: {}
|
rndm@1.2.0: {}
|
||||||
|
|
||||||
rollup@4.46.2:
|
|
||||||
dependencies:
|
|
||||||
'@types/estree': 1.0.8
|
|
||||||
optionalDependencies:
|
|
||||||
'@rollup/rollup-android-arm-eabi': 4.46.2
|
|
||||||
'@rollup/rollup-android-arm64': 4.46.2
|
|
||||||
'@rollup/rollup-darwin-arm64': 4.46.2
|
|
||||||
'@rollup/rollup-darwin-x64': 4.46.2
|
|
||||||
'@rollup/rollup-freebsd-arm64': 4.46.2
|
|
||||||
'@rollup/rollup-freebsd-x64': 4.46.2
|
|
||||||
'@rollup/rollup-linux-arm-gnueabihf': 4.46.2
|
|
||||||
'@rollup/rollup-linux-arm-musleabihf': 4.46.2
|
|
||||||
'@rollup/rollup-linux-arm64-gnu': 4.46.2
|
|
||||||
'@rollup/rollup-linux-arm64-musl': 4.46.2
|
|
||||||
'@rollup/rollup-linux-loongarch64-gnu': 4.46.2
|
|
||||||
'@rollup/rollup-linux-ppc64-gnu': 4.46.2
|
|
||||||
'@rollup/rollup-linux-riscv64-gnu': 4.46.2
|
|
||||||
'@rollup/rollup-linux-riscv64-musl': 4.46.2
|
|
||||||
'@rollup/rollup-linux-s390x-gnu': 4.46.2
|
|
||||||
'@rollup/rollup-linux-x64-gnu': 4.46.2
|
|
||||||
'@rollup/rollup-linux-x64-musl': 4.46.2
|
|
||||||
'@rollup/rollup-win32-arm64-msvc': 4.46.2
|
|
||||||
'@rollup/rollup-win32-ia32-msvc': 4.46.2
|
|
||||||
'@rollup/rollup-win32-x64-msvc': 4.46.2
|
|
||||||
fsevents: 2.3.3
|
|
||||||
|
|
||||||
rollup@4.49.0:
|
rollup@4.49.0:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@types/estree': 1.0.8
|
'@types/estree': 1.0.8
|
||||||
@@ -32923,7 +32734,7 @@ snapshots:
|
|||||||
picocolors: 1.1.1
|
picocolors: 1.1.1
|
||||||
postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.6)(tsx@4.19.3)
|
postcss-load-config: 6.0.1(jiti@1.21.7)(postcss@8.5.6)(tsx@4.19.3)
|
||||||
resolve-from: 5.0.0
|
resolve-from: 5.0.0
|
||||||
rollup: 4.46.2
|
rollup: 4.49.0
|
||||||
source-map: 0.8.0-beta.0
|
source-map: 0.8.0-beta.0
|
||||||
sucrase: 3.35.0
|
sucrase: 3.35.0
|
||||||
tinyexec: 0.3.2
|
tinyexec: 0.3.2
|
||||||
@@ -33424,10 +33235,10 @@ snapshots:
|
|||||||
vite@6.3.5(@types/node@20.19.11)(jiti@1.21.7)(sass@1.89.2)(terser@5.16.1)(tsx@4.19.3):
|
vite@6.3.5(@types/node@20.19.11)(jiti@1.21.7)(sass@1.89.2)(terser@5.16.1)(tsx@4.19.3):
|
||||||
dependencies:
|
dependencies:
|
||||||
esbuild: 0.25.9
|
esbuild: 0.25.9
|
||||||
fdir: 6.4.6(picomatch@4.0.3)
|
fdir: 6.5.0(picomatch@4.0.3)
|
||||||
picomatch: 4.0.3
|
picomatch: 4.0.3
|
||||||
postcss: 8.5.6
|
postcss: 8.5.6
|
||||||
rollup: 4.46.2
|
rollup: 4.49.0
|
||||||
tinyglobby: 0.2.14
|
tinyglobby: 0.2.14
|
||||||
optionalDependencies:
|
optionalDependencies:
|
||||||
'@types/node': 20.19.11
|
'@types/node': 20.19.11
|
||||||
|
|||||||
Reference in New Issue
Block a user