@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
@@ -13,7 +13,7 @@ export class GptFunctionNodeImpl extends NodeImpl {
13
13
  static create() {
14
14
  const chartNode = {
15
15
  type: 'gptFunction',
16
- title: 'GPT Function',
16
+ title: 'Tool',
17
17
  id: nanoid(),
18
18
  visualData: {
19
19
  x: 0,
@@ -21,7 +21,7 @@ export class GptFunctionNodeImpl extends NodeImpl {
21
21
  width: 250,
22
22
  },
23
23
  data: {
24
- name: 'newFunction',
24
+ name: 'newTool',
25
25
  description: 'No description provided',
26
26
  schema: dedent `
27
27
  {
@@ -39,7 +39,7 @@ export class GptFunctionNodeImpl extends NodeImpl {
39
39
  id: 'name',
40
40
  title: 'Name',
41
41
  dataType: 'string',
42
- description: 'The name of the function that GPT will see as available to call',
42
+ description: 'The name of the tool that the LLM will see as available to call',
43
43
  });
44
44
  }
45
45
  if (this.data.useDescriptionInput) {
@@ -47,7 +47,7 @@ export class GptFunctionNodeImpl extends NodeImpl {
47
47
  id: 'description',
48
48
  title: 'Description',
49
49
  dataType: 'string',
50
- description: 'The description of the function that GPT will see as available to call',
50
+ description: 'The description of the tool that the LLM will see as available to call',
51
51
  });
52
52
  }
53
53
  if (this.data.useSchemaInput) {
@@ -55,7 +55,7 @@ export class GptFunctionNodeImpl extends NodeImpl {
55
55
  id: 'schema',
56
56
  title: 'Schema',
57
57
  dataType: 'object',
58
- description: 'The schema of the function that GPT will see as available to call',
58
+ description: 'The schema of the tool that the LLM will see as available to call',
59
59
  });
60
60
  }
61
61
  // Extract inputs from promptText, everything like {{input}}
@@ -81,7 +81,7 @@ export class GptFunctionNodeImpl extends NodeImpl {
81
81
  id: 'function',
82
82
  title: 'Function',
83
83
  dataType: 'gpt-function',
84
- description: 'The GPT function that can be called by the LLM.',
84
+ description: 'The tool that can be called by the LLM.',
85
85
  },
86
86
  ];
87
87
  }
@@ -127,10 +127,10 @@ export class GptFunctionNodeImpl extends NodeImpl {
127
127
  static getUIData() {
128
128
  return {
129
129
  infoBoxBody: dedent `
130
- Defines a GPT function, which is a method that the LLM can call in its responses.
130
+ Defines a tool, which is a method that the LLM can call in its responses.
131
131
  `,
132
- infoBoxTitle: 'GPT Function Node',
133
- contextMenuTitle: 'GPT Function',
132
+ infoBoxTitle: 'Tool Node',
133
+ contextMenuTitle: 'Tool',
134
134
  group: ['AI'],
135
135
  };
136
136
  }
@@ -166,4 +166,4 @@ export class GptFunctionNodeImpl extends NodeImpl {
166
166
  };
167
167
  }
168
168
  }
169
- export const gptFunctionNode = nodeDefinition(GptFunctionNodeImpl, 'GPT Function');
169
+ export const gptFunctionNode = nodeDefinition(GptFunctionNodeImpl, 'Tool');
@@ -5,6 +5,7 @@ import {} from '../../index.js';
5
5
  import { dedent } from 'ts-dedent';
6
6
  import { nodeDefinition } from '../NodeDefinition.js';
7
7
  import { coerceType } from '../../utils/coerceType.js';
8
+ import {} from '../ProcessContext.js';
8
9
  export class UserInputNodeImpl extends NodeImpl {
9
10
  static create() {
10
11
  const chartNode = {
@@ -89,21 +90,18 @@ export class UserInputNodeImpl extends NodeImpl {
89
90
  group: ['Input/Output'],
90
91
  };
91
92
  }
92
- async process() {
93
+ async process(inputs, context) {
94
+ const questions = this.data.useInput ? coerceType(inputs['questions'], 'string[]') : [this.data.prompt];
95
+ const renderingFormat = this.data.renderingFormat === 'preformatted' ? 'text' : 'markdown';
96
+ const response = await context.requestUserInput(questions, renderingFormat);
93
97
  return {
94
- ['output']: undefined,
95
- ['questionsAndAnswers']: undefined,
96
- };
97
- }
98
- getOutputValuesFromUserInput(questions, answers) {
99
- const questionsList = this.data.useInput
100
- ? coerceType(questions['questions'], 'string[]')
101
- : [this.data.prompt];
102
- return {
103
- ['output']: answers,
98
+ ['output']: {
99
+ type: 'string[]',
100
+ value: response.value,
101
+ },
104
102
  ['questionsAndAnswers']: {
105
103
  type: 'string[]',
106
- value: zip(questionsList, answers.value).map(([q, a]) => `${q}\n${a}`),
104
+ value: zip(questions, response.value).map(([q, a]) => `${q}\n${a}`),
107
105
  },
108
106
  };
109
107
  }
@@ -0,0 +1,147 @@
1
+ import {} from '../NodeBase.js';
2
+ import {} from '../DataValue.js';
3
+ import { NodeImpl } from '../NodeImpl.js';
4
+ import { nodeDefinition } from '../NodeDefinition.js';
5
+ import { nanoid } from 'nanoid/non-secure';
6
+ import { getInputOrData } from '../../utils/index.js';
7
+ import {} from '../ProcessContext.js';
8
+ import { dedent } from 'ts-dedent';
9
+ import { coerceTypeOptional } from '../../utils/coerceType.js';
10
+ import { extractInterpolationVariables, interpolate } from '../../utils/interpolation.js';
11
+ const mimeToExtension = {
12
+ 'image/jpeg': 'jpg',
13
+ 'image/png': 'png',
14
+ 'image/gif': 'gif',
15
+ 'audio/wav': 'wav',
16
+ 'audio/mpeg ': 'mp3',
17
+ 'audio/mp3': 'mp3',
18
+ 'audio/ogg': 'ogg'
19
+ };
20
+ export class WriteFileNodeImpl extends NodeImpl {
21
+ static create() {
22
+ return {
23
+ id: nanoid(),
24
+ type: 'writeFile',
25
+ title: 'Write File',
26
+ visualData: { x: 0, y: 0, width: 250 },
27
+ data: {
28
+ path: '',
29
+ asBinary: false,
30
+ usePathOutput: true,
31
+ overwriteExistingFile: false,
32
+ },
33
+ };
34
+ }
35
+ getInputDefinitions() {
36
+ const inputDefinitions = [
37
+ {
38
+ id: 'content',
39
+ title: 'Content',
40
+ dataType: this.data.asBinary ? 'binary' : 'string',
41
+ },
42
+ ];
43
+ if (this.chartNode.data.usePathOutput) {
44
+ inputDefinitions.push({
45
+ id: 'path',
46
+ title: 'Path',
47
+ dataType: 'string',
48
+ coerced: false,
49
+ });
50
+ }
51
+ return inputDefinitions;
52
+ }
53
+ getOutputDefinitions() {
54
+ return [
55
+ {
56
+ id: 'outputContent',
57
+ title: 'Content',
58
+ dataType: this.data.asBinary ? 'binary' : 'string',
59
+ },
60
+ ];
61
+ }
62
+ static getUIData() {
63
+ return {
64
+ infoBoxBody: dedent `
65
+ Writes the contents of the specified file and outputs it as a string.
66
+ `,
67
+ infoBoxTitle: 'Write File Node',
68
+ contextMenuTitle: 'Write File',
69
+ group: ['Input/Output'],
70
+ };
71
+ }
72
+ getEditors() {
73
+ return [
74
+ {
75
+ type: 'string',
76
+ label: 'Path',
77
+ dataKey: 'path',
78
+ useInputToggleDataKey: 'usePathOutput',
79
+ },
80
+ {
81
+ type: 'toggle',
82
+ label: 'Overwrite Existing File instead of making additional copy',
83
+ dataKey: 'overwriteExistingFile',
84
+ },
85
+ {
86
+ type: 'toggle',
87
+ label: 'Read as Binary',
88
+ dataKey: 'asBinary',
89
+ },
90
+ ];
91
+ }
92
+ getBody() {
93
+ return dedent `
94
+ ${this.data.asBinary ? 'Write as Binary' : 'Write as Text'}
95
+ ${this.data.usePathOutput ? '' : `Path: ${this.data.path}`}
96
+ `;
97
+ }
98
+ async process(inputData, context) {
99
+ const { nativeApi } = context;
100
+ const inputContent = inputData['content'] ?? { type: 'any', value: undefined };
101
+ if (nativeApi == null) {
102
+ throw new Error('This node requires a native API to run.');
103
+ }
104
+ const currentPath = context.project.metadata?.path;
105
+ if (!currentPath) {
106
+ throw new Error('Project metadata is missing path.');
107
+ }
108
+ const folderPath = currentPath.replace('.rivet-project', '.rivet-files');
109
+ await nativeApi.createdir(folderPath, true);
110
+ let path = getInputOrData(this.chartNode.data, inputData, 'path');
111
+ const interpolations = extractInterpolationVariables(path);
112
+ if (interpolations.includes('ext')) {
113
+ let extension = 'txt';
114
+ if (this.data.asBinary) {
115
+ if (inputContent.type === 'audio') {
116
+ extension = mimeToExtension[inputContent.value.mediaType ?? ''] ?? 'audio';
117
+ }
118
+ else if (inputContent.type === 'image') {
119
+ extension = mimeToExtension[inputContent.value.mediaType ?? ''] ?? 'image';
120
+ }
121
+ else {
122
+ extension = 'binary';
123
+ }
124
+ }
125
+ path = interpolate(path, { ext: extension });
126
+ }
127
+ let fileDestination = await nativeApi.join(folderPath, path);
128
+ if (!this.data.overwriteExistingFile) {
129
+ fileDestination = await nativeApi.uniqueFilename(fileDestination);
130
+ }
131
+ if (this.data.asBinary) {
132
+ const content = coerceTypeOptional(inputContent, 'binary') ?? new Uint8Array();
133
+ await nativeApi.writeBinaryFile(fileDestination, content);
134
+ return {
135
+ ['outputContent']: { type: 'binary', value: content },
136
+ };
137
+ }
138
+ else {
139
+ const content = coerceTypeOptional(inputContent, 'string') ?? '';
140
+ await nativeApi.writeTextFile(fileDestination, content);
141
+ return {
142
+ ['outputContent']: { type: 'string', value: content },
143
+ };
144
+ }
145
+ }
146
+ }
147
+ export const writeFileNode = nodeDefinition(WriteFileNodeImpl, 'Write File');
@@ -1,6 +1,9 @@
1
1
  import {} from './BaseDir.js';
2
2
  import {} from './NativeApi.js';
3
3
  export class BrowserNativeApi {
4
+ createdir(_path, _recursive, _baseDir) {
5
+ throw new Error('Method not implemented.');
6
+ }
4
7
  readdir(_path, _baseDir) {
5
8
  throw new Error('Method not implemented.');
6
9
  }
@@ -13,7 +16,19 @@ export class BrowserNativeApi {
13
16
  writeTextFile(_path, _data, _baseDir) {
14
17
  throw new Error('Method not implemented.');
15
18
  }
16
- exec(command, args, options) {
19
+ writeBinaryFile(_path, _data, _baseDir) {
20
+ throw new Error('Method not implemented.');
21
+ }
22
+ exists(_path, _baseDir) {
23
+ throw new Error('Method not implemented.');
24
+ }
25
+ join(..._paths) {
26
+ throw new Error('Method not implemented.');
27
+ }
28
+ uniqueFilename(_path, _baseDir) {
29
+ throw new Error('Method not implemented.');
30
+ }
31
+ exec() {
17
32
  throw new Error('Method not supported.');
18
33
  }
19
34
  }
@@ -1,10 +1,10 @@
1
- import { ChatNodeImpl, Rivet, globalRivetNodeRegistry, } from '../../../index.js';
1
+ import { ChatNodeImpl, globalRivetNodeRegistry, } from '../../../index.js';
2
2
  import { omit } from 'lodash-es';
3
3
  import { dedent } from 'ts-dedent';
4
4
  import { coerceTypeOptional } from '../../../utils/coerceType.js';
5
5
  import { pluginNodeDefinition } from '../../../model/NodeDefinition.js';
6
6
  // Temporary
7
- const cache = new Map();
7
+ // const cache = new Map<string, Outputs>();
8
8
  const registry = globalRivetNodeRegistry;
9
9
  ;
10
10
  class ChatAidonNodeImpl extends ChatNodeImpl {
@@ -84,14 +84,14 @@ class ChatAidonNodeImpl extends ChatNodeImpl {
84
84
  const customHeaders = schemaDetail.headers; // Moved this line up to the loop
85
85
  // Check if custom headers are set and are of type string
86
86
  if (customHeaders && typeof customHeaders === "string") {
87
- let parsedCustomHeaders = JSON.parse(customHeaders);
87
+ const parsedCustomHeaders = JSON.parse(customHeaders);
88
88
  headers = {
89
89
  ...headers,
90
90
  ...parsedCustomHeaders
91
91
  };
92
92
  }
93
93
  const fullUrl = schemaDetail.url + path;
94
- const bodyContent = parsedArgs.requestBody || parsedArgs;
94
+ const bodyContent = parsedArgs.requestBody ?? parsedArgs;
95
95
  const requestInit = {
96
96
  method: "POST",
97
97
  headers,
@@ -129,7 +129,7 @@ class ChatAidonNodeImpl extends ChatNodeImpl {
129
129
  //call the tool(s) to get the results to add to the message
130
130
  for (const functionCall of functionCalls) {
131
131
  // Find the schema detail that contains the function name
132
- const toolSchema = toolSchemas.find(detail => detail.name == functionCall.name);
132
+ const toolSchema = toolSchemas.find(detail => detail.name === functionCall.name);
133
133
  if (!toolSchema) {
134
134
  throw new Error(`Function ${functionCall.name} not found in any schema`);
135
135
  }
@@ -56,7 +56,7 @@ export const anthropicModels = {
56
56
  },
57
57
  displayName: 'Claude 3 Opus',
58
58
  },
59
- 'claude-3-5-sonnet-20240620': {
59
+ 'claude-3-5-sonnet-latest': {
60
60
  maxTokens: 200_000,
61
61
  cost: {
62
62
  prompt: 3e-6,
@@ -64,19 +64,36 @@ export const anthropicModels = {
64
64
  },
65
65
  displayName: 'Claude 3.5 Sonnet',
66
66
  },
67
+ 'claude-3-5-haiku-latest': {
68
+ maxTokens: 200_000,
69
+ cost: {
70
+ prompt: 0.8e-6,
71
+ completion: 4e-6,
72
+ },
73
+ displayName: 'Claude 3.5 Haiku',
74
+ },
75
+ 'claude-3-7-sonnet-latest': {
76
+ maxTokens: 200_000,
77
+ cost: {
78
+ prompt: 3e-6,
79
+ completion: 15e-6,
80
+ },
81
+ displayName: 'Claude 3.7 Sonnet',
82
+ },
67
83
  };
68
84
  export const anthropicModelOptions = Object.entries(anthropicModels).map(([id, { displayName }]) => ({
69
85
  value: id,
70
86
  label: displayName,
71
87
  }));
72
- export async function* streamChatCompletions({ apiKey, signal, ...rest }) {
88
+ export async function* streamChatCompletions({ apiEndpoint, apiKey, signal, ...rest }) {
73
89
  const defaultSignal = new AbortController().signal;
74
- const response = await fetchEventSource('https://api.anthropic.com/v1/complete', {
90
+ const response = await fetchEventSource(`${apiEndpoint}/completions`, {
75
91
  method: 'POST',
76
92
  headers: {
77
93
  'Content-Type': 'application/json',
78
94
  'x-api-key': apiKey,
79
95
  'anthropic-version': '2023-06-01',
96
+ 'anthropic-dangerous-direct-browser-access': 'true',
80
97
  },
81
98
  body: JSON.stringify({
82
99
  ...rest,
@@ -85,14 +102,12 @@ export async function* streamChatCompletions({ apiKey, signal, ...rest }) {
85
102
  signal: signal ?? defaultSignal,
86
103
  });
87
104
  let hadChunks = false;
88
- let nextDataType;
89
105
  for await (const chunk of response.events()) {
90
106
  hadChunks = true;
91
107
  if (chunk === '[DONE]') {
92
108
  return;
93
109
  }
94
110
  else if (/\[\w+\]/.test(chunk)) {
95
- nextDataType = chunk.slice(1, -1);
96
111
  continue;
97
112
  }
98
113
  let data;
@@ -110,15 +125,16 @@ export async function* streamChatCompletions({ apiKey, signal, ...rest }) {
110
125
  throw new AnthropicError(`No chunks received. Response: ${JSON.stringify(responseJson)}`, response, responseJson);
111
126
  }
112
127
  }
113
- export async function callMessageApi({ apiKey, signal, tools, ...rest }) {
128
+ export async function callMessageApi({ apiEndpoint, apiKey, signal, tools, beta, ...rest }) {
114
129
  const defaultSignal = new AbortController().signal;
115
- const response = await fetch('https://api.anthropic.com/v1/messages', {
130
+ const response = await fetch(`${apiEndpoint}/messages`, {
116
131
  method: 'POST',
117
132
  headers: {
118
133
  'Content-Type': 'application/json',
119
134
  'x-api-key': apiKey,
120
135
  'anthropic-version': '2023-06-01',
121
- 'anthropic-beta': tools ? 'tools-2024-04-04' : 'messages-2023-12-15',
136
+ 'anthropic-dangerous-direct-browser-access': 'true',
137
+ ...(beta ? { 'anthropic-beta': beta } : {}),
122
138
  },
123
139
  body: JSON.stringify({
124
140
  ...rest,
@@ -133,16 +149,17 @@ export async function callMessageApi({ apiKey, signal, tools, ...rest }) {
133
149
  }
134
150
  return responseJson;
135
151
  }
136
- export async function* streamMessageApi({ apiKey, signal, ...rest }) {
152
+ export async function* streamMessageApi({ apiEndpoint, apiKey, signal, beta, ...rest }) {
137
153
  // Use the Messages API for Claude 3 models
138
154
  const defaultSignal = new AbortController().signal;
139
- const response = await fetchEventSource('https://api.anthropic.com/v1/messages', {
155
+ const response = await fetchEventSource(`${apiEndpoint}/messages`, {
140
156
  method: 'POST',
141
157
  headers: {
142
158
  'Content-Type': 'application/json',
143
159
  'x-api-key': apiKey,
144
160
  'anthropic-version': '2023-06-01',
145
- 'anthropic-beta': 'messages-2023-12-15',
161
+ 'anthropic-dangerous-direct-browser-access': 'true',
162
+ ...(beta ? { 'anthropic-beta': beta } : {}),
146
163
  },
147
164
  body: JSON.stringify({
148
165
  ...rest,
@@ -151,14 +168,12 @@ export async function* streamMessageApi({ apiKey, signal, ...rest }) {
151
168
  signal: signal ?? defaultSignal,
152
169
  });
153
170
  let hadChunks = false;
154
- let nextDataType;
155
171
  for await (const chunk of response.events()) {
156
172
  hadChunks = true;
157
173
  if (chunk === '[message_stop]') {
158
174
  return;
159
175
  }
160
- else if (/\[\w+\]/.test(chunk)) {
161
- nextDataType = chunk.slice(1, -1);
176
+ else if (/^\[\w+\]$/.test(chunk)) {
162
177
  continue;
163
178
  }
164
179
  let data;
@@ -1,3 +1,4 @@
1
+ import { DEFAULT_CHAT_NODE_TIMEOUT } from '../../utils/defaults.js';
1
2
  // https://github.com/openai/openai-node/issues/18#issuecomment-1518715285
2
3
  export class EventSourceResponse extends Response {
3
4
  name;
@@ -24,7 +25,7 @@ export class EventSourceResponse extends Response {
24
25
  const reader = this.streams.eventStream.getReader();
25
26
  try {
26
27
  while (true) {
27
- const { done, value } = await this.raceWithTimeout(reader.read());
28
+ const { done, value } = await this.raceWithTimeout(reader.read(), DEFAULT_CHAT_NODE_TIMEOUT);
28
29
  if (done) {
29
30
  break;
30
31
  }
@@ -36,7 +37,7 @@ export class EventSourceResponse extends Response {
36
37
  }
37
38
  }
38
39
  async raceWithTimeout(promise, timeout = 5000) {
39
- // eslint-disable-next-line no-async-promise-executor -- Error handled correctly
40
+ // eslint-disable-next-line no-async-promise-executor,@typescript-eslint/no-misused-promises -- Error handled correctly
40
41
  return new Promise(async (resolve, reject) => {
41
42
  const timer = setTimeout(() => {
42
43
  reject(new Error('Timeout: API response took too long.'));