@alpic80/rivet-core 1.19.1-aidon.3 → 1.24.0-aidon.1

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 (105) hide show
  1. package/README.md +4 -0
  2. package/dist/cjs/bundle.cjs +3993 -943
  3. package/dist/cjs/bundle.cjs.map +4 -4
  4. package/dist/esm/api/createProcessor.js +8 -17
  5. package/dist/esm/api/looseDataValue.js +16 -0
  6. package/dist/esm/exports.js +2 -0
  7. package/dist/esm/integrations/CodeRunner.js +36 -0
  8. package/dist/esm/integrations/GptTokenizerTokenizer.js +7 -4
  9. package/dist/esm/integrations/openai/OpenAIEmbeddingGenerator.js +1 -1
  10. package/dist/esm/model/DataValue.js +14 -2
  11. package/dist/esm/model/GraphProcessor.js +275 -104
  12. package/dist/esm/model/NodeBase.js +11 -1
  13. package/dist/esm/model/NodeImpl.js +8 -0
  14. package/dist/esm/model/Nodes.js +28 -4
  15. package/dist/esm/model/ProjectReferenceLoader.js +1 -0
  16. package/dist/esm/model/nodes/AssembleMessageNode.js +12 -2
  17. package/dist/esm/model/nodes/AssemblePromptNode.js +22 -0
  18. package/dist/esm/model/nodes/CallGraphNode.js +3 -4
  19. package/dist/esm/model/nodes/ChatLoopNode.js +150 -0
  20. package/dist/esm/model/nodes/ChatNode.js +7 -934
  21. package/dist/esm/model/nodes/ChatNodeBase.js +1275 -0
  22. package/dist/esm/model/nodes/ChunkNode.js +2 -2
  23. package/dist/esm/model/nodes/CodeNode.js +40 -4
  24. package/dist/esm/model/nodes/CronNode.js +248 -0
  25. package/dist/esm/model/nodes/DelegateFunctionCallNode.js +37 -12
  26. package/dist/esm/model/nodes/DestructureNode.js +1 -1
  27. package/dist/esm/model/nodes/DocumentNode.js +183 -0
  28. package/dist/esm/model/nodes/ExtractJsonNode.js +4 -4
  29. package/dist/esm/model/nodes/ExtractRegexNode.js +10 -11
  30. package/dist/esm/model/nodes/GetEmbeddingNode.js +1 -1
  31. package/dist/esm/model/nodes/HttpCallNode.js +3 -1
  32. package/dist/esm/model/nodes/IfNode.js +5 -0
  33. package/dist/esm/model/nodes/LoopUntilNode.js +214 -0
  34. package/dist/esm/model/nodes/PromptNode.js +29 -6
  35. package/dist/esm/model/nodes/ReadAllFilesNode.js +210 -0
  36. package/dist/esm/model/nodes/ReadDirectoryNode.js +31 -25
  37. package/dist/esm/model/nodes/ReferencedGraphAliasNode.js +199 -0
  38. package/dist/esm/model/nodes/TextNode.js +9 -4
  39. package/dist/esm/model/nodes/ToMarkdownTableNode.js +119 -0
  40. package/dist/esm/model/nodes/ToTreeNode.js +133 -0
  41. package/dist/esm/model/nodes/{GptFunctionNode.js → ToolNode.js} +10 -10
  42. package/dist/esm/model/nodes/UserInputNode.js +10 -12
  43. package/dist/esm/plugins/aidon/nodes/ChatAidonNode.js +2 -2
  44. package/dist/esm/plugins/anthropic/anthropic.js +29 -10
  45. package/dist/esm/plugins/anthropic/fetchEventSource.js +3 -2
  46. package/dist/esm/plugins/anthropic/nodes/ChatAnthropicNode.js +267 -147
  47. package/dist/esm/plugins/anthropic/plugin.js +9 -1
  48. package/dist/esm/plugins/gentrace/plugin.js +6 -6
  49. package/dist/esm/plugins/google/google.js +113 -5
  50. package/dist/esm/plugins/google/nodes/ChatGoogleNode.js +211 -54
  51. package/dist/esm/plugins/google/plugin.js +13 -6
  52. package/dist/esm/plugins/openai/nodes/RunThreadNode.js +2 -2
  53. package/dist/esm/recording/ExecutionRecorder.js +5 -1
  54. package/dist/esm/utils/chatMessageToOpenAIChatCompletionMessage.js +15 -2
  55. package/dist/esm/utils/coerceType.js +1 -1
  56. package/dist/esm/utils/fetchEventSource.js +1 -1
  57. package/dist/esm/utils/interpolation.js +108 -3
  58. package/dist/esm/utils/openai.js +106 -50
  59. package/dist/esm/utils/paths.js +80 -0
  60. package/dist/esm/utils/serialization/serialization_v4.js +5 -0
  61. package/dist/types/api/createProcessor.d.ts +11 -5
  62. package/dist/types/api/looseDataValue.d.ts +4 -0
  63. package/dist/types/api/streaming.d.ts +1 -1
  64. package/dist/types/exports.d.ts +2 -0
  65. package/dist/types/integrations/CodeRunner.d.ts +18 -0
  66. package/dist/types/model/DataValue.d.ts +29 -6
  67. package/dist/types/model/EditorDefinition.d.ts +6 -1
  68. package/dist/types/model/GraphProcessor.d.ts +14 -7
  69. package/dist/types/model/NodeBase.d.ts +4 -0
  70. package/dist/types/model/NodeImpl.d.ts +5 -4
  71. package/dist/types/model/Nodes.d.ts +12 -4
  72. package/dist/types/model/ProcessContext.d.ts +16 -1
  73. package/dist/types/model/Project.d.ts +19 -7
  74. package/dist/types/model/ProjectReferenceLoader.d.ts +5 -0
  75. package/dist/types/model/RivetPlugin.d.ts +6 -0
  76. package/dist/types/model/RivetUIContext.d.ts +5 -1
  77. package/dist/types/model/Settings.d.ts +1 -0
  78. package/dist/types/model/nodes/AssemblePromptNode.d.ts +4 -1
  79. package/dist/types/model/nodes/ChatLoopNode.d.ts +21 -0
  80. package/dist/types/model/nodes/ChatNode.d.ts +2 -62
  81. package/dist/types/model/nodes/ChatNodeBase.d.ts +85 -0
  82. package/dist/types/model/nodes/CodeNode.d.ts +8 -2
  83. package/dist/types/model/nodes/CronNode.d.ts +34 -0
  84. package/dist/types/model/nodes/DelegateFunctionCallNode.d.ts +1 -0
  85. package/dist/types/model/nodes/DocumentNode.d.ts +28 -0
  86. package/dist/types/model/nodes/LoopUntilNode.d.ts +32 -0
  87. package/dist/types/model/nodes/PromptNode.d.ts +2 -0
  88. package/dist/types/model/nodes/ReadAllFilesNode.d.ts +30 -0
  89. package/dist/types/model/nodes/ReadDirectoryNode.d.ts +1 -1
  90. package/dist/types/model/nodes/ReferencedGraphAliasNode.d.ts +31 -0
  91. package/dist/types/model/nodes/ToMarkdownTableNode.d.ts +19 -0
  92. package/dist/types/model/nodes/ToTreeNode.d.ts +21 -0
  93. package/dist/types/model/nodes/UserInputNode.d.ts +2 -3
  94. package/dist/types/plugins/anthropic/anthropic.d.ts +94 -13
  95. package/dist/types/plugins/anthropic/nodes/ChatAnthropicNode.d.ts +7 -2
  96. package/dist/types/plugins/google/google.d.ts +93 -18
  97. package/dist/types/plugins/google/nodes/ChatGoogleNode.d.ts +3 -2
  98. package/dist/types/recording/RecordedEvents.d.ts +2 -0
  99. package/dist/types/utils/base64.d.ts +1 -1
  100. package/dist/types/utils/chatMessageToOpenAIChatCompletionMessage.d.ts +3 -1
  101. package/dist/types/utils/interpolation.d.ts +3 -0
  102. package/dist/types/utils/openai.d.ts +127 -21
  103. package/dist/types/utils/paths.d.ts +8 -0
  104. package/package.json +15 -11
  105. /package/dist/types/model/nodes/{GptFunctionNode.d.ts → ToolNode.d.ts} +0 -0
@@ -1 +1,11 @@
1
- export {};
1
+ export const IF_PORT = {
2
+ id: `$if`,
3
+ title: 'if',
4
+ dataType: 'boolean',
5
+ coerced: true,
6
+ description: 'Only run the node if this condition is true',
7
+ defaultValue: 'false',
8
+ };
9
+ export function isBuiltInInputDefinition(input) {
10
+ return input.id === IF_PORT.id;
11
+ }
@@ -1,3 +1,4 @@
1
+ import { IF_PORT, } from './NodeBase.js';
1
2
  export class NodeImpl {
2
3
  chartNode;
3
4
  constructor(chartNode) {
@@ -18,6 +19,13 @@ export class NodeImpl {
18
19
  get data() {
19
20
  return this.chartNode.data;
20
21
  }
22
+ getInputDefinitionsIncludingBuiltIn(connections, nodes, project, referencedProjects) {
23
+ const ports = [...this.getInputDefinitions(connections, nodes, project, referencedProjects)];
24
+ if (this.chartNode.isConditional) {
25
+ ports.push(IF_PORT);
26
+ }
27
+ return ports;
28
+ }
21
29
  getEditors(_context) {
22
30
  return [];
23
31
  }
@@ -5,6 +5,7 @@ import { textNode } from './nodes/TextNode.js';
5
5
  export * from './nodes/TextNode.js';
6
6
  import { chatNode } from './nodes/ChatNode.js';
7
7
  export * from './nodes/ChatNode.js';
8
+ export * from './nodes/ChatNodeBase.js';
8
9
  import { promptNode } from './nodes/PromptNode.js';
9
10
  export * from './nodes/PromptNode.js';
10
11
  import { extractRegexNode } from './nodes/ExtractRegexNode.js';
@@ -61,8 +62,8 @@ import { getGlobalNode } from './nodes/GetGlobalNode.js';
61
62
  export * from './nodes/GetGlobalNode.js';
62
63
  import { waitForEventNode } from './nodes/WaitForEventNode.js';
63
64
  export * from './nodes/WaitForEventNode.js';
64
- import { gptFunctionNode } from './nodes/GptFunctionNode.js';
65
- export * from './nodes/GptFunctionNode.js';
65
+ import { gptFunctionNode } from './nodes/ToolNode.js';
66
+ export * from './nodes/ToolNode.js';
66
67
  import { toYamlNode } from './nodes/ToYamlNode.js';
67
68
  export * from './nodes/ToYamlNode.js';
68
69
  import { getEmbeddingNode } from './nodes/GetEmbeddingNode.js';
@@ -145,7 +146,22 @@ import { delegateFunctionCallNode } from './nodes/DelegateFunctionCallNode.js';
145
146
  export * from './nodes/DelegateFunctionCallNode.js';
146
147
  import { playAudioNode } from './nodes/PlayAudioNode.js';
147
148
  export * from './nodes/PlayAudioNode.js';
148
- export * from './nodes/CallGraphNode.js';
149
+ import { documentNode } from './nodes/DocumentNode.js';
150
+ export * from './nodes/DocumentNode.js';
151
+ import { chatLoopNode } from './nodes/ChatLoopNode.js';
152
+ export * from './nodes/ChatLoopNode.js';
153
+ import { readAllFilesNode } from './nodes/ReadAllFilesNode.js';
154
+ export * from './nodes/ReadAllFilesNode.js';
155
+ import { toMarkdownTableNode } from './nodes/ToMarkdownTableNode.js';
156
+ export * from './nodes/ToMarkdownTableNode.js';
157
+ import { cronNode } from './nodes/CronNode.js';
158
+ export * from './nodes/CronNode.js';
159
+ import { toTreeNode } from './nodes/ToTreeNode.js';
160
+ export * from './nodes/ToTreeNode.js';
161
+ import { loopUntilNode } from './nodes/LoopUntilNode.js';
162
+ export * from './nodes/LoopUntilNode.js';
163
+ import { referencedGraphAliasNode } from './nodes/ReferencedGraphAliasNode.js';
164
+ export * from './nodes/ReferencedGraphAliasNode.js';
149
165
  export const registerBuiltInNodes = (registry) => {
150
166
  return registry
151
167
  .register(toYamlNode)
@@ -220,7 +236,15 @@ export const registerBuiltInNodes = (registry) => {
220
236
  .register(graphReferenceNode)
221
237
  .register(callGraphNode)
222
238
  .register(delegateFunctionCallNode)
223
- .register(playAudioNode);
239
+ .register(playAudioNode)
240
+ .register(documentNode)
241
+ .register(chatLoopNode)
242
+ .register(readAllFilesNode)
243
+ .register(toMarkdownTableNode)
244
+ .register(cronNode)
245
+ .register(toTreeNode)
246
+ .register(loopUntilNode)
247
+ .register(referencedGraphAliasNode);
224
248
  };
225
249
  let globalRivetNodeRegistry = registerBuiltInNodes(new NodeRegistration());
226
250
  export { globalRivetNodeRegistry };
@@ -0,0 +1 @@
1
+ export {};
@@ -54,7 +54,7 @@ export class AssembleMessageNodeImpl extends NodeImpl {
54
54
  }
55
55
  for (let i = 1; i <= messageCount; i++) {
56
56
  inputs.push({
57
- dataType: ['string', 'image', 'string[]', 'image[]', 'object', 'object[]'],
57
+ dataType: ['string', 'image', 'string[]', 'image[]', 'object', 'object[]', 'document', 'document[]'],
58
58
  id: `part${i}`,
59
59
  title: `Part ${i}`,
60
60
  description: 'A part of the message to assemble.',
@@ -112,7 +112,7 @@ export class AssembleMessageNodeImpl extends NodeImpl {
112
112
  return {
113
113
  infoBoxBody: dedent `
114
114
  Assembles a single chat message from multiple parts. This is similar to a Prompt node, but works with multimodal
115
- models, as you can include both text and images in the message.
115
+ models, as you can include text, images, and documents in the message.
116
116
  `,
117
117
  infoBoxTitle: 'Assemble Message Node',
118
118
  contextMenuTitle: 'Assemble Message',
@@ -181,6 +181,16 @@ export class AssembleMessageNodeImpl extends NodeImpl {
181
181
  });
182
182
  }
183
183
  }
184
+ else if (message.type === 'document') {
185
+ outMessage.message.push({
186
+ type: 'document',
187
+ data: message.value.data,
188
+ mediaType: message.value.mediaType,
189
+ context: message.value.context,
190
+ title: message.value.title,
191
+ enableCitations: message.value.enableCitations,
192
+ });
193
+ }
184
194
  else {
185
195
  const coerced = coerceTypeOptional(message, 'string');
186
196
  if (coerced) {
@@ -7,6 +7,7 @@ import { coerceType } from '../../utils/coerceType.js';
7
7
  import { orderBy } from 'lodash-es';
8
8
  import { dedent } from 'ts-dedent';
9
9
  import { nodeDefinition } from '../NodeDefinition.js';
10
+ import { getInputOrData } from '../../utils/inputs.js';
10
11
  export class AssemblePromptNodeImpl extends NodeImpl {
11
12
  static create() {
12
13
  const chartNode = {
@@ -25,6 +26,14 @@ export class AssemblePromptNodeImpl extends NodeImpl {
25
26
  getInputDefinitions(connections) {
26
27
  const inputs = [];
27
28
  const messageCount = this.#getMessagePortCount(connections);
29
+ if (this.data.useIsLastMessageCacheBreakpointInput) {
30
+ inputs.push({
31
+ dataType: 'boolean',
32
+ id: 'isLastMessageCacheBreakpoint',
33
+ title: 'Is Last Message Cache Breakpoint',
34
+ description: 'Whether the last message in the prompt should be a cache breakpoint.',
35
+ });
36
+ }
28
37
  for (let i = 1; i <= messageCount; i++) {
29
38
  inputs.push({
30
39
  dataType: ['chat-message', 'chat-message[]'],
@@ -87,10 +96,20 @@ export class AssemblePromptNodeImpl extends NodeImpl {
87
96
  label: 'Compute Token Count',
88
97
  dataKey: 'computeTokenCount',
89
98
  },
99
+ {
100
+ type: 'toggle',
101
+ label: 'Is Last Message Cache Breakpoint',
102
+ dataKey: 'isLastMessageCacheBreakpoint',
103
+ helperMessage: 'For Anthropic, marks the last message as a cache breakpoint - this message and every message before it will be cached using Prompt Caching.',
104
+ },
90
105
  ];
91
106
  }
107
+ getBody(_context) {
108
+ return this.data.isLastMessageCacheBreakpoint ? 'Last message is cache breakpoint' : '';
109
+ }
92
110
  async process(inputs, context) {
93
111
  const output = {};
112
+ const isLastMessageCacheBreakpoint = getInputOrData(this.data, inputs, 'isLastMessageCacheBreakpoint', 'boolean');
94
113
  const outMessages = [];
95
114
  const inputMessages = orderBy(Object.entries(inputs).filter(([key]) => key.startsWith('message')), ([key]) => key, 'asc');
96
115
  for (const [, inputMessage] of inputMessages) {
@@ -110,6 +129,9 @@ export class AssemblePromptNodeImpl extends NodeImpl {
110
129
  }
111
130
  }
112
131
  }
132
+ if (isLastMessageCacheBreakpoint && outMessages.length > 1) {
133
+ outMessages.at(-1).isCacheBreakpoint = true;
134
+ }
113
135
  output['prompt'] = {
114
136
  type: 'chat-message[]',
115
137
  value: outMessages,
@@ -2,12 +2,11 @@ import {} from '../NodeBase.js';
2
2
  import { NodeImpl } from '../NodeImpl.js';
3
3
  import { nodeDefinition } from '../NodeDefinition.js';
4
4
  import {} from '../GraphProcessor.js';
5
- import {} from '../NodeGraph.js';
6
5
  import { nanoid } from 'nanoid/non-secure';
7
6
  import {} from '../ProcessContext.js';
8
7
  import { dedent } from 'ts-dedent';
9
- import { coerceType, coerceTypeOptional } from '../../utils/coerceType.js';
10
- import { looseDataValuesToDataValues } from '../../index.js';
8
+ import { coerceTypeOptional } from '../../utils/coerceType.js';
9
+ import { looseDataValuesToDataValues } from '../../api/looseDataValue.js';
11
10
  import { getError } from '../../utils/errors.js';
12
11
  export class CallGraphNodeImpl extends NodeImpl {
13
12
  static create() {
@@ -93,7 +92,7 @@ export class CallGraphNodeImpl extends NodeImpl {
93
92
  };
94
93
  }
95
94
  const subGraphProcessor = context.createSubProcessor(graphRef.graphId, { signal: context.signal });
96
- let outputs = {};
95
+ const outputs = {};
97
96
  try {
98
97
  const startTime = Date.now();
99
98
  const inputData = looseDataValuesToDataValues(graphInputs);
@@ -0,0 +1,150 @@
1
+ import {} from '../NodeBase.js';
2
+ import { nanoid } from 'nanoid/non-secure';
3
+ import { NodeImpl } from '../NodeImpl.js';
4
+ import {} from '../ProcessContext.js';
5
+ import {} from '../../index.js';
6
+ import { dedent } from 'ts-dedent';
7
+ import { nodeDefinition } from '../NodeDefinition.js';
8
+ import { ChatNodeBase } from './ChatNodeBase.js';
9
+ import { coerceType } from '../../utils/coerceType.js';
10
+ export class ChatLoopNodeImpl extends NodeImpl {
11
+ static create() {
12
+ const chartNode = {
13
+ type: 'chatLoop',
14
+ title: 'Chat Loop',
15
+ id: nanoid(),
16
+ visualData: {
17
+ x: 0,
18
+ y: 0,
19
+ width: 250,
20
+ },
21
+ data: {
22
+ ...ChatNodeBase.defaultData(),
23
+ userPrompt: 'Your response:',
24
+ renderingFormat: 'markdown',
25
+ },
26
+ };
27
+ return chartNode;
28
+ }
29
+ getInputDefinitions() {
30
+ return ChatNodeBase.getInputDefinitions(this.data);
31
+ }
32
+ getOutputDefinitions() {
33
+ return [
34
+ {
35
+ dataType: 'string[]',
36
+ id: 'conversation',
37
+ title: 'Full Conversation',
38
+ },
39
+ {
40
+ dataType: 'string',
41
+ id: 'lastMessage',
42
+ title: 'Last Message',
43
+ },
44
+ ];
45
+ }
46
+ static getUIData() {
47
+ return {
48
+ infoBoxBody: dedent `
49
+ Creates an interactive chat loop with an AI model. The node will:
50
+ 1. Send the initial prompt to the AI
51
+ 2. Show the AI's response and prompt for user input
52
+ 3. Send the user's input back to the AI
53
+ 4. Repeat steps 2-3 until the user ends the conversation
54
+
55
+ The conversation history is maintained and sent with each new message.
56
+ `,
57
+ contextMenuTitle: 'Chat Loop',
58
+ infoBoxTitle: 'Chat Loop Node',
59
+ group: ['Convenience'],
60
+ };
61
+ }
62
+ getEditors() {
63
+ return [
64
+ ...ChatNodeBase.getEditors(),
65
+ {
66
+ type: 'code',
67
+ label: 'User Prompt',
68
+ dataKey: 'userPrompt',
69
+ language: 'plain-text',
70
+ },
71
+ {
72
+ type: 'group',
73
+ label: 'Rendering',
74
+ editors: [
75
+ {
76
+ type: 'dropdown',
77
+ dataKey: 'renderingFormat',
78
+ label: 'Format',
79
+ options: [
80
+ { label: 'Text', value: 'text' },
81
+ { label: 'Markdown', value: 'markdown' },
82
+ ],
83
+ defaultValue: 'markdown',
84
+ },
85
+ ],
86
+ },
87
+ ];
88
+ }
89
+ getBody() {
90
+ return ChatNodeBase.getBody(this.data);
91
+ }
92
+ async process(inputs, context) {
93
+ const conversation = [];
94
+ let continueChat = true;
95
+ conversation.push(...coerceType(inputs['prompt'], 'chat-message[]'));
96
+ // Initial chat call
97
+ const initialResponse = await ChatNodeBase.process(this.data, this.chartNode, inputs, context);
98
+ const firstMessage = coerceType(initialResponse['response'], 'string');
99
+ conversation.push({
100
+ type: 'assistant',
101
+ message: firstMessage,
102
+ function_calls: undefined,
103
+ function_call: undefined,
104
+ });
105
+ let messageToUser = firstMessage;
106
+ while (continueChat) {
107
+ // Get user input
108
+ const userResponse = await context.requestUserInput([messageToUser], this.data.renderingFormat ?? 'text');
109
+ // Check if user wants to end conversation
110
+ if (!userResponse || userResponse.value.length === 0 || userResponse.value[0]?.length === 0) {
111
+ continueChat = false;
112
+ break;
113
+ }
114
+ // Add user message to conversation
115
+ conversation.push({
116
+ type: 'user',
117
+ message: userResponse.value[0],
118
+ });
119
+ // Prepare next AI message
120
+ const chatInputs = {
121
+ ...inputs,
122
+ prompt: {
123
+ type: 'chat-message[]',
124
+ value: conversation,
125
+ },
126
+ };
127
+ // Get AI response
128
+ const aiResponse = await ChatNodeBase.process(this.data, this.chartNode, chatInputs, context);
129
+ const aiMessage = coerceType(aiResponse['response'], 'string');
130
+ conversation.push({
131
+ type: 'assistant',
132
+ message: aiMessage,
133
+ function_calls: undefined,
134
+ function_call: undefined,
135
+ });
136
+ messageToUser = aiMessage;
137
+ }
138
+ return {
139
+ ['conversation']: {
140
+ type: 'chat-message[]',
141
+ value: conversation,
142
+ },
143
+ ['lastMessage']: {
144
+ type: 'chat-message',
145
+ value: conversation.at(-1),
146
+ },
147
+ };
148
+ }
149
+ }
150
+ export const chatLoopNode = nodeDefinition(ChatLoopNodeImpl, 'Chat Loop');