From 83225c1ff8c7377764b3ddf0ed251383e39ef6db Mon Sep 17 00:00:00 2001 From: Zhang Yi Jiang Date: Wed, 11 Dec 2024 12:00:04 -0800 Subject: [PATCH 1/7] Add Lint and Prettier check to CI --- .github/workflows/build.yml | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index cd6720165..815ebb9ab 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -23,3 +23,7 @@ jobs: NODE_OPTIONS: --max_old_space_size=6000 - name: Test run: yarn test + - name: Lint + run: yarn lint + - name: Prettier + run: yarn prettier --check From 00d357bb01e4f91bc985637bdad750987ae0fcbd Mon Sep 17 00:00:00 2001 From: Zhang Yi Jiang Date: Wed, 11 Dec 2024 13:50:15 -0800 Subject: [PATCH 2/7] Fix top level lint config --- .eslintrc.cjs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.eslintrc.cjs b/.eslintrc.cjs index 6d2204373..e73c68e31 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -4,7 +4,7 @@ module.exports = { es2021: true, }, root: true, - extends: ['standard-with-typescript', 'plugin:react/recommended'], + extends: ['standard-with-typescript'], plugins: ['import', '@typescript-eslint'], overrides: [ { From 9ebfd0c016c418a64c6e75a412d73d0545c62ed9 Mon Sep 17 00:00:00 2001 From: Zhang Yi Jiang Date: Wed, 11 Dec 2024 13:58:24 -0800 Subject: [PATCH 3/7] Lint autofix and ignores --- packages/core/src/model/nodes/CallGraphNode.ts | 2 +- packages/core/src/model/nodes/ExtractJsonNode.ts | 8 ++++---- packages/core/src/model/nodes/HttpCallNode.ts | 2 ++ .../core/src/plugins/anthropic/nodes/ChatAnthropicNode.ts | 6 +++--- packages/core/src/plugins/google/google.ts | 3 ++- .../core/src/plugins/pinecone/PineconeVectorDatabase.ts | 5 ++--- 6 files changed, 14 insertions(+), 12 deletions(-) diff --git a/packages/core/src/model/nodes/CallGraphNode.ts b/packages/core/src/model/nodes/CallGraphNode.ts index f5a5ed381..d6b1a56bf 100644 --- a/packages/core/src/model/nodes/CallGraphNode.ts +++ b/packages/core/src/model/nodes/CallGraphNode.ts @@ -122,7 +122,7 @@ export class CallGraphNodeImpl extends NodeImpl { const subGraphProcessor = context.createSubProcessor(graphRef.graphId, { signal: context.signal }); - let outputs: Outputs = {}; + const outputs: Outputs = {}; try { const startTime = Date.now(); diff --git a/packages/core/src/model/nodes/ExtractJsonNode.ts b/packages/core/src/model/nodes/ExtractJsonNode.ts index d14a0a590..0abbbed8e 100644 --- a/packages/core/src/model/nodes/ExtractJsonNode.ts +++ b/packages/core/src/model/nodes/ExtractJsonNode.ts @@ -94,10 +94,10 @@ export class ExtractJsonNodeImpl extends NodeImpl { // Find the first { or [ and the last } or ], and try parsing everything in between including them. - let firstBracket = inputString.indexOf('{'); - let lastBracket = inputString.lastIndexOf('}'); - let firstSquareBracket = inputString.indexOf('['); - let lastSquareBracket = inputString.lastIndexOf(']'); + const firstBracket = inputString.indexOf('{'); + const lastBracket = inputString.lastIndexOf('}'); + const firstSquareBracket = inputString.indexOf('['); + const lastSquareBracket = inputString.lastIndexOf(']'); const firstIndex = firstBracket >= 0 && firstSquareBracket >= 0 diff --git a/packages/core/src/model/nodes/HttpCallNode.ts b/packages/core/src/model/nodes/HttpCallNode.ts index 9fe70d87a..272b63288 100644 --- a/packages/core/src/model/nodes/HttpCallNode.ts +++ b/packages/core/src/model/nodes/HttpCallNode.ts @@ -211,7 +211,9 @@ export class HttpCallNodeImpl extends NodeImpl { const method = getInputOrData(this.data, inputs, 'method', 'string'); const url = getInputOrData(this.data, inputs, 'url', 'string'); + // TODO: Use URL.canParse when we drop support for Node 18 try { + // eslint-disable-next-line no-new new URL(url); } catch (err) { throw new Error(`Invalid URL: ${url}`); diff --git a/packages/core/src/plugins/anthropic/nodes/ChatAnthropicNode.ts b/packages/core/src/plugins/anthropic/nodes/ChatAnthropicNode.ts index 63a36ce1b..549702ac3 100644 --- a/packages/core/src/plugins/anthropic/nodes/ChatAnthropicNode.ts +++ b/packages/core/src/plugins/anthropic/nodes/ChatAnthropicNode.ts @@ -420,7 +420,7 @@ export const ChatAnthropicNodeImpl: PluginNodeImpl = { top_p: useTopP ? topP : undefined, max_tokens: maxTokens ?? modelInfo.maxTokens, stop_sequences: stop ? [stop] : undefined, - system: system, + system, messages, tools: tools ? tools.map((tool) => ({ name: tool.name, description: tool.description, input_schema: tool.parameters })) @@ -507,8 +507,8 @@ export const ChatAnthropicNodeImpl: PluginNodeImpl = { // Process the response chunks and update the output const responseParts: string[] = []; - let requestTokens: number | undefined = undefined, - responseTokens: number | undefined = undefined; + let requestTokens: number | undefined = undefined; + let responseTokens: number | undefined = undefined; for await (const chunk of chunks) { let completion: string = ''; if (chunk.type === 'content_block_start') { diff --git a/packages/core/src/plugins/google/google.ts b/packages/core/src/plugins/google/google.ts index 20b31fa09..e8cd35e35 100644 --- a/packages/core/src/plugins/google/google.ts +++ b/packages/core/src/plugins/google/google.ts @@ -74,6 +74,7 @@ export type ChatCompletionChunk = { model: string; }; +/* eslint-disable @typescript-eslint/naming-convention */ export async function* streamChatCompletions({ project, location, @@ -92,7 +93,7 @@ export async function* streamChatCompletions({ const { VertexAI } = await import('@google-cloud/vertexai'); // Can't find a way to pass the credentials path in - process.env['GOOGLE_APPLICATION_CREDENTIALS'] = applicationCredentials; + process.env.GOOGLE_APPLICATION_CREDENTIALS = applicationCredentials; const vertexAi = new VertexAI({ project, location }); const generativeModel = vertexAi.preview.getGenerativeModel({ model, diff --git a/packages/core/src/plugins/pinecone/PineconeVectorDatabase.ts b/packages/core/src/plugins/pinecone/PineconeVectorDatabase.ts index cd3d382bf..a2bc57623 100644 --- a/packages/core/src/plugins/pinecone/PineconeVectorDatabase.ts +++ b/packages/core/src/plugins/pinecone/PineconeVectorDatabase.ts @@ -23,11 +23,10 @@ export class PineconeVectorDatabase implements VectorDatabase { id = CryptoJS.SHA256(vector.value.join(',')).toString(CryptoJS.enc.Hex); } - let metadata: Record = {} + let metadata: Record = {}; if (data.type === 'object') { metadata = data.value; - } - else { + } else { metadata = { data: data.value }; } From 49358f0807f743bc9dcb494d8c6345498510713a Mon Sep 17 00:00:00 2001 From: Zhang Yi Jiang Date: Wed, 11 Dec 2024 14:19:39 -0800 Subject: [PATCH 4/7] Fix circular imports --- packages/core/src/model/GraphProcessor.ts | 2 +- packages/core/src/model/Nodes.ts | 4 ---- packages/core/src/model/nodes/CallGraphNode.ts | 5 ++--- .../core/src/plugins/anthropic/nodes/ChatAnthropicNode.ts | 4 ++-- packages/core/src/plugins/google/nodes/ChatGoogleNode.ts | 2 +- packages/core/src/plugins/openai/nodes/RunThreadNode.ts | 6 +----- 6 files changed, 7 insertions(+), 16 deletions(-) diff --git a/packages/core/src/model/GraphProcessor.ts b/packages/core/src/model/GraphProcessor.ts index 6fa6fe604..d7acb3d08 100644 --- a/packages/core/src/model/GraphProcessor.ts +++ b/packages/core/src/model/GraphProcessor.ts @@ -919,7 +919,7 @@ export class GraphProcessor { if (this.runToNodeIds) { const dependencyNodes = this.getDependencyNodesDeep(node.id); - if (this.runToNodeIds.some((runTo) => runTo != node.id && dependencyNodes.includes(runTo))) { + if (this.runToNodeIds.some((runTo) => runTo !== node.id && dependencyNodes.includes(runTo))) { this.#emitter.emit('trace', `Node ${node.title} is excluded due to runToNodeIds`); return; } diff --git a/packages/core/src/model/Nodes.ts b/packages/core/src/model/Nodes.ts index 4e2993b66..821fc56f5 100644 --- a/packages/core/src/model/Nodes.ts +++ b/packages/core/src/model/Nodes.ts @@ -1,6 +1,4 @@ -import type { ChartNode } from './NodeBase.js'; import { NodeRegistration } from './NodeRegistration.js'; -import type { NodeImpl } from './NodeImpl.js'; import { userInputNode } from './nodes/UserInputNode.js'; export * from './nodes/UserInputNode.js'; @@ -218,8 +216,6 @@ export * from './nodes/DelegateFunctionCallNode.js'; import { playAudioNode } from './nodes/PlayAudioNode.js'; export * from './nodes/PlayAudioNode.js'; -export * from './nodes/CallGraphNode.js'; - export const registerBuiltInNodes = (registry: NodeRegistration) => { return registry .register(toYamlNode) diff --git a/packages/core/src/model/nodes/CallGraphNode.ts b/packages/core/src/model/nodes/CallGraphNode.ts index d6b1a56bf..4e9f53ff1 100644 --- a/packages/core/src/model/nodes/CallGraphNode.ts +++ b/packages/core/src/model/nodes/CallGraphNode.ts @@ -8,12 +8,11 @@ import { import { NodeImpl, type NodeUIData } from '../NodeImpl.js'; import { nodeDefinition } from '../NodeDefinition.js'; import { type Inputs, type Outputs } from '../GraphProcessor.js'; -import { type GraphId } from '../NodeGraph.js'; import { nanoid } from 'nanoid/non-secure'; import { type InternalProcessContext } from '../ProcessContext.js'; import { dedent } from 'ts-dedent'; -import { coerceType, coerceTypeOptional } from '../../utils/coerceType.js'; -import { looseDataValuesToDataValues, type LooseDataValue } from '../../index.js'; +import { coerceTypeOptional } from '../../utils/coerceType.js'; +import { looseDataValuesToDataValues, type LooseDataValue } from '../../api/createProcessor.js'; import { getError } from '../../utils/errors.js'; export type CallGraphNode = ChartNode<'callGraph', CallGraphNodeData>; diff --git a/packages/core/src/plugins/anthropic/nodes/ChatAnthropicNode.ts b/packages/core/src/plugins/anthropic/nodes/ChatAnthropicNode.ts index 549702ac3..7a6f1dcaf 100644 --- a/packages/core/src/plugins/anthropic/nodes/ChatAnthropicNode.ts +++ b/packages/core/src/plugins/anthropic/nodes/ChatAnthropicNode.ts @@ -1,5 +1,4 @@ import { - uint8ArrayToBase64, type ChartNode, type ChatMessage, type EditorDefinition, @@ -42,6 +41,7 @@ import { getScalarTypeOf, isArrayDataValue } from '../../../model/DataValue.js'; import type { TokenizerCallInfo } from '../../../integrations/Tokenizer.js'; import { assertNever } from '../../../utils/assertNever.js'; import { isNotNull } from '../../../utils/genericUtilFunctions.js'; +import { uint8ArrayToBase64 } from '../../../utils/base64.js'; export type ChatAnthropicNode = ChartNode<'chatAnthropic', ChatAnthropicNodeData>; @@ -508,7 +508,7 @@ export const ChatAnthropicNodeImpl: PluginNodeImpl = { // Process the response chunks and update the output const responseParts: string[] = []; let requestTokens: number | undefined = undefined; - let responseTokens: number | undefined = undefined; + let responseTokens: number | undefined = undefined; for await (const chunk of chunks) { let completion: string = ''; if (chunk.type === 'content_block_start') { diff --git a/packages/core/src/plugins/google/nodes/ChatGoogleNode.ts b/packages/core/src/plugins/google/nodes/ChatGoogleNode.ts index 2ba1a9c13..f26855017 100644 --- a/packages/core/src/plugins/google/nodes/ChatGoogleNode.ts +++ b/packages/core/src/plugins/google/nodes/ChatGoogleNode.ts @@ -1,5 +1,4 @@ import { - uint8ArrayToBase64, type ChartNode, type ChatMessage, type EditorDefinition, @@ -29,6 +28,7 @@ import { match } from 'ts-pattern'; import { coerceType, coerceTypeOptional } from '../../../utils/coerceType.js'; import { addWarning } from '../../../utils/outputs.js'; import { getError } from '../../../utils/errors.js'; +import { uint8ArrayToBase64 } from '../../../utils/base64.js'; import { pluginNodeDefinition } from '../../../model/NodeDefinition.js'; import { getScalarTypeOf, isArrayDataValue } from '../../../model/DataValue.js'; import type { TokenizerCallInfo } from '../../../integrations/Tokenizer.js'; diff --git a/packages/core/src/plugins/openai/nodes/RunThreadNode.ts b/packages/core/src/plugins/openai/nodes/RunThreadNode.ts index 29ceb5c09..b3e06cc61 100644 --- a/packages/core/src/plugins/openai/nodes/RunThreadNode.ts +++ b/packages/core/src/plugins/openai/nodes/RunThreadNode.ts @@ -8,10 +8,6 @@ import { type GptFunction, type GraphId, type GraphInputs, - type ScalarDataValue, - isArrayDataValue, - arrayizeDataValue, - unwrapDataValue, } from '../../../index.js'; import { openAiModelOptions, @@ -25,10 +21,10 @@ import { type OpenAIThreadMessage, } from '../../../utils/openai.js'; import { dedent, newId, coerceTypeOptional, getInputOrData } from '../../../utils/index.js'; +import { arrayizeDataValue, unwrapDataValue } from '../../../model/DataValue.js'; import { pluginNodeDefinition } from '../../../model/NodeDefinition.js'; import { handleOpenAIError } from '../handleOpenaiError.js'; import { type DataValue } from '../../../model/DataValue.js'; -import { match } from 'ts-pattern'; export type RunThreadNode = ChartNode<'openaiRunThread', RunThreadNodeData>; From 13c5f9ed4c9a85fa3191cd192426af9f28f989a8 Mon Sep 17 00:00:00 2001 From: Zhang Yi Jiang Date: Wed, 11 Dec 2024 14:53:36 -0800 Subject: [PATCH 5/7] Downgrade no-cycle to warn temporarily --- .eslintrc.cjs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.eslintrc.cjs b/.eslintrc.cjs index e73c68e31..8dfba6fd6 100644 --- a/.eslintrc.cjs +++ b/.eslintrc.cjs @@ -52,7 +52,8 @@ module.exports = { 'prefer-const': 'error', 'eol-last': 'off', 'import/no-duplicates': 'error', - 'import/no-cycle': 'error', + // TODO: Enable after fixing cycle in CallGraphNode -> globalRivetNodeRegistry + 'import/no-cycle': 'warn', 'no-extra-boolean-cast': 'off', 'no-prototype-builtins': 'off', 'no-undef-init': 'off', From 6ad9528e98b90f84bea9ab4d2f566372ada2cee4 Mon Sep 17 00:00:00 2001 From: Zhang Yi Jiang Date: Wed, 11 Dec 2024 15:06:33 -0800 Subject: [PATCH 6/7] Fix lint command in cli --- .pnp.cjs | 38 ++------------------------------------ packages/cli/.eslintrc.cjs | 2 +- packages/cli/package.json | 1 + yarn.lock | 1 + 4 files changed, 5 insertions(+), 37 deletions(-) diff --git a/.pnp.cjs b/.pnp.cjs index d1c32b985..89de913be 100755 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -6730,8 +6730,9 @@ const RAW_RUNTIME_STATE = ["@ironclad/rivet-cli", "workspace:packages/cli"],\ ["@ironclad/rivet-node", "workspace:packages/node"],\ ["@types/yargs", "npm:17.0.29"],\ + ["@typescript-eslint/eslint-plugin", "virtual:388c29633752d7c364e0487c276ae72861ce5d69c069bff16a49b35801303d87d39cb24723bbac1721c48df59f346575324fe3c6de8ead4fb7d83d6ae4a0e521#npm:6.9.0"],\ ["eslint", "npm:8.52.0"],\ - ["eslint-config-standard-with-typescript", "virtual:bbd91125264a56425cb84647dbdb3897ebf3aa2cdf8c02bff68076c228ddd912fb3bb6659c03fbe9e3e3898d8847f372ce79bb07d1395c306ae5ef774f9a7fa3#npm:39.1.1"],\ + ["eslint-config-standard-with-typescript", "virtual:388c29633752d7c364e0487c276ae72861ce5d69c069bff16a49b35801303d87d39cb24723bbac1721c48df59f346575324fe3c6de8ead4fb7d83d6ae4a0e521#npm:39.1.1"],\ ["eslint-plugin-import", "virtual:388c29633752d7c364e0487c276ae72861ce5d69c069bff16a49b35801303d87d39cb24723bbac1721c48df59f346575324fe3c6de8ead4fb7d83d6ae4a0e521#npm:2.29.0"],\ ["eslint-plugin-n", "virtual:388c29633752d7c364e0487c276ae72861ce5d69c069bff16a49b35801303d87d39cb24723bbac1721c48df59f346575324fe3c6de8ead4fb7d83d6ae4a0e521#npm:16.2.0"],\ ["eslint-plugin-promise", "virtual:388c29633752d7c364e0487c276ae72861ce5d69c069bff16a49b35801303d87d39cb24723bbac1721c48df59f346575324fe3c6de8ead4fb7d83d6ae4a0e521#npm:6.1.1"],\ @@ -14719,41 +14720,6 @@ const RAW_RUNTIME_STATE = ],\ "linkType": "HARD"\ }],\ - ["virtual:bbd91125264a56425cb84647dbdb3897ebf3aa2cdf8c02bff68076c228ddd912fb3bb6659c03fbe9e3e3898d8847f372ce79bb07d1395c306ae5ef774f9a7fa3#npm:39.1.1", {\ - "packageLocation": "./.yarn/__virtual__/eslint-config-standard-with-typescript-virtual-dbb4c907a2/0/cache/eslint-config-standard-with-typescript-npm-39.1.1-ff5efff6e8-75b5e29b1e.zip/node_modules/eslint-config-standard-with-typescript/",\ - "packageDependencies": [\ - ["eslint-config-standard-with-typescript", "virtual:bbd91125264a56425cb84647dbdb3897ebf3aa2cdf8c02bff68076c228ddd912fb3bb6659c03fbe9e3e3898d8847f372ce79bb07d1395c306ae5ef774f9a7fa3#npm:39.1.1"],\ - ["@types/eslint", null],\ - ["@types/eslint-plugin-import", null],\ - ["@types/eslint-plugin-n", null],\ - ["@types/eslint-plugin-promise", null],\ - ["@types/typescript", null],\ - ["@types/typescript-eslint__eslint-plugin", null],\ - ["@typescript-eslint/eslint-plugin", null],\ - ["@typescript-eslint/parser", "virtual:ce0a1a3dc1d2c68486e45f658daa2797aed508b6c7f8165837d04e87640f4a86cc4ae6e30f0913571707a77e538d32fd97db17859e4991b7ed430142d73bec3b#npm:6.9.1"],\ - ["eslint", "npm:8.52.0"],\ - ["eslint-config-standard", "virtual:ce0a1a3dc1d2c68486e45f658daa2797aed508b6c7f8165837d04e87640f4a86cc4ae6e30f0913571707a77e538d32fd97db17859e4991b7ed430142d73bec3b#npm:17.1.0"],\ - ["eslint-plugin-import", "virtual:388c29633752d7c364e0487c276ae72861ce5d69c069bff16a49b35801303d87d39cb24723bbac1721c48df59f346575324fe3c6de8ead4fb7d83d6ae4a0e521#npm:2.29.0"],\ - ["eslint-plugin-n", "virtual:388c29633752d7c364e0487c276ae72861ce5d69c069bff16a49b35801303d87d39cb24723bbac1721c48df59f346575324fe3c6de8ead4fb7d83d6ae4a0e521#npm:16.2.0"],\ - ["eslint-plugin-promise", "virtual:388c29633752d7c364e0487c276ae72861ce5d69c069bff16a49b35801303d87d39cb24723bbac1721c48df59f346575324fe3c6de8ead4fb7d83d6ae4a0e521#npm:6.1.1"],\ - ["typescript", "patch:typescript@npm%3A5.2.2#optional!builtin::version=5.2.2&hash=f3b441"]\ - ],\ - "packagePeers": [\ - "@types/eslint-plugin-import",\ - "@types/eslint-plugin-n",\ - "@types/eslint-plugin-promise",\ - "@types/eslint",\ - "@types/typescript-eslint__eslint-plugin",\ - "@types/typescript",\ - "@typescript-eslint/eslint-plugin",\ - "eslint-plugin-import",\ - "eslint-plugin-n",\ - "eslint-plugin-promise",\ - "eslint",\ - "typescript"\ - ],\ - "linkType": "HARD"\ - }],\ ["virtual:f9fb339f6b948da33dabfb081667f976e95ec9e5a804a6ae723484b48758a3c6b4ae83d894110dcf0bece688b8e216d48353a446d7ad8694a8b19291cba8d0a8#npm:39.1.1", {\ "packageLocation": "./.yarn/__virtual__/eslint-config-standard-with-typescript-virtual-bc256cc5b9/0/cache/eslint-config-standard-with-typescript-npm-39.1.1-ff5efff6e8-75b5e29b1e.zip/node_modules/eslint-config-standard-with-typescript/",\ "packageDependencies": [\ diff --git a/packages/cli/.eslintrc.cjs b/packages/cli/.eslintrc.cjs index 8afe9c62d..252b10505 100644 --- a/packages/cli/.eslintrc.cjs +++ b/packages/cli/.eslintrc.cjs @@ -5,7 +5,7 @@ module.exports = { { files: ['*.ts', '*.tsx'], parserOptions: { - project: './packages/cli/tsconfig.json', + project: './tsconfig.json', ecmaVersion: 'latest', sourceType: 'module', }, diff --git a/packages/cli/package.json b/packages/cli/package.json index 58daa375c..ed3568ea3 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -26,6 +26,7 @@ }, "devDependencies": { "@types/yargs": "^17.0.29", + "@typescript-eslint/eslint-plugin": "^6.9.0", "eslint": "^8.52.0", "eslint-config-standard-with-typescript": "^39.1.1", "eslint-plugin-import": "^2.29.0", diff --git a/yarn.lock b/yarn.lock index 65d1d7659..3784309b9 100644 --- a/yarn.lock +++ b/yarn.lock @@ -3882,6 +3882,7 @@ __metadata: dependencies: "@ironclad/rivet-node": "workspace:^" "@types/yargs": "npm:^17.0.29" + "@typescript-eslint/eslint-plugin": "npm:^6.9.0" eslint: "npm:^8.52.0" eslint-config-standard-with-typescript: "npm:^39.1.1" eslint-plugin-import: "npm:^2.29.0" From a7e8c3957a17da680ada4830f8ed0f8fca6ed903 Mon Sep 17 00:00:00 2001 From: Zhang Yi Jiang Date: Wed, 11 Dec 2024 15:10:25 -0800 Subject: [PATCH 7/7] Run prettier --- packages/app/src/components/Port.tsx | 6 +- packages/cli/bin/cli.js | 189 +++++++++--------- .../openai/OpenAIEmbeddingGenerator.ts | 4 +- .../core/src/model/nodes/GetEmbeddingNode.ts | 4 +- 4 files changed, 108 insertions(+), 95 deletions(-) diff --git a/packages/app/src/components/Port.tsx b/packages/app/src/components/Port.tsx index 3ac6255d5..6c3e2cd81 100644 --- a/packages/app/src/components/Port.tsx +++ b/packages/app/src/components/Port.tsx @@ -116,7 +116,11 @@ export const Port: FC<{ > {canDragTo &&
}
-
+
{title}
diff --git a/packages/cli/bin/cli.js b/packages/cli/bin/cli.js index e207f1811..1b6ff6dd1 100644 --- a/packages/cli/bin/cli.js +++ b/packages/cli/bin/cli.js @@ -3,99 +3,108 @@ import { resolve } from 'node:path'; import yargs from 'yargs'; import { hideBin } from 'yargs/helpers'; await yargs(hideBin(process.argv)) - .command('run [graphName]', 'Run a graph in a project file, or the main graph if graphName is not specified.', (y) => y - .positional('projectFile', { - describe: 'The project file to run', - type: 'string', - demandOption: true, -}) - .positional('graphName', { - describe: 'The name of the graph to run', - type: 'string', -}) - .option('inputs-stdin', { - describe: 'Read inputs from stdin as JSON', - type: 'boolean', - default: false, -}) - .option('include-cost', { - describe: 'Include the total cost in the output', - type: 'boolean', - default: false, -}) - .option('context', { - describe: 'Adds a context value to the graph run', - type: 'string', - array: true, - default: [], -}) - .option('input', { - describe: 'Adds an input to the graph run', - type: 'string', - array: true, - default: [], -}), (args) => run(args)) - .demandCommand() - .parseAsync(); + .command( + 'run [graphName]', + 'Run a graph in a project file, or the main graph if graphName is not specified.', + (y) => + y + .positional('projectFile', { + describe: 'The project file to run', + type: 'string', + demandOption: true, + }) + .positional('graphName', { + describe: 'The name of the graph to run', + type: 'string', + }) + .option('inputs-stdin', { + describe: 'Read inputs from stdin as JSON', + type: 'boolean', + default: false, + }) + .option('include-cost', { + describe: 'Include the total cost in the output', + type: 'boolean', + default: false, + }) + .option('context', { + describe: 'Adds a context value to the graph run', + type: 'string', + array: true, + default: [], + }) + .option('input', { + describe: 'Adds an input to the graph run', + type: 'string', + array: true, + default: [], + }), + (args) => run(args), + ) + .demandCommand() + .parseAsync(); async function run(args) { - try { - const projectPath = resolve(process.cwd(), args.projectFile); - const project = await loadProjectFromFile(projectPath); - if (!args.graphName && !project.metadata.mainGraphId) { - const validGraphs = Object.values(project.graphs).map((graph) => [graph.metadata.id, graph.metadata.name]); - const validGraphNames = validGraphs.map(([id, name]) => `• "${name}" (${id})`); - console.error(`No graph name provided, and project does not specify a main graph. Valid graphs are: \n${validGraphNames.join('\n')}\n\n Use either the graph's name or its ID. For example, \`rivet run my-project.rivet-project my-graph\` or \`rivet run my-project.rivet-project 1234abcd\``); - process.exit(1); - } - let inputs = {}; - if (args.inputsStdin) { - // Read json from stdin - const stdin = process.stdin; - stdin.setEncoding('utf8'); - let input = ''; - for await (const chunk of stdin) { - input += chunk; - } - try { - inputs = JSON.parse(input); - } - catch (err) { - console.error('Failed to parse input JSON'); - console.error(err); - process.exit(1); - } - } - else { - inputs = Object.fromEntries(args.input.map((input) => { - const [key, value] = input.split('='); - if (!key || !value) { - console.error(`Invalid input value: ${input}`); - process.exit(1); - } - return [key, value]; - })); - } - const contextValues = Object.fromEntries(args.context.map((context) => { - const [key, value] = context.split('='); - if (!key || !value) { - console.error(`Invalid context value: ${context}`); - process.exit(1); - } - return [key, value]; - })); - const { run } = createProcessor(project, { - graph: args.graphName, - inputs, - context: contextValues, - }); - const outputs = await run(); - if (!args.includeCost) { - delete outputs.cost; - } - console.log(outputs); + try { + const projectPath = resolve(process.cwd(), args.projectFile); + const project = await loadProjectFromFile(projectPath); + if (!args.graphName && !project.metadata.mainGraphId) { + const validGraphs = Object.values(project.graphs).map((graph) => [graph.metadata.id, graph.metadata.name]); + const validGraphNames = validGraphs.map(([id, name]) => `• "${name}" (${id})`); + console.error( + `No graph name provided, and project does not specify a main graph. Valid graphs are: \n${validGraphNames.join('\n')}\n\n Use either the graph's name or its ID. For example, \`rivet run my-project.rivet-project my-graph\` or \`rivet run my-project.rivet-project 1234abcd\``, + ); + process.exit(1); } - catch (err) { + let inputs = {}; + if (args.inputsStdin) { + // Read json from stdin + const stdin = process.stdin; + stdin.setEncoding('utf8'); + let input = ''; + for await (const chunk of stdin) { + input += chunk; + } + try { + inputs = JSON.parse(input); + } catch (err) { + console.error('Failed to parse input JSON'); console.error(err); process.exit(1); + } + } else { + inputs = Object.fromEntries( + args.input.map((input) => { + const [key, value] = input.split('='); + if (!key || !value) { + console.error(`Invalid input value: ${input}`); + process.exit(1); + } + return [key, value]; + }), + ); + } + const contextValues = Object.fromEntries( + args.context.map((context) => { + const [key, value] = context.split('='); + if (!key || !value) { + console.error(`Invalid context value: ${context}`); + process.exit(1); + } + return [key, value]; + }), + ); + const { run } = createProcessor(project, { + graph: args.graphName, + inputs, + context: contextValues, + }); + const outputs = await run(); + if (!args.includeCost) { + delete outputs.cost; } + console.log(outputs); + } catch (err) { + console.error(err); + process.exit(1); + } } diff --git a/packages/core/src/integrations/openai/OpenAIEmbeddingGenerator.ts b/packages/core/src/integrations/openai/OpenAIEmbeddingGenerator.ts index 1e5c1e319..6989ec521 100644 --- a/packages/core/src/integrations/openai/OpenAIEmbeddingGenerator.ts +++ b/packages/core/src/integrations/openai/OpenAIEmbeddingGenerator.ts @@ -2,7 +2,7 @@ import { type Settings } from '../../index.js'; import { type EmbeddingGenerator } from '../EmbeddingGenerator.js'; import { OpenAI } from 'openai'; -type OpenAIOptions = Pick +type OpenAIOptions = Pick; export class OpenAIEmbeddingGenerator implements EmbeddingGenerator { readonly #settings; @@ -21,7 +21,7 @@ export class OpenAIEmbeddingGenerator implements EmbeddingGenerator { const response = await api.embeddings.create({ input: text, model: options?.model ?? 'text-embedding-ada-002', - dimensions: options?.dimensions + dimensions: options?.dimensions, }); const embeddings = response.data; diff --git a/packages/core/src/model/nodes/GetEmbeddingNode.ts b/packages/core/src/model/nodes/GetEmbeddingNode.ts index ac4e1ec1d..308bf05f5 100644 --- a/packages/core/src/model/nodes/GetEmbeddingNode.ts +++ b/packages/core/src/model/nodes/GetEmbeddingNode.ts @@ -37,7 +37,7 @@ export class GetEmbeddingNodeImpl extends NodeImpl { integration: 'openai', useIntegrationInput: false, model: undefined, - dimensions: undefined + dimensions: undefined, }, }; } @@ -141,7 +141,7 @@ export class GetEmbeddingNodeImpl extends NodeImpl { const integrationName = this.data.useIntegrationInput ? coerceType(inputs['integration' as PortId], 'string') : this.data.integration; - + const model = this.data.useModelInput ? coerceType(inputs['model' as PortId], 'string') : this.data.model; const dimensions = this.data.useDimensionsInput