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

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 (129) hide show
  1. package/README.md +4 -0
  2. package/dist/cjs/bundle.cjs +4512 -1240
  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/DatasetProvider.js +1 -1
  9. package/dist/esm/integrations/GptTokenizerTokenizer.js +7 -4
  10. package/dist/esm/integrations/openai/OpenAIEmbeddingGenerator.js +1 -1
  11. package/dist/esm/model/DataValue.js +14 -2
  12. package/dist/esm/model/GraphProcessor.js +276 -107
  13. package/dist/esm/model/NodeBase.js +11 -1
  14. package/dist/esm/model/NodeImpl.js +8 -0
  15. package/dist/esm/model/Nodes.js +31 -4
  16. package/dist/esm/model/ProjectReferenceLoader.js +1 -0
  17. package/dist/esm/model/nodes/AssembleMessageNode.js +12 -2
  18. package/dist/esm/model/nodes/AssemblePromptNode.js +22 -0
  19. package/dist/esm/model/nodes/CallGraphNode.js +3 -4
  20. package/dist/esm/model/nodes/ChatLoopNode.js +150 -0
  21. package/dist/esm/model/nodes/ChatNode.js +7 -934
  22. package/dist/esm/model/nodes/ChatNodeBase.js +1277 -0
  23. package/dist/esm/model/nodes/ChunkNode.js +2 -2
  24. package/dist/esm/model/nodes/CodeNode.js +40 -5
  25. package/dist/esm/model/nodes/CronNode.js +248 -0
  26. package/dist/esm/model/nodes/DelegateFunctionCallNode.js +37 -12
  27. package/dist/esm/model/nodes/DestructureNode.js +1 -1
  28. package/dist/esm/model/nodes/DocumentNode.js +183 -0
  29. package/dist/esm/model/nodes/ExtractJsonNode.js +4 -4
  30. package/dist/esm/model/nodes/ExtractRegexNode.js +10 -11
  31. package/dist/esm/model/nodes/GetAllDatasetsNode.js +1 -1
  32. package/dist/esm/model/nodes/GetEmbeddingNode.js +1 -1
  33. package/dist/esm/model/nodes/HttpCallNode.js +3 -1
  34. package/dist/esm/model/nodes/IfNode.js +5 -0
  35. package/dist/esm/model/nodes/LoopControllerNode.js +1 -1
  36. package/dist/esm/model/nodes/LoopUntilNode.js +214 -0
  37. package/dist/esm/model/nodes/ObjectNode.js +1 -1
  38. package/dist/esm/model/nodes/PromptNode.js +29 -6
  39. package/dist/esm/model/nodes/RaceInputsNode.js +1 -2
  40. package/dist/esm/model/nodes/ReadAllFilesNode.js +210 -0
  41. package/dist/esm/model/nodes/ReadDirectoryNode.js +31 -25
  42. package/dist/esm/model/nodes/ReferencedGraphAliasNode.js +199 -0
  43. package/dist/esm/model/nodes/ReplaceDatasetNode.js +1 -1
  44. package/dist/esm/model/nodes/SliceNode.js +0 -1
  45. package/dist/esm/model/nodes/SplitNode.js +1 -1
  46. package/dist/esm/model/nodes/SubGraphNode.js +0 -1
  47. package/dist/esm/model/nodes/TextNode.js +9 -4
  48. package/dist/esm/model/nodes/ToMarkdownTableNode.js +119 -0
  49. package/dist/esm/model/nodes/ToTreeNode.js +133 -0
  50. package/dist/esm/model/nodes/{GptFunctionNode.js → ToolNode.js} +10 -10
  51. package/dist/esm/model/nodes/UserInputNode.js +10 -12
  52. package/dist/esm/model/nodes/WriteFileNode.js +147 -0
  53. package/dist/esm/native/BrowserNativeApi.js +16 -1
  54. package/dist/esm/plugins/aidon/nodes/ChatAidonNode.js +5 -5
  55. package/dist/esm/plugins/anthropic/anthropic.js +29 -14
  56. package/dist/esm/plugins/anthropic/fetchEventSource.js +3 -2
  57. package/dist/esm/plugins/anthropic/nodes/ChatAnthropicNode.js +264 -147
  58. package/dist/esm/plugins/anthropic/plugin.js +9 -1
  59. package/dist/esm/plugins/assemblyAi/LemurQaNode.js +1 -1
  60. package/dist/esm/plugins/assemblyAi/LemurSummaryNode.js +1 -1
  61. package/dist/esm/plugins/gentrace/plugin.js +6 -6
  62. package/dist/esm/plugins/google/google.js +120 -6
  63. package/dist/esm/plugins/google/nodes/ChatGoogleNode.js +219 -56
  64. package/dist/esm/plugins/google/plugin.js +13 -6
  65. package/dist/esm/plugins/openai/nodes/RunThreadNode.js +2 -2
  66. package/dist/esm/plugins/openai/nodes/ThreadMessageNode.js +1 -1
  67. package/dist/esm/recording/ExecutionRecorder.js +59 -4
  68. package/dist/esm/utils/base64.js +13 -0
  69. package/dist/esm/utils/chatMessageToOpenAIChatCompletionMessage.js +15 -2
  70. package/dist/esm/utils/coerceType.js +4 -1
  71. package/dist/esm/utils/fetchEventSource.js +1 -1
  72. package/dist/esm/utils/interpolation.js +108 -3
  73. package/dist/esm/utils/openai.js +106 -50
  74. package/dist/esm/utils/paths.js +80 -0
  75. package/dist/esm/utils/serialization/serialization_v4.js +5 -0
  76. package/dist/types/api/createProcessor.d.ts +11 -5
  77. package/dist/types/api/looseDataValue.d.ts +4 -0
  78. package/dist/types/api/streaming.d.ts +1 -1
  79. package/dist/types/exports.d.ts +2 -0
  80. package/dist/types/integrations/CodeRunner.d.ts +18 -0
  81. package/dist/types/integrations/DatasetProvider.d.ts +1 -1
  82. package/dist/types/model/DataValue.d.ts +29 -6
  83. package/dist/types/model/EditorDefinition.d.ts +6 -1
  84. package/dist/types/model/GraphProcessor.d.ts +14 -7
  85. package/dist/types/model/NodeBase.d.ts +4 -0
  86. package/dist/types/model/NodeImpl.d.ts +5 -4
  87. package/dist/types/model/Nodes.d.ts +13 -4
  88. package/dist/types/model/ProcessContext.d.ts +16 -1
  89. package/dist/types/model/Project.d.ts +19 -7
  90. package/dist/types/model/ProjectReferenceLoader.d.ts +5 -0
  91. package/dist/types/model/RivetPlugin.d.ts +6 -0
  92. package/dist/types/model/RivetUIContext.d.ts +5 -1
  93. package/dist/types/model/Settings.d.ts +1 -0
  94. package/dist/types/model/nodes/AssemblePromptNode.d.ts +4 -1
  95. package/dist/types/model/nodes/ChatLoopNode.d.ts +21 -0
  96. package/dist/types/model/nodes/ChatNode.d.ts +2 -62
  97. package/dist/types/model/nodes/ChatNodeBase.d.ts +85 -0
  98. package/dist/types/model/nodes/CodeNode.d.ts +8 -2
  99. package/dist/types/model/nodes/CronNode.d.ts +34 -0
  100. package/dist/types/model/nodes/DelegateFunctionCallNode.d.ts +1 -0
  101. package/dist/types/model/nodes/DocumentNode.d.ts +28 -0
  102. package/dist/types/model/nodes/GetAllDatasetsNode.d.ts +2 -2
  103. package/dist/types/model/nodes/LoopUntilNode.d.ts +32 -0
  104. package/dist/types/model/nodes/ObjectNode.d.ts +2 -2
  105. package/dist/types/model/nodes/PromptNode.d.ts +2 -0
  106. package/dist/types/model/nodes/RaceInputsNode.d.ts +1 -2
  107. package/dist/types/model/nodes/ReadAllFilesNode.d.ts +30 -0
  108. package/dist/types/model/nodes/ReadDirectoryNode.d.ts +1 -1
  109. package/dist/types/model/nodes/ReferencedGraphAliasNode.d.ts +31 -0
  110. package/dist/types/model/nodes/SplitNode.d.ts +2 -2
  111. package/dist/types/model/nodes/ToMarkdownTableNode.d.ts +19 -0
  112. package/dist/types/model/nodes/ToTreeNode.d.ts +21 -0
  113. package/dist/types/model/nodes/UserInputNode.d.ts +2 -3
  114. package/dist/types/model/nodes/WriteFileNode.d.ts +23 -0
  115. package/dist/types/native/BrowserNativeApi.d.ts +8 -5
  116. package/dist/types/native/NativeApi.d.ts +12 -1
  117. package/dist/types/plugins/anthropic/anthropic.d.ts +94 -13
  118. package/dist/types/plugins/anthropic/nodes/ChatAnthropicNode.d.ts +7 -2
  119. package/dist/types/plugins/google/google.d.ts +101 -18
  120. package/dist/types/plugins/google/nodes/ChatGoogleNode.d.ts +3 -2
  121. package/dist/types/recording/RecordedEvents.d.ts +3 -0
  122. package/dist/types/utils/base64.d.ts +2 -1
  123. package/dist/types/utils/chatMessageToOpenAIChatCompletionMessage.d.ts +3 -1
  124. package/dist/types/utils/interpolation.d.ts +3 -0
  125. package/dist/types/utils/openai.d.ts +127 -21
  126. package/dist/types/utils/paths.d.ts +8 -0
  127. package/dist/types/utils/serialization/serialization_v3.d.ts +1 -0
  128. package/package.json +15 -11
  129. /package/dist/types/model/nodes/{GptFunctionNode.d.ts → ToolNode.d.ts} +0 -0
@@ -1,6 +1,8 @@
1
1
  import { nanoid } from 'nanoid/non-secure';
2
2
  import {} from '../index.js';
3
3
  import Emittery from 'emittery';
4
+ import { uint8ArrayToBase64Sync, base64ToUint8Array } from '../utils/base64.js';
5
+ import { isPlainObject } from 'lodash-es';
4
6
  const toRecordedEventMap = {
5
7
  graphStart: ({ graph, inputs }) => ({ graphId: graph.metadata.id, inputs }),
6
8
  graphFinish: ({ graph, outputs }) => ({ graphId: graph.metadata.id, outputs }),
@@ -36,11 +38,13 @@ const toRecordedEventMap = {
36
38
  outputs,
37
39
  reason,
38
40
  }),
39
- userInput: ({ node, inputs, callback, processId }) => ({
41
+ userInput: ({ node, inputs, callback, processId, inputStrings, renderingType }) => ({
40
42
  nodeId: node.id,
41
43
  inputs,
42
44
  callback,
43
45
  processId,
46
+ inputStrings,
47
+ renderingType,
44
48
  }),
45
49
  partialOutput: ({ node, outputs, index, processId }) => ({
46
50
  nodeId: node.id,
@@ -91,6 +95,25 @@ function toRecordedEvent(event, data) {
91
95
  ts: Date.now(),
92
96
  };
93
97
  }
98
+ function mapValuesDeep(obj, fn) {
99
+ if (Array.isArray(obj)) {
100
+ return obj.map((value) => {
101
+ if (isPlainObject(value) || Array.isArray(value)) {
102
+ return mapValuesDeep(value, fn);
103
+ }
104
+ return fn(value);
105
+ });
106
+ }
107
+ if (isPlainObject(obj)) {
108
+ return Object.fromEntries(Object.entries(obj).map(([key, value]) => {
109
+ if (isPlainObject(value) || Array.isArray(value)) {
110
+ return [key, mapValuesDeep(value, fn)];
111
+ }
112
+ return [key, fn(value)];
113
+ }));
114
+ }
115
+ return fn(obj);
116
+ }
94
117
  export class ExecutionRecorder {
95
118
  #events = [];
96
119
  recordingId;
@@ -107,7 +130,7 @@ export class ExecutionRecorder {
107
130
  off = undefined;
108
131
  once = undefined;
109
132
  recordSocket(channel) {
110
- return new Promise((resolve, reject) => {
133
+ return new Promise((resolve) => {
111
134
  this.recordingId = nanoid();
112
135
  const listener = (event) => {
113
136
  const { message, data } = JSON.parse(event.data);
@@ -119,6 +142,7 @@ export class ExecutionRecorder {
119
142
  }
120
143
  this.#events.push(toRecordedEvent(message, data));
121
144
  if (message === 'done' || message === 'abort' || message === 'error') {
145
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
122
146
  this.#emitter.emit('finish', {
123
147
  recording: this.getRecording(),
124
148
  });
@@ -140,6 +164,7 @@ export class ExecutionRecorder {
140
164
  }
141
165
  this.#events.push(toRecordedEvent(event, data));
142
166
  if (event === 'done' || event === 'abort' || event === 'error') {
167
+ // eslint-disable-next-line @typescript-eslint/no-floating-promises
143
168
  this.#emitter.emit('finish', {
144
169
  recording: this.getRecording(),
145
170
  });
@@ -163,15 +188,45 @@ export class ExecutionRecorder {
163
188
  if (serializedRecording.version !== 1) {
164
189
  throw new Error('Unsupported serialized events version');
165
190
  }
166
- recorder.recordingId = serializedRecording.recording.recordingId;
167
- recorder.#events = serializedRecording.recording.events;
191
+ const recording = mapValuesDeep(serializedRecording.recording, (val) => {
192
+ if (typeof val === 'string' && val.startsWith('$ASSET:')) {
193
+ const id = val.slice('$ASSET:'.length);
194
+ const asset = serializedRecording.assets?.[id];
195
+ if (asset) {
196
+ return new Uint8Array(base64ToUint8Array(asset));
197
+ }
198
+ else {
199
+ return val;
200
+ }
201
+ }
202
+ return val;
203
+ });
204
+ recorder.recordingId = recording.recordingId;
205
+ recorder.#events = recording.events;
168
206
  return recorder;
169
207
  }
170
208
  serialize() {
171
209
  const serialized = {
172
210
  version: 1,
173
211
  recording: this.getRecording(),
212
+ assets: {},
174
213
  };
214
+ serialized.recording = mapValuesDeep(serialized.recording, (val) => {
215
+ if (val instanceof Uint8Array) {
216
+ const asString = uint8ArrayToBase64Sync(val);
217
+ const existingAsset = Object.entries(serialized.assets).find(([, asset]) => asset === asString);
218
+ if (!existingAsset) {
219
+ const id = nanoid();
220
+ serialized.assets[id] = asString;
221
+ return `$ASSET:${id}`;
222
+ }
223
+ else {
224
+ const [id] = existingAsset;
225
+ return `$ASSET:${id}`;
226
+ }
227
+ }
228
+ return val;
229
+ });
175
230
  return JSON.stringify(serialized);
176
231
  }
177
232
  }
@@ -14,6 +14,19 @@ export async function uint8ArrayToBase64(uint8Array) {
14
14
  return dataUrl.split(',')[1];
15
15
  }
16
16
  }
17
+ export function uint8ArrayToBase64Sync(uint8Array) {
18
+ if (typeof window === 'undefined') {
19
+ // Node executor
20
+ return Buffer.from(uint8Array).toString('base64');
21
+ }
22
+ else {
23
+ // Browser executor
24
+ const binary = Array.from(uint8Array)
25
+ .map((byte) => String.fromCharCode(byte))
26
+ .join('');
27
+ return btoa(binary);
28
+ }
29
+ }
17
30
  export function base64ToUint8Array(base64) {
18
31
  const binaryString = atob(base64);
19
32
  const len = binaryString.length;
@@ -1,6 +1,6 @@
1
1
  import { match } from 'ts-pattern';
2
2
  import { uint8ArrayToBase64 } from './index.js';
3
- export async function chatMessageToOpenAIChatCompletionMessage(message) {
3
+ export async function chatMessageToOpenAIChatCompletionMessage(message, options) {
4
4
  const onlyStringContent = (message) => {
5
5
  const parts = Array.isArray(message.message) ? message.message : [message.message];
6
6
  const stringContent = parts
@@ -14,7 +14,20 @@ export async function chatMessageToOpenAIChatCompletionMessage(message) {
14
14
  return stringContent;
15
15
  };
16
16
  return match(message)
17
- .with({ type: 'system' }, (m) => ({ role: m.type, content: onlyStringContent(m) }))
17
+ .with({ type: 'system' }, (m) => {
18
+ if (options.isReasoningModel) {
19
+ return {
20
+ role: 'developer',
21
+ content: onlyStringContent(m),
22
+ };
23
+ }
24
+ else {
25
+ return {
26
+ role: m.type,
27
+ content: onlyStringContent(m),
28
+ };
29
+ }
30
+ })
18
31
  .with({ type: 'user' }, async (m) => {
19
32
  const parts = Array.isArray(m.message) ? m.message : [m.message];
20
33
  if (parts.length === 1 && typeof parts[0] === 'string') {
@@ -268,7 +268,10 @@ function coerceToBinary(value) {
268
268
  if (value.type === 'number') {
269
269
  return new Uint8Array([value.value]);
270
270
  }
271
- if (value.type === 'audio' || value.type === 'image') {
271
+ if (value.type === 'chat-message') {
272
+ return new TextEncoder().encode(coerceToString(value));
273
+ }
274
+ if (value.type === 'audio' || value.type === 'image' || value.type === 'document') {
272
275
  return value.value.data;
273
276
  }
274
277
  return new TextEncoder().encode(JSON.stringify(value.value));
@@ -47,7 +47,7 @@ export class EventSourceResponse extends Response {
47
47
  }
48
48
  async raceWithTimeout(promise, timeout) {
49
49
  const raceTimeout = timeout ?? DEFAULT_CHAT_NODE_TIMEOUT;
50
- // eslint-disable-next-line no-async-promise-executor -- Error handled correctly
50
+ // eslint-disable-next-line no-async-promise-executor,@typescript-eslint/no-misused-promises -- Error handled correctly
51
51
  return new Promise(async (resolve, reject) => {
52
52
  const timer = setTimeout(() => {
53
53
  reject(new Error('Timeout: API response took too long.'));
@@ -1,6 +1,111 @@
1
+ import { dedent } from './misc.js';
2
+ export const TOKEN_MATCH_REGEX = /\{\{(?!\{)([^{}\s][^{}]*[^{}\s]|[^{}\s])\}\}(?!\})/g;
3
+ export const ESCAPED_TOKEN_REGEX = /\{{3}([^{}]+)\}{3}/g;
4
+ const processingFunctions = {
5
+ indent: (input, spaces = 0) => {
6
+ const indent = ' '.repeat(spaces);
7
+ return input
8
+ .split('\n')
9
+ .map((line) => `${indent}${line}`)
10
+ .join('\n');
11
+ },
12
+ quote: (input, level = 1) => {
13
+ const quotePrefix = '> '.repeat(level);
14
+ return input
15
+ .split('\n')
16
+ .map((line) => `${quotePrefix}${line}`)
17
+ .join('\n');
18
+ },
19
+ uppercase: (input) => {
20
+ return input.toUpperCase();
21
+ },
22
+ lowercase: (input) => {
23
+ return input.toLowerCase();
24
+ },
25
+ trim: (input) => {
26
+ return input.trim();
27
+ },
28
+ truncate: (input, length = 50) => {
29
+ if (input.length <= length)
30
+ return input;
31
+ return input.slice(0, length) + '...';
32
+ },
33
+ list: (input, level = 1) => {
34
+ const indent = ' '.repeat(level - 1);
35
+ return input
36
+ .split('\n')
37
+ .map((line) => `${indent}- ${line}`)
38
+ .join('\n');
39
+ },
40
+ sort: (input) => {
41
+ return input.split('\n').sort().join('\n');
42
+ },
43
+ dedent: (input) => {
44
+ return dedent(input);
45
+ },
46
+ wrap: (input, width = 80) => {
47
+ const words = input.split(/\s+/);
48
+ const lines = [];
49
+ let currentLine = '';
50
+ for (const word of words) {
51
+ if (currentLine.length + word.length + 1 <= width) {
52
+ currentLine += (currentLine ? ' ' : '') + word;
53
+ }
54
+ else {
55
+ lines.push(currentLine);
56
+ currentLine = word;
57
+ }
58
+ }
59
+ if (currentLine) {
60
+ lines.push(currentLine);
61
+ }
62
+ return lines.join('\n');
63
+ },
64
+ };
65
+ // Parse processing instructions like "indent 2" or "quote" into function name and parameter
66
+ function parseProcessing(instruction) {
67
+ const parts = instruction.trim().split(/\s+/);
68
+ return {
69
+ func: parts[0],
70
+ param: parts[1] ? parseInt(parts[1], 10) : undefined,
71
+ };
72
+ }
73
+ // Apply a chain of processing functions to a string
74
+ function applyProcessing(value, processingChain) {
75
+ const instructions = processingChain.split('|').slice(1); // Remove the token part
76
+ return instructions.reduce((result, instruction) => {
77
+ const { func, param } = parseProcessing(instruction);
78
+ const processingFunc = processingFunctions[func];
79
+ if (!processingFunc) {
80
+ console.warn(`Unknown processing function: ${func}`);
81
+ return result;
82
+ }
83
+ return processingFunc(result, param);
84
+ }, value);
85
+ }
1
86
  export function interpolate(baseString, values) {
2
- return baseString.replace(/\{\{([^}]+)\}\}/g, (_m, p1) => {
3
- const value = values[p1];
4
- return value !== undefined ? value : '';
87
+ return baseString
88
+ .replace(TOKEN_MATCH_REGEX, (_m, p1) => {
89
+ const [token, ...processing] = p1.split('|');
90
+ const value = values[token.trim()];
91
+ if (value === undefined)
92
+ return '';
93
+ if (processing.length > 0) {
94
+ return applyProcessing(value, p1);
95
+ }
96
+ return value;
97
+ })
98
+ .replace(ESCAPED_TOKEN_REGEX, (_m, p1) => {
99
+ return `{{${p1}}}`;
5
100
  });
6
101
  }
102
+ // Extract all unique variable names from a template string
103
+ export function extractInterpolationVariables(template) {
104
+ const matches = template.matchAll(TOKEN_MATCH_REGEX);
105
+ const variables = new Set();
106
+ for (const match of matches) {
107
+ const [token] = match[1].split('|');
108
+ variables.add(token.trim());
109
+ }
110
+ return Array.from(variables);
111
+ }
@@ -1,6 +1,9 @@
1
1
  import { orderBy } from 'lodash-es';
2
2
  import { DEFAULT_CHAT_NODE_TIMEOUT } from './defaults.js';
3
3
  import fetchEventSource from './fetchEventSource.js';
4
+ export const defaultOpenaiSupported = {
5
+ parallelFunctionCalls: true,
6
+ };
4
7
  export const openaiModels = {
5
8
  'gpt-4': {
6
9
  maxTokens: 8192,
@@ -34,54 +37,6 @@ export const openaiModels = {
34
37
  },
35
38
  displayName: 'GPT-4 32k (v0613)',
36
39
  },
37
- 'gpt-3.5-turbo': {
38
- maxTokens: 4096,
39
- cost: {
40
- prompt: 0.002,
41
- completion: 0.002,
42
- },
43
- displayName: 'GPT-3.5 Turbo',
44
- },
45
- 'gpt-3.5-turbo-16k': {
46
- maxTokens: 16384,
47
- cost: {
48
- prompt: 0.001,
49
- completion: 0.002,
50
- },
51
- displayName: 'GPT-3.5 16k',
52
- },
53
- 'gpt-3.5-turbo-0613': {
54
- maxTokens: 16384,
55
- cost: {
56
- prompt: 0.002,
57
- completion: 0.002,
58
- },
59
- displayName: 'GPT-3.5 (v0613)',
60
- },
61
- 'gpt-3.5-turbo-1106': {
62
- maxTokens: 16385,
63
- cost: {
64
- prompt: 0.001,
65
- completion: 0.002,
66
- },
67
- displayName: 'GPT-3.5 (v1106)',
68
- },
69
- 'gpt-3.5-turbo-16k-0613': {
70
- maxTokens: 16384,
71
- cost: {
72
- prompt: 0.001,
73
- completion: 0.002,
74
- },
75
- displayName: 'GPT-3.5 16k (v0613)',
76
- },
77
- 'gpt-3.5-turbo-0301': {
78
- maxTokens: 16384,
79
- cost: {
80
- prompt: 0.002,
81
- completion: 0.002,
82
- },
83
- displayName: 'GPT-3.5 (v0301)',
84
- },
85
40
  'gpt-4-0314': {
86
41
  maxTokens: 8192,
87
42
  cost: {
@@ -146,6 +101,93 @@ export const openaiModels = {
146
101
  },
147
102
  displayName: 'GPT-4o mini (2024-07-18)',
148
103
  },
104
+ o1: {
105
+ maxTokens: 128000,
106
+ cost: {
107
+ prompt: 0.015,
108
+ completion: 0.6,
109
+ },
110
+ displayName: 'o1',
111
+ supported: {
112
+ parallelFunctionCalls: false,
113
+ },
114
+ },
115
+ 'o1-preview': {
116
+ maxTokens: 128000,
117
+ cost: {
118
+ prompt: 0.015,
119
+ completion: 0.06,
120
+ },
121
+ displayName: 'o1-preview',
122
+ supported: {
123
+ parallelFunctionCalls: false,
124
+ },
125
+ },
126
+ 'o1-preview-2024-09-12': {
127
+ maxTokens: 128000,
128
+ cost: {
129
+ prompt: 0.015,
130
+ completion: 0.06,
131
+ },
132
+ displayName: 'o1-preview (2024-09-12)',
133
+ supported: {
134
+ parallelFunctionCalls: false,
135
+ },
136
+ },
137
+ 'o1-mini': {
138
+ maxTokens: 128000,
139
+ cost: {
140
+ prompt: 0.0011,
141
+ completion: 0.0044,
142
+ },
143
+ displayName: 'o1-mini',
144
+ supported: {
145
+ parallelFunctionCalls: false,
146
+ },
147
+ },
148
+ 'o1-mini-2024-09-12': {
149
+ maxTokens: 128000,
150
+ cost: {
151
+ prompt: 0.0011,
152
+ completion: 0.0044,
153
+ },
154
+ displayName: 'o1-mini (2024-09-12)',
155
+ supported: {
156
+ parallelFunctionCalls: false,
157
+ },
158
+ },
159
+ 'o3-mini': {
160
+ maxTokens: 200000,
161
+ cost: {
162
+ prompt: 0.0011,
163
+ completion: 0.0044,
164
+ },
165
+ displayName: 'o3-mini',
166
+ supported: {
167
+ parallelFunctionCalls: false,
168
+ },
169
+ },
170
+ 'o3-mini-2025-01-31': {
171
+ maxTokens: 200000,
172
+ cost: {
173
+ prompt: 0.0011,
174
+ completion: 0.0044,
175
+ },
176
+ displayName: 'o3-mini (2025-01-31)',
177
+ supported: {
178
+ parallelFunctionCalls: false,
179
+ },
180
+ },
181
+ 'gpt-4o-audio-preview': {
182
+ maxTokens: 128000,
183
+ cost: {
184
+ prompt: 0.0025,
185
+ completion: 0.01,
186
+ audioPrompt: 0.04,
187
+ audioCompletion: 0.08,
188
+ },
189
+ displayName: 'GPT-4o Audio (Preview)',
190
+ },
149
191
  'local-model': {
150
192
  maxTokens: Number.MAX_SAFE_INTEGER,
151
193
  cost: {
@@ -169,7 +211,21 @@ export class OpenAIError extends Error {
169
211
  this.name = 'OpenAIError';
170
212
  }
171
213
  }
172
- ;
214
+ export async function chatCompletions({ endpoint, auth, signal, headers, timeout, ...rest }) {
215
+ const abortSignal = signal ?? new AbortController().signal;
216
+ const response = await fetch(endpoint, {
217
+ method: 'POST',
218
+ headers: {
219
+ 'Content-Type': 'application/json',
220
+ Authorization: `Bearer ${auth.apiKey}`,
221
+ ...(auth.organization ? { 'OpenAI-Organization': auth.organization } : {}),
222
+ ...headers,
223
+ },
224
+ body: JSON.stringify(rest),
225
+ signal: abortSignal,
226
+ });
227
+ return response.json();
228
+ }
173
229
  export async function* streamChatCompletions({ endpoint, auth, signal, headers, timeout, ...rest }) {
174
230
  const abortSignal = signal ?? new AbortController().signal;
175
231
  const response = await fetchEventSource(endpoint, {
@@ -184,7 +240,7 @@ export async function* streamChatCompletions({ endpoint, auth, signal, headers,
184
240
  ...rest,
185
241
  stream: true,
186
242
  stream_options: {
187
- "include_usage": true
243
+ include_usage: true,
188
244
  },
189
245
  }),
190
246
  signal: abortSignal,
@@ -0,0 +1,80 @@
1
+ export function createTreeFromPaths(paths, rootPath) {
2
+ // Helper to get all parent paths of a given path
3
+ const getParentPaths = (path) => {
4
+ const parts = path.split('/').filter((p) => p);
5
+ return parts.slice(0, -1).map((_, index) => parts.slice(0, index + 1).join('/'));
6
+ };
7
+ // First, create a unique set of all directories
8
+ const directories = new Set();
9
+ paths.forEach((path) => {
10
+ // Add all parent directories of this path
11
+ const cleanPath = path.replace(/^\/+|\/+$/g, '');
12
+ getParentPaths(cleanPath).forEach((dir) => directories.add(dir));
13
+ // If the path itself ends with /, it's a directory
14
+ if (path.endsWith('/')) {
15
+ directories.add(cleanPath);
16
+ }
17
+ });
18
+ // Create the root node
19
+ const root = {
20
+ path: rootPath,
21
+ name: rootPath || 'root',
22
+ isDirectory: true,
23
+ children: [],
24
+ };
25
+ // Create a map for quick node lookups - use full paths as keys
26
+ const nodeMap = new Map();
27
+ nodeMap.set(rootPath, root);
28
+ // Helper to get or create a node for a path
29
+ const getOrCreateNode = (fullPath) => {
30
+ const cleanPath = fullPath.replace(/^\/+|\/+$/g, '');
31
+ if (nodeMap.has(cleanPath)) {
32
+ return nodeMap.get(cleanPath);
33
+ }
34
+ const parts = cleanPath.split('/').filter((p) => p);
35
+ const name = parts[parts.length - 1] || cleanPath;
36
+ const node = {
37
+ path: name, // Just use the name as the path
38
+ name,
39
+ isDirectory: directories.has(cleanPath),
40
+ children: [],
41
+ };
42
+ nodeMap.set(cleanPath, node); // Still use full path for lookup
43
+ // Important: Create parent-child relationship immediately
44
+ if (parts.length > 1) {
45
+ const parentPath = parts.slice(0, -1).join('/');
46
+ const parent = getOrCreateNode(parentPath);
47
+ if (!parent.children.some((child) => child.name === name)) {
48
+ parent.children.push(node);
49
+ }
50
+ }
51
+ else if (cleanPath && rootPath !== cleanPath) {
52
+ // Top-level node
53
+ if (!root.children.some((child) => child.name === name)) {
54
+ root.children.push(node);
55
+ }
56
+ }
57
+ return node;
58
+ };
59
+ // Process all paths to build the tree
60
+ paths
61
+ .filter((path) => path.trim())
62
+ .forEach((path) => {
63
+ const cleanPath = path.replace(/^\/+|\/+$/g, '');
64
+ if (cleanPath) {
65
+ getOrCreateNode(cleanPath);
66
+ }
67
+ });
68
+ // Sort children of all nodes
69
+ const sortNode = (node) => {
70
+ node.children.sort((a, b) => {
71
+ if (a.isDirectory !== b.isDirectory) {
72
+ return a.isDirectory ? -1 : 1;
73
+ }
74
+ return a.name.localeCompare(b.name);
75
+ });
76
+ node.children.forEach(sortNode);
77
+ };
78
+ sortNode(root);
79
+ return root;
80
+ }
@@ -3,6 +3,7 @@ import stableStringify from 'safe-stable-stringify';
3
3
  import * as yaml from 'yaml';
4
4
  import { doubleCheckProject } from './serializationUtils.js';
5
5
  import { entries } from '../typeSafety.js';
6
+ import {} from '../../model/Project.js';
6
7
  export function projectV4Deserializer(data) {
7
8
  if (typeof data !== 'string') {
8
9
  throw new Error('Project v4 deserializer requires a string');
@@ -60,6 +61,7 @@ function toSerializedProject(project, attachedData) {
60
61
  graphs: mapValues(project.graphs, (graph) => toSerializedGraph(graph)),
61
62
  attachedData,
62
63
  plugins: project.plugins ?? [],
64
+ references: project.references ?? [],
63
65
  };
64
66
  }
65
67
  function fromSerializedProject(serializedProject) {
@@ -68,6 +70,7 @@ function fromSerializedProject(serializedProject) {
68
70
  metadata: serializedProject.metadata,
69
71
  graphs: mapValues(serializedProject.graphs, (graph) => fromSerializedGraph(graph)),
70
72
  plugins: serializedProject.plugins ?? [],
73
+ references: serializedProject.references ?? [],
71
74
  },
72
75
  serializedProject.attachedData ?? {},
73
76
  ];
@@ -136,6 +139,7 @@ function toSerializedNode(node, allNodes, allConnections) {
136
139
  outgoingConnections: outgoingConnections.length > 0 ? outgoingConnections : undefined,
137
140
  variants: (node.variants?.length ?? 0) > 0 ? node.variants : undefined,
138
141
  disabled: node.disabled ? true : undefined,
142
+ isConditional: node.isConditional,
139
143
  };
140
144
  }
141
145
  function fromSerializedNode(serializedNode, serializedNodeInfo) {
@@ -162,6 +166,7 @@ function fromSerializedNode(serializedNode, serializedNodeInfo) {
162
166
  data: serializedNode.data ?? {},
163
167
  variants: serializedNode.variants ?? [],
164
168
  disabled: serializedNode.disabled,
169
+ isConditional: serializedNode.isConditional,
165
170
  },
166
171
  connections,
167
172
  ];
@@ -1,7 +1,10 @@
1
1
  import type { PascalCase } from 'type-fest';
2
2
  import { type AttachedData, type AudioProvider, type DataValue, type DatasetProvider, type ExternalFunction, type NativeApi, type NodeRegistration, type ProcessContext, type ProcessEvents, type Project, type RivetEventStreamFilterSpec, type Settings } from '../index.js';
3
3
  import { GraphProcessor } from '../model/GraphProcessor.js';
4
- export type LooseDataValue = DataValue | string | number | boolean;
4
+ import type { Tokenizer } from '../integrations/Tokenizer.js';
5
+ import { type LooseDataValue } from './looseDataValue.js';
6
+ import type { CodeRunner } from '../integrations/CodeRunner.js';
7
+ import type { ProjectReferenceLoader } from '../model/ProjectReferenceLoader.js';
5
8
  export type RunGraphOptions = {
6
9
  graph?: string;
7
10
  inputs?: Record<string, LooseDataValue>;
@@ -17,18 +20,21 @@ export type RunGraphOptions = {
17
20
  };
18
21
  abortSignal?: AbortSignal;
19
22
  registry?: NodeRegistration;
23
+ includeTrace?: boolean;
20
24
  getChatNodeEndpoint?: ProcessContext['getChatNodeEndpoint'];
25
+ tokenizer?: Tokenizer;
26
+ codeRunner?: CodeRunner;
27
+ projectPath?: string;
28
+ projectReferenceLoader?: ProjectReferenceLoader;
21
29
  } & {
22
30
  [P in keyof ProcessEvents as `on${PascalCase<P>}`]?: (params: ProcessEvents[P]) => void;
23
31
  } & Settings;
24
- export declare function looseDataValuesToDataValues(values: Record<string, LooseDataValue>): Record<string, DataValue>;
25
- export declare function looseDataValueToDataValue(value: LooseDataValue): DataValue;
26
32
  export declare function coreCreateProcessor(project: Project, options: RunGraphOptions): {
27
33
  processor: GraphProcessor;
28
34
  inputs: Record<string, DataValue>;
29
35
  contextValues: Record<string, DataValue>;
30
- getEvents: (spec: RivetEventStreamFilterSpec) => AsyncGenerator<import("./streaming.js").RivetEventStreamEventInfo, void, unknown>;
31
- getSSEStream: (spec: RivetEventStreamFilterSpec) => ReadableStream<Uint8Array>;
36
+ getEvents: (spec: RivetEventStreamFilterSpec) => AsyncGenerator<import("./streaming.js").RivetEventStreamEventInfo, void, any>;
37
+ getSSEStream: (spec: RivetEventStreamFilterSpec) => ReadableStream<Uint8Array<ArrayBufferLike>>;
32
38
  streamNode: (nodeIdOrTitle: string) => ReadableStream<string>;
33
39
  run(): Promise<import("../index.js").GraphOutputs>;
34
40
  };
@@ -0,0 +1,4 @@
1
+ import type { DataValue } from '../model/DataValue.js';
2
+ export type LooseDataValue = DataValue | string | number | boolean;
3
+ export declare function looseDataValuesToDataValues(values: Record<string, LooseDataValue>): Record<string, DataValue>;
4
+ export declare function looseDataValueToDataValue(value: LooseDataValue): DataValue;
@@ -52,5 +52,5 @@ export declare function getProcessorEvents(processor: GraphProcessor, spec: Rive
52
52
  */
53
53
  export declare function getProcessorSSEStream(processor: GraphProcessor,
54
54
  /** The spec for what you're streaming to the client */
55
- spec: RivetEventStreamFilterSpec): ReadableStream<Uint8Array>;
55
+ spec: RivetEventStreamFilterSpec): ReadableStream<Uint8Array<ArrayBufferLike>>;
56
56
  export declare function getSingleNodeStream(processor: GraphProcessor, nodeIdOrTitle: string): ReadableStream<string>;
@@ -29,5 +29,7 @@ export * from './model/Dataset.js';
29
29
  export * from './api/streaming.js';
30
30
  export * from './api/createProcessor.js';
31
31
  export * from './integrations/AudioProvider.js';
32
+ export * from './api/looseDataValue.js';
33
+ export * from './integrations/CodeRunner.js';
32
34
  import * as openai from './utils/openai.js';
33
35
  export { openai };