@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.
- package/README.md +4 -0
- package/dist/cjs/bundle.cjs +4512 -1240
- package/dist/cjs/bundle.cjs.map +4 -4
- package/dist/esm/api/createProcessor.js +8 -17
- package/dist/esm/api/looseDataValue.js +16 -0
- package/dist/esm/exports.js +2 -0
- package/dist/esm/integrations/CodeRunner.js +36 -0
- package/dist/esm/integrations/DatasetProvider.js +1 -1
- package/dist/esm/integrations/GptTokenizerTokenizer.js +7 -4
- package/dist/esm/integrations/openai/OpenAIEmbeddingGenerator.js +1 -1
- package/dist/esm/model/DataValue.js +14 -2
- package/dist/esm/model/GraphProcessor.js +276 -107
- package/dist/esm/model/NodeBase.js +11 -1
- package/dist/esm/model/NodeImpl.js +8 -0
- package/dist/esm/model/Nodes.js +31 -4
- package/dist/esm/model/ProjectReferenceLoader.js +1 -0
- package/dist/esm/model/nodes/AssembleMessageNode.js +12 -2
- package/dist/esm/model/nodes/AssemblePromptNode.js +22 -0
- package/dist/esm/model/nodes/CallGraphNode.js +3 -4
- package/dist/esm/model/nodes/ChatLoopNode.js +150 -0
- package/dist/esm/model/nodes/ChatNode.js +7 -934
- package/dist/esm/model/nodes/ChatNodeBase.js +1277 -0
- package/dist/esm/model/nodes/ChunkNode.js +2 -2
- package/dist/esm/model/nodes/CodeNode.js +40 -5
- package/dist/esm/model/nodes/CronNode.js +248 -0
- package/dist/esm/model/nodes/DelegateFunctionCallNode.js +37 -12
- package/dist/esm/model/nodes/DestructureNode.js +1 -1
- package/dist/esm/model/nodes/DocumentNode.js +183 -0
- package/dist/esm/model/nodes/ExtractJsonNode.js +4 -4
- package/dist/esm/model/nodes/ExtractRegexNode.js +10 -11
- package/dist/esm/model/nodes/GetAllDatasetsNode.js +1 -1
- package/dist/esm/model/nodes/GetEmbeddingNode.js +1 -1
- package/dist/esm/model/nodes/HttpCallNode.js +3 -1
- package/dist/esm/model/nodes/IfNode.js +5 -0
- package/dist/esm/model/nodes/LoopControllerNode.js +1 -1
- package/dist/esm/model/nodes/LoopUntilNode.js +214 -0
- package/dist/esm/model/nodes/ObjectNode.js +1 -1
- package/dist/esm/model/nodes/PromptNode.js +29 -6
- package/dist/esm/model/nodes/RaceInputsNode.js +1 -2
- package/dist/esm/model/nodes/ReadAllFilesNode.js +210 -0
- package/dist/esm/model/nodes/ReadDirectoryNode.js +31 -25
- package/dist/esm/model/nodes/ReferencedGraphAliasNode.js +199 -0
- package/dist/esm/model/nodes/ReplaceDatasetNode.js +1 -1
- package/dist/esm/model/nodes/SliceNode.js +0 -1
- package/dist/esm/model/nodes/SplitNode.js +1 -1
- package/dist/esm/model/nodes/SubGraphNode.js +0 -1
- package/dist/esm/model/nodes/TextNode.js +9 -4
- package/dist/esm/model/nodes/ToMarkdownTableNode.js +119 -0
- package/dist/esm/model/nodes/ToTreeNode.js +133 -0
- package/dist/esm/model/nodes/{GptFunctionNode.js → ToolNode.js} +10 -10
- package/dist/esm/model/nodes/UserInputNode.js +10 -12
- package/dist/esm/model/nodes/WriteFileNode.js +147 -0
- package/dist/esm/native/BrowserNativeApi.js +16 -1
- package/dist/esm/plugins/aidon/nodes/ChatAidonNode.js +5 -5
- package/dist/esm/plugins/anthropic/anthropic.js +29 -14
- package/dist/esm/plugins/anthropic/fetchEventSource.js +3 -2
- package/dist/esm/plugins/anthropic/nodes/ChatAnthropicNode.js +264 -147
- package/dist/esm/plugins/anthropic/plugin.js +9 -1
- package/dist/esm/plugins/assemblyAi/LemurQaNode.js +1 -1
- package/dist/esm/plugins/assemblyAi/LemurSummaryNode.js +1 -1
- package/dist/esm/plugins/gentrace/plugin.js +6 -6
- package/dist/esm/plugins/google/google.js +120 -6
- package/dist/esm/plugins/google/nodes/ChatGoogleNode.js +219 -56
- package/dist/esm/plugins/google/plugin.js +13 -6
- package/dist/esm/plugins/openai/nodes/RunThreadNode.js +2 -2
- package/dist/esm/plugins/openai/nodes/ThreadMessageNode.js +1 -1
- package/dist/esm/recording/ExecutionRecorder.js +59 -4
- package/dist/esm/utils/base64.js +13 -0
- package/dist/esm/utils/chatMessageToOpenAIChatCompletionMessage.js +15 -2
- package/dist/esm/utils/coerceType.js +4 -1
- package/dist/esm/utils/fetchEventSource.js +1 -1
- package/dist/esm/utils/interpolation.js +108 -3
- package/dist/esm/utils/openai.js +106 -50
- package/dist/esm/utils/paths.js +80 -0
- package/dist/esm/utils/serialization/serialization_v4.js +5 -0
- package/dist/types/api/createProcessor.d.ts +11 -5
- package/dist/types/api/looseDataValue.d.ts +4 -0
- package/dist/types/api/streaming.d.ts +1 -1
- package/dist/types/exports.d.ts +2 -0
- package/dist/types/integrations/CodeRunner.d.ts +18 -0
- package/dist/types/integrations/DatasetProvider.d.ts +1 -1
- package/dist/types/model/DataValue.d.ts +29 -6
- package/dist/types/model/EditorDefinition.d.ts +6 -1
- package/dist/types/model/GraphProcessor.d.ts +14 -7
- package/dist/types/model/NodeBase.d.ts +4 -0
- package/dist/types/model/NodeImpl.d.ts +5 -4
- package/dist/types/model/Nodes.d.ts +13 -4
- package/dist/types/model/ProcessContext.d.ts +16 -1
- package/dist/types/model/Project.d.ts +19 -7
- package/dist/types/model/ProjectReferenceLoader.d.ts +5 -0
- package/dist/types/model/RivetPlugin.d.ts +6 -0
- package/dist/types/model/RivetUIContext.d.ts +5 -1
- package/dist/types/model/Settings.d.ts +1 -0
- package/dist/types/model/nodes/AssemblePromptNode.d.ts +4 -1
- package/dist/types/model/nodes/ChatLoopNode.d.ts +21 -0
- package/dist/types/model/nodes/ChatNode.d.ts +2 -62
- package/dist/types/model/nodes/ChatNodeBase.d.ts +85 -0
- package/dist/types/model/nodes/CodeNode.d.ts +8 -2
- package/dist/types/model/nodes/CronNode.d.ts +34 -0
- package/dist/types/model/nodes/DelegateFunctionCallNode.d.ts +1 -0
- package/dist/types/model/nodes/DocumentNode.d.ts +28 -0
- package/dist/types/model/nodes/GetAllDatasetsNode.d.ts +2 -2
- package/dist/types/model/nodes/LoopUntilNode.d.ts +32 -0
- package/dist/types/model/nodes/ObjectNode.d.ts +2 -2
- package/dist/types/model/nodes/PromptNode.d.ts +2 -0
- package/dist/types/model/nodes/RaceInputsNode.d.ts +1 -2
- package/dist/types/model/nodes/ReadAllFilesNode.d.ts +30 -0
- package/dist/types/model/nodes/ReadDirectoryNode.d.ts +1 -1
- package/dist/types/model/nodes/ReferencedGraphAliasNode.d.ts +31 -0
- package/dist/types/model/nodes/SplitNode.d.ts +2 -2
- package/dist/types/model/nodes/ToMarkdownTableNode.d.ts +19 -0
- package/dist/types/model/nodes/ToTreeNode.d.ts +21 -0
- package/dist/types/model/nodes/UserInputNode.d.ts +2 -3
- package/dist/types/model/nodes/WriteFileNode.d.ts +23 -0
- package/dist/types/native/BrowserNativeApi.d.ts +8 -5
- package/dist/types/native/NativeApi.d.ts +12 -1
- package/dist/types/plugins/anthropic/anthropic.d.ts +94 -13
- package/dist/types/plugins/anthropic/nodes/ChatAnthropicNode.d.ts +7 -2
- package/dist/types/plugins/google/google.d.ts +101 -18
- package/dist/types/plugins/google/nodes/ChatGoogleNode.d.ts +3 -2
- package/dist/types/recording/RecordedEvents.d.ts +3 -0
- package/dist/types/utils/base64.d.ts +2 -1
- package/dist/types/utils/chatMessageToOpenAIChatCompletionMessage.d.ts +3 -1
- package/dist/types/utils/interpolation.d.ts +3 -0
- package/dist/types/utils/openai.d.ts +127 -21
- package/dist/types/utils/paths.d.ts +8 -0
- package/dist/types/utils/serialization/serialization_v3.d.ts +1 -0
- package/package.json +15 -11
- /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
|
|
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
|
-
|
|
167
|
-
|
|
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
|
}
|
package/dist/esm/utils/base64.js
CHANGED
|
@@ -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) =>
|
|
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 === '
|
|
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
|
|
3
|
-
|
|
4
|
-
|
|
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
|
+
}
|
package/dist/esm/utils/openai.js
CHANGED
|
@@ -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
|
-
|
|
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
|
-
|
|
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,
|
|
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>;
|
package/dist/types/exports.d.ts
CHANGED
|
@@ -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 };
|