@alpic80/rivet-core 1.24.0-aidon.5 → 1.24.2-aidon.10

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/README.md +9 -6
  2. package/dist/cjs/bundle.cjs +1534 -278
  3. package/dist/cjs/bundle.cjs.map +4 -4
  4. package/dist/esm/api/createProcessor.js +2 -0
  5. package/dist/esm/api/streaming.js +48 -2
  6. package/dist/esm/exports.js +1 -0
  7. package/dist/esm/integrations/CodeRunner.js +10 -2
  8. package/dist/esm/integrations/mcp/MCPBase.js +100 -0
  9. package/dist/esm/integrations/mcp/MCPProvider.js +23 -0
  10. package/dist/esm/integrations/mcp/MCPUtils.js +33 -0
  11. package/dist/esm/model/GraphProcessor.js +7 -1
  12. package/dist/esm/model/NodeRegistration.js +0 -1
  13. package/dist/esm/model/Nodes.js +9 -0
  14. package/dist/esm/model/nodes/ChatNodeBase.js +1 -1
  15. package/dist/esm/model/nodes/CodeNode.js +1 -1
  16. package/dist/esm/model/nodes/GetAllDatasetsNode.js +1 -1
  17. package/dist/esm/model/nodes/GraphInputNode.js +2 -0
  18. package/dist/esm/model/nodes/HttpCallNode.js +2 -2
  19. package/dist/esm/model/nodes/MCPDiscoveryNode.js +239 -0
  20. package/dist/esm/model/nodes/MCPGetPromptNode.js +262 -0
  21. package/dist/esm/model/nodes/MCPToolCallNode.js +290 -0
  22. package/dist/esm/model/nodes/ObjectNode.js +42 -21
  23. package/dist/esm/model/nodes/PromptNode.js +1 -1
  24. package/dist/esm/model/nodes/SubGraphNode.js +1 -0
  25. package/dist/esm/model/nodes/TextNode.js +13 -2
  26. package/dist/esm/plugins/aidon/nodes/ChatAidonNode.js +7 -5
  27. package/dist/esm/plugins/aidon/plugin.js +15 -0
  28. package/dist/esm/plugins/anthropic/anthropic.js +22 -3
  29. package/dist/esm/plugins/anthropic/nodes/ChatAnthropicNode.js +33 -3
  30. package/dist/esm/plugins/google/google.js +29 -14
  31. package/dist/esm/plugins/google/nodes/ChatGoogleNode.js +70 -5
  32. package/dist/esm/plugins/huggingface/nodes/ChatHuggingFace.js +4 -2
  33. package/dist/esm/plugins/huggingface/nodes/TextToImageHuggingFace.js +5 -3
  34. package/dist/esm/utils/interpolation.js +155 -17
  35. package/dist/esm/utils/openai.js +24 -0
  36. package/dist/types/api/createProcessor.d.ts +3 -2
  37. package/dist/types/api/streaming.d.ts +7 -1
  38. package/dist/types/exports.d.ts +1 -0
  39. package/dist/types/integrations/CodeRunner.d.ts +4 -3
  40. package/dist/types/integrations/mcp/MCPBase.d.ts +20 -0
  41. package/dist/types/integrations/mcp/MCPProvider.d.ts +153 -0
  42. package/dist/types/integrations/mcp/MCPUtils.d.ts +9 -0
  43. package/dist/types/model/GraphProcessor.d.ts +5 -1
  44. package/dist/types/model/Nodes.d.ts +13 -2
  45. package/dist/types/model/ProcessContext.d.ts +5 -1
  46. package/dist/types/model/Project.d.ts +2 -0
  47. package/dist/types/model/nodes/GetAllDatasetsNode.d.ts +2 -2
  48. package/dist/types/model/nodes/MCPDiscoveryNode.d.ts +9 -0
  49. package/dist/types/model/nodes/MCPGetPromptNode.d.ts +23 -0
  50. package/dist/types/model/nodes/MCPToolCallNode.d.ts +26 -0
  51. package/dist/types/model/nodes/ObjectNode.d.ts +3 -2
  52. package/dist/types/model/nodes/TextNode.d.ts +2 -1
  53. package/dist/types/plugins/anthropic/anthropic.d.ts +21 -3
  54. package/dist/types/plugins/anthropic/nodes/ChatAnthropicNode.d.ts +5 -0
  55. package/dist/types/plugins/google/google.d.ts +12 -2
  56. package/dist/types/plugins/google/nodes/ChatGoogleNode.d.ts +7 -0
  57. package/dist/types/utils/interpolation.d.ts +6 -1
  58. package/dist/types/utils/openai.d.ts +24 -0
  59. package/package.json +7 -7
@@ -0,0 +1,239 @@
1
+ import { nanoid } from 'nanoid';
2
+ import { NodeImpl } from '../NodeImpl.js';
3
+ import {} from '../../index.js';
4
+ import { MCPError, MCPErrorType } from '../../integrations/mcp/MCPProvider.js';
5
+ import { coerceType, dedent, getInputOrData } from '../../utils/index.js';
6
+ import { nodeDefinition } from '../NodeDefinition.js';
7
+ import { getServerHelperMessage, getServerOptions, loadMCPConfiguration } from '../../integrations/mcp/MCPUtils.js';
8
+ import { getMCPBaseInputs } from '../../integrations/mcp/MCPBase.js';
9
+ class MCPDiscoveryNodeImpl extends NodeImpl {
10
+ static create() {
11
+ const chartNode = {
12
+ type: 'mcpDiscovery',
13
+ title: 'MCP Discovery',
14
+ id: nanoid(),
15
+ visualData: {
16
+ x: 0,
17
+ y: 0,
18
+ width: 250,
19
+ },
20
+ data: {
21
+ name: 'mcp-client',
22
+ version: '1.0.0',
23
+ transportType: 'stdio',
24
+ serverUrl: 'http://localhost:8080/mcp',
25
+ headers: '',
26
+ serverId: '',
27
+ useNameInput: false,
28
+ useVersionInput: false,
29
+ useToolsOutput: true,
30
+ usePromptsOutput: true,
31
+ },
32
+ };
33
+ return chartNode;
34
+ }
35
+ getInputDefinitions() {
36
+ const inputs = getMCPBaseInputs(this.data);
37
+ return inputs;
38
+ }
39
+ getOutputDefinitions() {
40
+ const outputDefinitions = [];
41
+ if (this.data.useToolsOutput) {
42
+ outputDefinitions.push({
43
+ id: 'tools',
44
+ title: 'Tools',
45
+ dataType: 'object[]',
46
+ description: 'Tools returned from the MCP server',
47
+ });
48
+ }
49
+ if (this.data.usePromptsOutput) {
50
+ outputDefinitions.push({
51
+ id: 'prompts',
52
+ title: 'Prompts',
53
+ dataType: 'object[]',
54
+ description: 'Prompts returned from the MCP server',
55
+ });
56
+ }
57
+ return outputDefinitions;
58
+ }
59
+ async getEditors(context) {
60
+ const editors = [
61
+ {
62
+ type: 'toggle',
63
+ label: 'Output Tools',
64
+ dataKey: 'useToolsOutput',
65
+ helperMessage: 'Toggle on if you want to get a Tools output',
66
+ },
67
+ {
68
+ type: 'toggle',
69
+ label: 'Output Prompts',
70
+ dataKey: 'usePromptsOutput',
71
+ helperMessage: 'Toggle on if you want to get a Prompts output',
72
+ },
73
+ {
74
+ type: 'string',
75
+ label: 'Name',
76
+ dataKey: 'name',
77
+ useInputToggleDataKey: 'useNameInput',
78
+ helperMessage: 'The name for the MCP Client',
79
+ },
80
+ {
81
+ type: 'string',
82
+ label: 'Version',
83
+ dataKey: 'version',
84
+ useInputToggleDataKey: 'useVersionInput',
85
+ helperMessage: 'A version for the MCP Client',
86
+ },
87
+ {
88
+ type: 'dropdown',
89
+ label: 'Transport Type',
90
+ dataKey: 'transportType',
91
+ options: [
92
+ { label: 'HTTP', value: 'http' },
93
+ { label: 'STDIO', value: 'stdio' },
94
+ ],
95
+ },
96
+ ];
97
+ if (this.data.transportType === 'http') {
98
+ editors.push({
99
+ type: 'string',
100
+ label: 'Server URL',
101
+ dataKey: 'serverUrl',
102
+ useInputToggleDataKey: 'useServerUrlInput',
103
+ helperMessage: 'The base URL endpoint for the MCP server with `/mcp`',
104
+ }, {
105
+ type: 'code',
106
+ label: 'Headers',
107
+ dataKey: 'headers',
108
+ useInputToggleDataKey: 'useHeadersInput',
109
+ language: 'json',
110
+ });
111
+ }
112
+ else if (this.data.transportType === 'stdio') {
113
+ const serverOptions = await getServerOptions(context);
114
+ editors.push({
115
+ type: 'dropdown',
116
+ label: 'Server ID',
117
+ dataKey: 'serverId',
118
+ helperMessage: getServerHelperMessage(context, serverOptions.length),
119
+ options: serverOptions,
120
+ });
121
+ }
122
+ return editors;
123
+ }
124
+ getBody(context) {
125
+ let base;
126
+ let headers = '';
127
+ if (this.data.transportType === 'http') {
128
+ base = this.data.useServerUrlInput ? '(Using Server URL Input)' : this.data.serverUrl;
129
+ headers = this.data.useHeadersInput
130
+ ? '\nHeaders: (Using Input)'
131
+ : this.data.headers?.trim()
132
+ ? `\nHeaders: ${this.data.headers}`
133
+ : '';
134
+ }
135
+ else {
136
+ base = `Server ID: ${this.data.serverId || '(None)'}`;
137
+ }
138
+ const namePart = `Name: ${this.data.name}`;
139
+ const versionPart = `Version: ${this.data.version}`;
140
+ const parts = [namePart, versionPart, base, headers];
141
+ if (context.executor !== 'nodejs') {
142
+ parts.push('(Requires Node Executor)');
143
+ }
144
+ return parts.join('\n');
145
+ }
146
+ static getUIData() {
147
+ return {
148
+ infoBoxBody: dedent `
149
+ Connects to an MCP (Model Context Protocol) server to discover capabilities like tools and prompts.
150
+ `,
151
+ infoBoxTitle: 'MCP Discovery Node',
152
+ contextMenuTitle: 'MCP Discovery',
153
+ group: ['MCP'],
154
+ };
155
+ }
156
+ async process(inputs, context) {
157
+ const name = getInputOrData(this.data, inputs, 'name', 'string');
158
+ const version = getInputOrData(this.data, inputs, 'version', 'string');
159
+ const transportType = getInputOrData(this.data, inputs, 'transportType', 'string');
160
+ let tools = [];
161
+ let prompts = [];
162
+ try {
163
+ if (!context.mcpProvider) {
164
+ throw new Error('MCP Provider not found');
165
+ }
166
+ if (transportType === 'http') {
167
+ const serverUrl = getInputOrData(this.data, inputs, 'serverUrl', 'string');
168
+ if (!serverUrl || serverUrl === '') {
169
+ throw new MCPError(MCPErrorType.SERVER_NOT_FOUND, 'No server URL was provided');
170
+ }
171
+ if (!serverUrl.includes('/mcp')) {
172
+ throw new MCPError(MCPErrorType.SERVER_COMMUNICATION_FAILED, 'Include /mcp in your server URL. For example: http://localhost:8080/mcp');
173
+ }
174
+ let headers;
175
+ if (this.data.useHeadersInput) {
176
+ const headersInput = inputs['headers'];
177
+ if (headersInput?.type === 'string') {
178
+ headers = JSON.parse(headersInput.value);
179
+ }
180
+ else if (headersInput?.type === 'object') {
181
+ headers = headersInput.value;
182
+ }
183
+ else {
184
+ headers = coerceType(headersInput, 'object');
185
+ }
186
+ }
187
+ else if (this.data.headers?.trim()) {
188
+ headers = JSON.parse(this.data.headers);
189
+ }
190
+ tools = await context.mcpProvider.getHTTPTools({ name, version }, serverUrl, headers);
191
+ prompts = await context.mcpProvider.getHTTPrompts({ name, version }, serverUrl, headers);
192
+ }
193
+ else if (transportType === 'stdio') {
194
+ const serverId = this.data.serverId ?? '';
195
+ const mcpConfig = await loadMCPConfiguration(context);
196
+ if (!mcpConfig.mcpServers[serverId]) {
197
+ throw new MCPError(MCPErrorType.SERVER_NOT_FOUND, `Server ${serverId} not found in MCP config`);
198
+ }
199
+ const serverConfig = {
200
+ config: mcpConfig.mcpServers[serverId],
201
+ serverId,
202
+ };
203
+ tools = await context.mcpProvider.getStdioTools({ name, version }, serverConfig);
204
+ prompts = await context.mcpProvider.getStdioPrompts({ name, version }, serverConfig);
205
+ }
206
+ const output = {};
207
+ const gptFunctions = tools.map((tool) => ({
208
+ name: tool.name,
209
+ description: tool.description ?? '',
210
+ parameters: tool.inputSchema,
211
+ strict: false,
212
+ }));
213
+ if (this.data.useToolsOutput) {
214
+ output['tools'] = {
215
+ type: 'gpt-function[]',
216
+ value: gptFunctions,
217
+ };
218
+ }
219
+ if (this.data.usePromptsOutput) {
220
+ output['prompts'] = {
221
+ type: 'object[]',
222
+ value: prompts.map((prompt) => ({
223
+ name: prompt.name,
224
+ description: prompt.description,
225
+ arguments: prompt.arugments,
226
+ })),
227
+ };
228
+ }
229
+ return output;
230
+ }
231
+ catch (err) {
232
+ if (context.executor === 'browser') {
233
+ throw new Error('Failed to create Client without Node Executor');
234
+ }
235
+ throw err;
236
+ }
237
+ }
238
+ }
239
+ export const mcpDiscoveryNode = nodeDefinition(MCPDiscoveryNodeImpl, 'MCP Discovery');
@@ -0,0 +1,262 @@
1
+ import {} from '../NodeBase.js';
2
+ import { nanoid } from 'nanoid/non-secure';
3
+ import { NodeImpl } from '../NodeImpl.js';
4
+ import { nodeDefinition } from '../NodeDefinition.js';
5
+ import {} from '../GraphProcessor.js';
6
+ import { coerceType } from '../../index.js';
7
+ import { MCPError, MCPErrorType } from '../../integrations/mcp/MCPProvider.js';
8
+ import { coerceTypeOptional } from '../../utils/coerceType.js';
9
+ import { dedent, getInputOrData } from '../../utils/index.js';
10
+ import { getError } from '../../utils/errors.js';
11
+ import { getMCPBaseInputs } from '../../integrations/mcp/MCPBase.js';
12
+ import { getServerHelperMessage, getServerOptions, loadMCPConfiguration } from '../../integrations/mcp/MCPUtils.js';
13
+ import { keys } from '../../utils/typeSafety.js';
14
+ import { interpolate } from '../../utils/interpolation.js';
15
+ export class MCPGetPromptNodeImpl extends NodeImpl {
16
+ static create() {
17
+ const chartNode = {
18
+ type: 'mcpGetPrompt',
19
+ title: 'MCP Get Prompt',
20
+ id: nanoid(),
21
+ visualData: {
22
+ x: 0,
23
+ y: 0,
24
+ width: 250,
25
+ },
26
+ data: {
27
+ name: 'mcp-get-prompt-client',
28
+ version: '1.0.0',
29
+ transportType: 'stdio',
30
+ serverUrl: 'http://localhost:8080/mcp',
31
+ headers: '',
32
+ serverId: '',
33
+ promptName: '',
34
+ promptArguments: dedent `
35
+ {
36
+ "key": "value"
37
+ }`,
38
+ useNameInput: false,
39
+ useVersionInput: false,
40
+ usePromptNameInput: false,
41
+ usePromptArgumentsInput: false,
42
+ },
43
+ };
44
+ return chartNode;
45
+ }
46
+ getInputDefinitions() {
47
+ const inputs = getMCPBaseInputs(this.data);
48
+ if (this.data.usePromptNameInput) {
49
+ inputs.push({
50
+ dataType: 'string',
51
+ id: 'promptName',
52
+ title: 'Prompt Name',
53
+ });
54
+ }
55
+ if (this.data.usePromptArgumentsInput) {
56
+ inputs.push({
57
+ dataType: 'object',
58
+ id: 'promptArguments',
59
+ title: 'Prompt Arguments',
60
+ });
61
+ }
62
+ return inputs;
63
+ }
64
+ getOutputDefinitions() {
65
+ const outputDefinitions = [];
66
+ outputDefinitions.push({
67
+ id: 'prompt',
68
+ title: 'Prompt',
69
+ dataType: 'object',
70
+ description: 'Prompt response result',
71
+ });
72
+ return outputDefinitions;
73
+ }
74
+ async getEditors(context) {
75
+ const editors = [
76
+ {
77
+ type: 'string',
78
+ label: 'Name',
79
+ dataKey: 'name',
80
+ useInputToggleDataKey: 'useNameInput',
81
+ helperMessage: 'The name for the MCP Client',
82
+ },
83
+ {
84
+ type: 'string',
85
+ label: 'Version',
86
+ dataKey: 'version',
87
+ useInputToggleDataKey: 'useVersionInput',
88
+ helperMessage: 'A version for the MCP Client',
89
+ },
90
+ {
91
+ type: 'dropdown',
92
+ label: 'Transport Type',
93
+ dataKey: 'transportType',
94
+ options: [
95
+ { label: 'HTTP', value: 'http' },
96
+ { label: 'STDIO', value: 'stdio' },
97
+ ],
98
+ },
99
+ {
100
+ type: 'string',
101
+ label: 'Prompt Name',
102
+ dataKey: 'promptName',
103
+ useInputToggleDataKey: 'usePromptNameInput',
104
+ helperMessage: 'The name for the MCP prompt',
105
+ },
106
+ {
107
+ type: 'code',
108
+ label: 'Prompt Arguments',
109
+ dataKey: 'promptArguments',
110
+ useInputToggleDataKey: 'usePromptArgumentsInput',
111
+ language: 'json',
112
+ helperMessage: 'Arguments to provide the prompt',
113
+ },
114
+ ];
115
+ if (this.data.transportType === 'http') {
116
+ editors.push({
117
+ type: 'string',
118
+ label: 'Server URL',
119
+ dataKey: 'serverUrl',
120
+ useInputToggleDataKey: 'useServerUrlInput',
121
+ helperMessage: 'The base URL endpoint for the MCP server with `/mcp`',
122
+ }, {
123
+ type: 'code',
124
+ label: 'Headers',
125
+ dataKey: 'headers',
126
+ useInputToggleDataKey: 'useHeadersInput',
127
+ language: 'json',
128
+ });
129
+ }
130
+ else if (this.data.transportType === 'stdio') {
131
+ const serverOptions = await getServerOptions(context);
132
+ editors.push({
133
+ type: 'dropdown',
134
+ label: 'Server ID',
135
+ dataKey: 'serverId',
136
+ helperMessage: getServerHelperMessage(context, serverOptions.length),
137
+ options: serverOptions,
138
+ });
139
+ }
140
+ return editors;
141
+ }
142
+ getBody(context) {
143
+ let base;
144
+ let headers = '';
145
+ if (this.data.transportType === 'http') {
146
+ base = this.data.useServerUrlInput ? '(Using Server URL Input)' : this.data.serverUrl;
147
+ headers = this.data.useHeadersInput
148
+ ? '\nHeaders: (Using Input)'
149
+ : this.data.headers?.trim()
150
+ ? `\nHeaders: ${this.data.headers}`
151
+ : '';
152
+ }
153
+ else {
154
+ base = `Server ID: ${this.data.serverId || '(None)'}`;
155
+ }
156
+ const namePart = `Name: ${this.data.name}`;
157
+ const versionPart = `Version: ${this.data.version}`;
158
+ const parts = [namePart, versionPart, base, headers];
159
+ if (context.executor !== 'nodejs') {
160
+ parts.push('(Requires Node Executor)');
161
+ }
162
+ return parts.join('\n');
163
+ }
164
+ static getUIData() {
165
+ return {
166
+ infoBoxBody: dedent `
167
+ Connects to an MCP (Model Context Protocol) server and gets a prompt response.
168
+ `,
169
+ infoBoxTitle: 'MCP Get Prompt Node',
170
+ contextMenuTitle: 'MCP Get Prompt',
171
+ group: ['MCP'],
172
+ };
173
+ }
174
+ async process(inputs, context) {
175
+ const name = getInputOrData(this.data, inputs, 'name', 'string');
176
+ const version = getInputOrData(this.data, inputs, 'version', 'string');
177
+ const promptName = getInputOrData(this.data, inputs, 'promptName', 'string');
178
+ let promptArguments;
179
+ if (this.data.usePromptArgumentsInput) {
180
+ promptArguments = getInputOrData(this.data, inputs, 'promptArguments', 'object');
181
+ if (promptArguments == null) {
182
+ throw new MCPError(MCPErrorType.INVALID_SCHEMA, 'Cannot parse tool argument with input toggle on');
183
+ }
184
+ }
185
+ else {
186
+ const inputMap = keys(inputs)
187
+ .filter((key) => key.startsWith('input'))
188
+ .reduce((acc, key) => {
189
+ const stringValue = coerceTypeOptional(inputs[key], 'string') ?? '';
190
+ const interpolationKey = key.slice('input-'.length);
191
+ acc[interpolationKey] = stringValue;
192
+ return acc;
193
+ }, {});
194
+ const interpolated = interpolate(this.data.promptArguments ?? '', inputMap);
195
+ promptArguments = JSON.parse(interpolated);
196
+ }
197
+ const getPromptRequest = {
198
+ name: promptName,
199
+ arguments: promptArguments,
200
+ };
201
+ const transportType = getInputOrData(this.data, inputs, 'transportType', 'string');
202
+ let getPromptResponse = undefined;
203
+ try {
204
+ if (!context.mcpProvider) {
205
+ throw new Error('MCP Provider not found');
206
+ }
207
+ if (transportType === 'http') {
208
+ const serverUrl = getInputOrData(this.data, inputs, 'serverUrl', 'string');
209
+ if (!serverUrl || serverUrl === '') {
210
+ throw new MCPError(MCPErrorType.SERVER_NOT_FOUND, 'No server URL was provided');
211
+ }
212
+ if (!serverUrl.includes('/mcp')) {
213
+ throw new MCPError(MCPErrorType.SERVER_COMMUNICATION_FAILED, 'Include /mcp in your server URL. For example: http://localhost:8080/mcp');
214
+ }
215
+ let headers;
216
+ if (this.data.useHeadersInput) {
217
+ const headersInput = inputs['headers'];
218
+ if (headersInput?.type === 'string') {
219
+ headers = JSON.parse(headersInput.value);
220
+ }
221
+ else if (headersInput?.type === 'object') {
222
+ headers = headersInput.value;
223
+ }
224
+ else {
225
+ headers = coerceType(headersInput, 'object');
226
+ }
227
+ }
228
+ else if (this.data.headers?.trim()) {
229
+ headers = JSON.parse(this.data.headers);
230
+ }
231
+ getPromptResponse = await context.mcpProvider.getHTTPrompt({ name, version }, serverUrl, headers, getPromptRequest);
232
+ }
233
+ else if (transportType === 'stdio') {
234
+ const serverId = this.data.serverId ?? '';
235
+ const mcpConfig = await loadMCPConfiguration(context);
236
+ if (!mcpConfig.mcpServers[serverId]) {
237
+ throw new MCPError(MCPErrorType.SERVER_NOT_FOUND, `Server ${serverId} not found in MCP config`);
238
+ }
239
+ const serverConfig = {
240
+ config: mcpConfig.mcpServers[serverId],
241
+ serverId,
242
+ };
243
+ getPromptResponse = await context.mcpProvider.getStdioPrompt({ name, version }, serverConfig, getPromptRequest);
244
+ }
245
+ const output = {};
246
+ output['response'] = {
247
+ type: 'object',
248
+ value: getPromptResponse,
249
+ };
250
+ return output;
251
+ }
252
+ catch (err) {
253
+ const { message } = getError(err);
254
+ if (context.executor === 'browser') {
255
+ throw new Error('Failed to create Client without a node executor');
256
+ }
257
+ console.log(message);
258
+ throw err;
259
+ }
260
+ }
261
+ }
262
+ export const mcpGetPromptNode = nodeDefinition(MCPGetPromptNodeImpl, 'MCP Get Prompt');