From 11ed9f5af11fd079bbf20aab6e4de661418dc0be Mon Sep 17 00:00:00 2001 From: Valera Popov Date: Fri, 22 Aug 2025 03:58:52 +0400 Subject: [PATCH] Added external functions support into the Rivet app for debugging purposes --- .../components/editors/custom/AiAssistEditorBase.tsx | 2 +- packages/app/src/hooks/useAiGraphBuilder.ts | 2 +- packages/core/src/integrations/CodeRunner.ts | 10 ++++++++++ packages/core/src/model/GraphProcessor.ts | 2 +- packages/core/src/model/nodes/CodeNode.ts | 9 +++++++++ packages/docs/docs/node-reference/external-call.mdx | 8 +++++--- packages/node/src/native/NodeCodeRunner.ts | 9 ++++++++- 7 files changed, 35 insertions(+), 7 deletions(-) diff --git a/packages/app/src/components/editors/custom/AiAssistEditorBase.tsx b/packages/app/src/components/editors/custom/AiAssistEditorBase.tsx index fe840dbc6..fe8be6bd1 100644 --- a/packages/app/src/components/editors/custom/AiAssistEditorBase.tsx +++ b/packages/app/src/components/editors/custom/AiAssistEditorBase.tsx @@ -100,7 +100,7 @@ export const AiAssistEditorBase = ({ model: model!, api: api!, }, - registry, + registry: registry as unknown as NodeRegistration, ...(await fillMissingSettingsFromEnvironmentVariables(settings, plugins)), }); diff --git a/packages/app/src/hooks/useAiGraphBuilder.ts b/packages/app/src/hooks/useAiGraphBuilder.ts index 7a59a2b06..23520b531 100644 --- a/packages/app/src/hooks/useAiGraphBuilder.ts +++ b/packages/app/src/hooks/useAiGraphBuilder.ts @@ -495,7 +495,7 @@ export function useAiGraphBuilder({ record, onFeedback }: { record: boolean; onF onUserEvent, nativeApi: new TauriNativeApi(), datasetProvider: new InMemoryDatasetProvider(data), - registry, + registry: registry as unknown as NodeRegistration, ...(await fillMissingSettingsFromEnvironmentVariables(settings, plugins)), }); diff --git a/packages/core/src/integrations/CodeRunner.ts b/packages/core/src/integrations/CodeRunner.ts index 3d9c849c9..3ff8cb8bc 100644 --- a/packages/core/src/integrations/CodeRunner.ts +++ b/packages/core/src/integrations/CodeRunner.ts @@ -1,5 +1,6 @@ import type { Inputs, Outputs } from '../index.js'; import type { DataValue } from '../model/DataValue.js'; +import type { InternalProcessContext } from '../model/ProcessContext.js'; // eslint-disable-next-line import/no-cycle -- There has to be a cycle if we're to import the entirety of Rivet here. import * as Rivet from '../exports.js'; @@ -8,6 +9,7 @@ export interface CodeRunnerOptions { includeRequire: boolean; includeFetch: boolean; includeRivet: boolean; + includeInternalProcessContext: boolean; includeProcess: boolean; includeConsole: boolean; } @@ -18,6 +20,7 @@ export interface CodeRunner { code: string, inputs: Inputs, options: CodeRunnerOptions, + context: InternalProcessContext, graphInputs?: Record, contextValues?: Record ) => Promise; @@ -28,6 +31,7 @@ export class IsomorphicCodeRunner implements CodeRunner { code: string, inputs: Inputs, options: CodeRunnerOptions, + context: InternalProcessContext, graphInputs?: Record, contextValues?: Record ): Promise { @@ -57,6 +61,11 @@ export class IsomorphicCodeRunner implements CodeRunner { args.push(Rivet); } + if (options.includeInternalProcessContext) { + argNames.push('internalProcessContext'); + args.push(context); + } + if (graphInputs) { argNames.push('graphInputs'); args.push(graphInputs); @@ -82,6 +91,7 @@ export class NotAllowedCodeRunner implements CodeRunner { _code: string, _inputs: Inputs, _options: CodeRunnerOptions, + _context: InternalProcessContext, _graphInputs?: Record, _contextValues?: Record ): Promise { diff --git a/packages/core/src/model/GraphProcessor.ts b/packages/core/src/model/GraphProcessor.ts index ffac44951..56b84bacb 100644 --- a/packages/core/src/model/GraphProcessor.ts +++ b/packages/core/src/model/GraphProcessor.ts @@ -1530,7 +1530,7 @@ export class GraphProcessor { this.getRootProcessor().raiseEvent(event, data as DataValue); }, contextValues: this.#contextValues, - externalFunctions: { ...this.#externalFunctions }, + externalFunctions: this.#externalFunctions, onPartialOutputs: (partialOutputs) => { partialOutput?.(node, partialOutputs, index); diff --git a/packages/core/src/model/nodes/CodeNode.ts b/packages/core/src/model/nodes/CodeNode.ts index 09c54bfdc..92f1e8d5e 100644 --- a/packages/core/src/model/nodes/CodeNode.ts +++ b/packages/core/src/model/nodes/CodeNode.ts @@ -26,6 +26,7 @@ export type CodeNodeData = { allowFetch?: boolean; allowRequire?: boolean; allowRivet?: boolean; + allowInternalProcessContext?: boolean; allowProcess?: boolean; allowConsole?: boolean; }; @@ -58,6 +59,7 @@ export class CodeNodeImpl extends NodeImpl { allowFetch: false, allowRequire: false, allowRivet: false, + allowInternalProcessContext: false, allowProcess: false, allowConsole: false, }, @@ -139,6 +141,11 @@ export class CodeNodeImpl extends NodeImpl { label: 'Allow using `Rivet`', dataKey: 'allowRivet', }, + { + type: 'toggle', + label: 'Allow using `internalProcessContext`', + dataKey: 'allowInternalProcessContext', + }, { type: 'toggle', label: 'Allow using `process`', @@ -189,9 +196,11 @@ export class CodeNodeImpl extends NodeImpl { includeFetch: this.data.allowFetch ?? false, includeRequire: this.data.allowRequire ?? false, includeRivet: this.data.allowRivet ?? false, + includeInternalProcessContext: this.data.allowInternalProcessContext ?? false, includeProcess: this.data.allowProcess ?? false, includeConsole: this.data.allowConsole ?? false, }, + context, context.graphInputNodeValues, context.contextValues ); diff --git a/packages/docs/docs/node-reference/external-call.mdx b/packages/docs/docs/node-reference/external-call.mdx index 35a6bbdc1..1f71821f5 100644 --- a/packages/docs/docs/node-reference/external-call.mdx +++ b/packages/docs/docs/node-reference/external-call.mdx @@ -19,7 +19,7 @@ import { runGraphInFile } from '@ironclad/rivet-node'; await runGraphInFile({ ...etc, externalFunctions: { - sum: (...args) => { + sum: (context, ...args) => { return { type: 'number', value: args.reduce((acc, curr) => acc + curr, 0); @@ -38,7 +38,7 @@ External functions are useful for many use-cases, they can do things like: - Get user information about who is running the graph - Anything else you can think of! -External functions are extremely powerful. They can only be used when running Rivet from a host application, and are not available when running Rivet in the Rivet applicaton. The external function nodes will error when running in the Rivet application. Use [Remote Debugging](../user-guide/remote-debugging.md) to run External Call nodes in the Rivet application. +External functions are extremely powerful. They can be used when running Rivet from a host application, and are not normally available when running Rivet in the Rivet applicaton (see "FAQ"). Use [Remote Debugging](../user-guide/remote-debugging.md) to run External Call nodes in the Rivet application. , - contextValues?: Record, + contextValues?: Record ): Promise { const argNames = ['inputs']; const args: any[] = [inputs]; @@ -41,6 +43,11 @@ export class NodeCodeRunner implements CodeRunner { args.push(Rivet); } + if (options.includeInternalProcessContext) { + argNames.push('internalProcessContext'); + args.push(context); + } + if (graphInputs) { argNames.push('graphInputs'); args.push(graphInputs);