From 14ab6333ff1f14b129370f99bfb8b11c6a5a65e7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Aur=C3=A9lien?= Date: Thu, 7 Sep 2023 13:17:01 +0200 Subject: [PATCH] add globals, fix openai temp, remove parameters --- .gitignore | 3 + .../src/engines/dataflow/constants.ts | 21 ++++++- .../src/engines/dataflow/runFlow.test.ts | 1 - .../ps-chains/src/engines/dataflow/runFlow.ts | 5 +- .../src/engines/dataflow/updateNodeInput.ts | 2 +- .../dataflow/utils/resolveVariables.test.ts | 63 ++++++++++++++++++- .../dataflow/utils/resolveVariables.ts | 24 +++---- .../dataflow/utils/sanitizeInput.test.ts | 19 ++++++ .../engines/dataflow/utils/sanitizeInput.ts | 14 +++++ .../src/engines/dataflow/utils/utils.ts | 2 +- packages/@pufflig/ps-chains/src/index.ts | 2 + .../@pufflig/ps-chains/src/mocks/chains.ts | 39 ------------ .../@pufflig/ps-chains/src/mocks/nodes.ts | 11 +--- packages/@pufflig/ps-chains/src/types.ts | 1 + .../src/utils/chainToReactFlow.ts | 2 +- .../adapters/custom_api/custom_api_chat.ts | 1 - .../custom_api/custom_api_completion.ts | 1 - .../ps-nodes-config/src/adapters/index.ts | 2 + .../src/adapters/openai/openai_chat.ts | 11 +--- .../src/adapters/openai/openai_completion.ts | 11 +--- .../src/adapters/openai/openai_embedding.ts | 11 +--- .../src/adapters/openai/openai_models.ts | 16 ++--- .../src/adapters/openai/openai_settings.ts | 4 +- .../ps-nodes-config/src/core/forin.ts | 1 - .../ps-nodes-config/src/core/input.ts | 1 - .../ps-nodes-config/src/core/output.ts | 1 - .../src/data/message/message.ts | 1 - .../ps-nodes-config/src/data/object/object.ts | 1 - .../ps-nodes-config/src/data/text/text.ts | 1 - .../@pufflig/ps-nodes-config/src/index.ts | 5 ++ .../src/modifiers/append_to/append_to_chat.ts | 1 - .../handlebar_template_chat.ts | 1 - .../handlebar_template_completion.ts | 1 - .../src/adapters/openai/openai_chat.ts | 13 ++-- .../src/adapters/openai/openai_completion.ts | 12 ++-- .../src/adapters/openai/openai_embedding.ts | 11 ++-- .../handlebar_template_chat.test.ts | 40 ++++++------ .../handlebar_template_chat.ts | 7 ++- .../handlebar_template_completion.test.ts | 40 ++++++------ .../handlebar_template_completion.ts | 10 ++- packages/@pufflig/ps-types/src/types/nodes.ts | 15 +++-- websites/docs/pages/api/run-flow.md | 4 +- websites/docs/pages/changelog.md | 12 +++- 43 files changed, 258 insertions(+), 186 deletions(-) create mode 100644 packages/@pufflig/ps-chains/src/engines/dataflow/utils/sanitizeInput.test.ts create mode 100644 packages/@pufflig/ps-chains/src/engines/dataflow/utils/sanitizeInput.ts diff --git a/.gitignore b/.gitignore index d0912a7..288ef9b 100644 --- a/.gitignore +++ b/.gitignore @@ -132,3 +132,6 @@ dist .yarn/build-state.yml .yarn/install-state.gz .pnp.* + +# docusaurus +build \ No newline at end of file diff --git a/packages/@pufflig/ps-chains/src/engines/dataflow/constants.ts b/packages/@pufflig/ps-chains/src/engines/dataflow/constants.ts index 3a486c7..3ec20f2 100644 --- a/packages/@pufflig/ps-chains/src/engines/dataflow/constants.ts +++ b/packages/@pufflig/ps-chains/src/engines/dataflow/constants.ts @@ -1,12 +1,27 @@ -import { NextNode, Node, ParamValueMap } from "@pufflig/ps-types"; +import { Execute, GetTargets, NextNode, Node, ParamValueMap } from "@pufflig/ps-types"; export const delimiterStart = "${{ps:ref:" as const; export const delimiterEnd = "}}" as const; export const executionPrefix = "exec:"; -export const identity = (i: ParamValueMap, _: Partial) => i; +/** + * Placeholder function for executing a node. + * Simply returns the nodes inputs. + * @param input + * @param _ + * @returns + */ +export const identity: Execute = async (input, _) => input; + +/** + * Given a node, returns the default targets for the node. + * The default target is the first executable output. + * @param node + * @returns + */ export const getDefaultTargets = - (node: Node) => (_input: ParamValueMap, _prev: ParamValueMap, results: ParamValueMap) => { + (node: Node): GetTargets => + async (_, results) => { if (!node.execution?.outputs?.[0]?.id) return []; return [ { diff --git a/packages/@pufflig/ps-chains/src/engines/dataflow/runFlow.test.ts b/packages/@pufflig/ps-chains/src/engines/dataflow/runFlow.test.ts index 910ed09..fbdbef6 100644 --- a/packages/@pufflig/ps-chains/src/engines/dataflow/runFlow.test.ts +++ b/packages/@pufflig/ps-chains/src/engines/dataflow/runFlow.test.ts @@ -458,7 +458,6 @@ test("a node can run its children multiple times 2", async () => { "n1", {}, { - logLevel: "debug", onNodeRunComplete, onNodeInputUpdate, onNodeRunError, diff --git a/packages/@pufflig/ps-chains/src/engines/dataflow/runFlow.ts b/packages/@pufflig/ps-chains/src/engines/dataflow/runFlow.ts index 6993197..12b2d32 100644 --- a/packages/@pufflig/ps-chains/src/engines/dataflow/runFlow.ts +++ b/packages/@pufflig/ps-chains/src/engines/dataflow/runFlow.ts @@ -91,7 +91,8 @@ export async function runFlow(flow: Flow, nodeId: string, input: Record | null = null; try { // resolve references in the input - result = await execute(resolvedInput, previousState.input); + const nodeOptions = { prevInput: previousState.input, globals: runOptions?.globals || {} }; + result = await execute(resolvedInput, nodeOptions); runOptions?.onNodeRunComplete?.(nodeId, result); logger.debug({ nodeId, result }, "Node run complete"); // track the run @@ -147,7 +148,7 @@ export async function runFlow(flow: Flow, nodeId: string, input: Record edge.sourceHandle.startsWith(executionPrefix) && edge.source === nodeId ); diff --git a/packages/@pufflig/ps-chains/src/engines/dataflow/updateNodeInput.ts b/packages/@pufflig/ps-chains/src/engines/dataflow/updateNodeInput.ts index 360d7c3..7d75270 100644 --- a/packages/@pufflig/ps-chains/src/engines/dataflow/updateNodeInput.ts +++ b/packages/@pufflig/ps-chains/src/engines/dataflow/updateNodeInput.ts @@ -30,7 +30,7 @@ export async function updateNodeInput( // parse the input const nodeState = flowState[nodeId]; const prevInput = nodeState?.input; - const parsedInput = await mapInput(input, prevInput); + const parsedInput = await mapInput(input, { prevInput, globals: runOptions?.globals }); // compile the new state of the node const newInput = { ...applyDefaultInputs(prevInput, nodeDefinition), ...parsedInput }; diff --git a/packages/@pufflig/ps-chains/src/engines/dataflow/utils/resolveVariables.test.ts b/packages/@pufflig/ps-chains/src/engines/dataflow/utils/resolveVariables.test.ts index 31e6024..5bdb35a 100644 --- a/packages/@pufflig/ps-chains/src/engines/dataflow/utils/resolveVariables.test.ts +++ b/packages/@pufflig/ps-chains/src/engines/dataflow/utils/resolveVariables.test.ts @@ -1,6 +1,6 @@ import { resolveVariables } from "./resolveVariables"; -test.only("resolveVariables - extract variables", async () => { +test("resolveVariables - extract variables", async () => { const resolver = jest.fn(async (variableName) => { return `RESOLVED_WITH_${variableName}`; }); @@ -32,3 +32,64 @@ test.only("resolveVariables - extract variables", async () => { } `); }); + +test("resolveVariables - handles special chars", async () => { + const resolver = jest.fn(async (variableName) => { + return `RESOLVED_WITH_${variableName} + + "I'm on a separate line" + +`; + }); + + expect( + await resolveVariables( + { + "param-1": "not_a_variable", + "param-2": "${{ps:ref:variable-1}}", + "param-3": "${{ps:ref:variable-2}}", + "param-4": "{{}}", + "param-5": "${{ps:ref:variable-1}} ${{ps:ref:variable-2}}", + "param-6": "{{dont_replace}} ${{ps:ref:variable-2}}", + "param-7": "{{faulty}", + "param-8": "{{faulty} ${{ps:ref:variable-2}}", + }, + resolver + ) + ).toMatchInlineSnapshot(` + { + "param-1": "not_a_variable", + "param-2": "RESOLVED_WITH_variable-1 + + "I'm on a separate line" + + ", + "param-3": "RESOLVED_WITH_variable-2 + + "I'm on a separate line" + + ", + "param-4": "{{}}", + "param-5": "RESOLVED_WITH_variable-1 + + "I'm on a separate line" + + RESOLVED_WITH_variable-2 + + "I'm on a separate line" + + ", + "param-6": "{{dont_replace}} RESOLVED_WITH_variable-2 + + "I'm on a separate line" + + ", + "param-7": "{{faulty}", + "param-8": "{{faulty} RESOLVED_WITH_variable-2 + + "I'm on a separate line" + + ", + } + `); +}); diff --git a/packages/@pufflig/ps-chains/src/engines/dataflow/utils/resolveVariables.ts b/packages/@pufflig/ps-chains/src/engines/dataflow/utils/resolveVariables.ts index 8a2a764..2c06e45 100644 --- a/packages/@pufflig/ps-chains/src/engines/dataflow/utils/resolveVariables.ts +++ b/packages/@pufflig/ps-chains/src/engines/dataflow/utils/resolveVariables.ts @@ -1,5 +1,4 @@ import { ParamValue } from "@pufflig/ps-types"; -import Mustache from "mustache"; import { delimiterEnd, delimiterStart } from "../constants"; import { extractVariables } from "./extractVariables"; @@ -24,15 +23,18 @@ export const resolveVariables = async ( vars.forEach((variable) => promises.push(resolver(variable))); const resolvedVariables = await Promise.all(promises); - // map of variables with resolved variables - const variablesMap = vars.reduce((acc, variable, index) => { - acc[variable] = resolvedVariables[index]; - return acc; - }, {} as Record); + // replace variables with resolved variables, text might contain special characters + const result = vars.reduce((acc, name, index) => { + const regexString = "\\" + delimiterStart + name + delimiterEnd; + const regex = new RegExp(regexString, "g"); + const value = resolvedVariables[index]; + return Object.entries(acc).reduce((acc2, [key, val]) => { + return { + ...acc2, + [key]: typeof val === "string" ? val?.replace(regex, value) : val, + }; + }, {} as Record); + }, input); - // insert resolved variables into input - const newInput: Record = JSON.parse( - Mustache.render(JSON.stringify(input), variablesMap, {}, [delimiterStart, delimiterEnd]) - ); - return newInput; + return result; }; diff --git a/packages/@pufflig/ps-chains/src/engines/dataflow/utils/sanitizeInput.test.ts b/packages/@pufflig/ps-chains/src/engines/dataflow/utils/sanitizeInput.test.ts new file mode 100644 index 0000000..70fd25b --- /dev/null +++ b/packages/@pufflig/ps-chains/src/engines/dataflow/utils/sanitizeInput.test.ts @@ -0,0 +1,19 @@ +import { sanitizeInput } from "./sanitizeInput"; + +test("sanitizeInput - remove variables", async () => { + const variables = await sanitizeInput({ + "param-1": "not_a_variable", + "param-2": "${{ps:ref:variable-1}}", + "param-3": "${{ps:ref:variable-2}", + "param-4": "${{variable-4}}", + }); + + expect(variables).toMatchInlineSnapshot(` + { + "param-1": "not_a_variable", + "param-2": "", + "param-3": "\${{ps:ref:variable-2}", + "param-4": "\${{variable-4}}", + } + `); +}); diff --git a/packages/@pufflig/ps-chains/src/engines/dataflow/utils/sanitizeInput.ts b/packages/@pufflig/ps-chains/src/engines/dataflow/utils/sanitizeInput.ts new file mode 100644 index 0000000..40f09e0 --- /dev/null +++ b/packages/@pufflig/ps-chains/src/engines/dataflow/utils/sanitizeInput.ts @@ -0,0 +1,14 @@ +import { ParamValue } from "@pufflig/ps-types"; +import { resolveVariables } from "./resolveVariables"; + +/** + * Remove all variables from an input object + * + * @param input + * @returns + */ +export const sanitizeInput = (input: Record) => { + return resolveVariables(input, async () => { + return ""; + }); +}; diff --git a/packages/@pufflig/ps-chains/src/engines/dataflow/utils/utils.ts b/packages/@pufflig/ps-chains/src/engines/dataflow/utils/utils.ts index 4c6de1b..18a22ab 100644 --- a/packages/@pufflig/ps-chains/src/engines/dataflow/utils/utils.ts +++ b/packages/@pufflig/ps-chains/src/engines/dataflow/utils/utils.ts @@ -21,7 +21,7 @@ export function paramToDefaults(params: Param[]) { * @returns node state with default values */ export function applyDefaultInputs(nodeStateData: Record | undefined, node: NodeConfig) { - const inputs = [...node.inputs, ...node.parameters]; + const inputs = [...node.inputs]; const defaults = paramToDefaults(inputs); return { ...defaults, ...(nodeStateData || {}) }; } diff --git a/packages/@pufflig/ps-chains/src/index.ts b/packages/@pufflig/ps-chains/src/index.ts index 76ca80e..e0ce071 100644 --- a/packages/@pufflig/ps-chains/src/index.ts +++ b/packages/@pufflig/ps-chains/src/index.ts @@ -1,3 +1,5 @@ export { runFlow } from "./engines/dataflow/runFlow"; export { updateNodeInput } from "./engines/dataflow/updateNodeInput"; export * from "./types"; +export { resolveVariables } from "./engines/dataflow/utils/resolveVariables"; +export { sanitizeInput } from "./engines/dataflow/utils/sanitizeInput"; diff --git a/packages/@pufflig/ps-chains/src/mocks/chains.ts b/packages/@pufflig/ps-chains/src/mocks/chains.ts index af5da6e..faae81b 100644 --- a/packages/@pufflig/ps-chains/src/mocks/chains.ts +++ b/packages/@pufflig/ps-chains/src/mocks/chains.ts @@ -18,9 +18,6 @@ export const singleNodeFlow: Flow = { n1: { id: "n1", type: "simple_node", - editor: { - position: { x: 0, y: 0 }, - }, }, }, }, @@ -42,9 +39,6 @@ export const configOnlyFlow: Flow = { n1: { id: "n1", type: "simple_node", - editor: { - position: { x: 0, y: 0 }, - }, }, }, }, @@ -74,16 +68,10 @@ export const simpleFlow: Flow = { n1: { id: "n1", type: "simple_node", - editor: { - position: { x: 0, y: 0 }, - }, }, n2: { id: "n2", type: "simple_node", - editor: { - position: { x: 0, y: 0 }, - }, }, }, }, @@ -108,9 +96,6 @@ export const simpleLoop: Flow = { n1: { id: "n1", type: "simple_node", - editor: { - position: { x: 0, y: 0 }, - }, }, }, }, @@ -164,23 +149,14 @@ export const mappedExample: Flow = { n1: { id: "n1", type: "simple_node", - editor: { - position: { x: 0, y: 0 }, - }, }, n2: { id: "n2", type: "multi_input", - editor: { - position: { x: 0, y: 0 }, - }, }, n3: { id: "n3", type: "simple_node", - editor: { - position: { x: 0, y: 0 }, - }, }, }, }, @@ -444,16 +420,10 @@ export const simpleFlowWithVars: Flow = { n1: { id: "n1", type: "simple_node", - editor: { - position: { x: 0, y: 0 }, - }, }, n2: { id: "n2", type: "simple_node", - editor: { - position: { x: 0, y: 0 }, - }, }, }, }, @@ -492,23 +462,14 @@ export const simpleFlowWithExec: Flow = { n1: { id: "n1", type: "simple_node", - editor: { - position: { x: 0, y: 0 }, - }, }, n2: { id: "n2", type: "simple_node", - editor: { - position: { x: 0, y: 0 }, - }, }, n3: { id: "n3", type: "simple_node", - editor: { - position: { x: 0, y: 0 }, - }, }, }, }, diff --git a/packages/@pufflig/ps-chains/src/mocks/nodes.ts b/packages/@pufflig/ps-chains/src/mocks/nodes.ts index dbdf4b9..811523e 100644 --- a/packages/@pufflig/ps-chains/src/mocks/nodes.ts +++ b/packages/@pufflig/ps-chains/src/mocks/nodes.ts @@ -16,14 +16,13 @@ export const loopNode: NodeActions = { }; export const joinNode: NodeActions<{ data: string; list: string[] }> = { - mapInput: async ({ data }, prev) => { - return { list: [...(prev?.list || []), data] }; + mapInput: async ({ data }, options) => { + return { list: [...(options?.prevInput?.list || []), data] }; }, }; export const simpleDataNode: Node = { name: "simpleNode", - parameters: [], inputs: [ { name: "data", @@ -47,7 +46,6 @@ export const simpleDataNode: Node = { export const configOnlyNode: Node = { name: "simpleNode", - parameters: [], inputs: [ { name: "data", @@ -70,7 +68,6 @@ export const configOnlyNode: Node = { export const multiInputDataNode: Node = { name: "multiInputNode", - parameters: [], inputs: [ { name: "data1", @@ -101,7 +98,6 @@ export const multiInputDataNode: Node = { export const multiOutputDataNode: Node = { name: "multiOutputNode", - parameters: [], inputs: [ { name: "input1", @@ -145,7 +141,6 @@ export const simpleExecNode: Node = { }, ], }, - parameters: [], inputs: [ { name: "data", @@ -181,7 +176,6 @@ export const loopNodeConfig: Node = { }, ], }, - parameters: [], inputs: [ { name: "list", @@ -217,7 +211,6 @@ export const joinNodeConfig: Node = { }, ], }, - parameters: [], inputs: [ { name: "data", diff --git a/packages/@pufflig/ps-chains/src/types.ts b/packages/@pufflig/ps-chains/src/types.ts index 304664d..d15b01a 100644 --- a/packages/@pufflig/ps-chains/src/types.ts +++ b/packages/@pufflig/ps-chains/src/types.ts @@ -41,6 +41,7 @@ export interface NodeState { export interface RunOptions { mode?: "dataflow" | "controlflow"; logLevel?: "debug" | "error"; + globals?: Record; resolveReferences?: (variable: string) => Promise; onNodeInputUpdate?: (id: string, input: NodeState) => void; onNodeRunError?: (id: string, error: Error) => void; diff --git a/packages/@pufflig/ps-node-editor/src/utils/chainToReactFlow.ts b/packages/@pufflig/ps-node-editor/src/utils/chainToReactFlow.ts index a7b7463..c7c1728 100644 --- a/packages/@pufflig/ps-node-editor/src/utils/chainToReactFlow.ts +++ b/packages/@pufflig/ps-node-editor/src/utils/chainToReactFlow.ts @@ -69,7 +69,7 @@ export const chainToReactFlow = (chain: Flow): ReactFlowData => { data: { type: node.type, label: nodeDefinition.name, - parameters: isCoreNode ? coreParameters : nodeDefinition.parameters, + parameters: coreParameters, inputs: inputs, outputs: outputs, }, diff --git a/packages/@pufflig/ps-nodes-config/src/adapters/custom_api/custom_api_chat.ts b/packages/@pufflig/ps-nodes-config/src/adapters/custom_api/custom_api_chat.ts index ff61c51..a1a6b06 100644 --- a/packages/@pufflig/ps-nodes-config/src/adapters/custom_api/custom_api_chat.ts +++ b/packages/@pufflig/ps-nodes-config/src/adapters/custom_api/custom_api_chat.ts @@ -17,7 +17,6 @@ export const customChatConfig: NodeConfig = { }, ], }, - parameters: [], outputs: [ { id: "message", diff --git a/packages/@pufflig/ps-nodes-config/src/adapters/custom_api/custom_api_completion.ts b/packages/@pufflig/ps-nodes-config/src/adapters/custom_api/custom_api_completion.ts index 6f732fa..b07c9d3 100644 --- a/packages/@pufflig/ps-nodes-config/src/adapters/custom_api/custom_api_completion.ts +++ b/packages/@pufflig/ps-nodes-config/src/adapters/custom_api/custom_api_completion.ts @@ -17,7 +17,6 @@ export const customCompletionConfig: NodeConfig = { }, ], }, - parameters: [], outputs: [ { id: "completion", diff --git a/packages/@pufflig/ps-nodes-config/src/adapters/index.ts b/packages/@pufflig/ps-nodes-config/src/adapters/index.ts index 7553afa..d48e8c0 100644 --- a/packages/@pufflig/ps-nodes-config/src/adapters/index.ts +++ b/packages/@pufflig/ps-nodes-config/src/adapters/index.ts @@ -29,3 +29,5 @@ export const modelConfig = { export const adapterNodeTypes = { openaiEmbeddingNodeType, }; + + diff --git a/packages/@pufflig/ps-nodes-config/src/adapters/openai/openai_chat.ts b/packages/@pufflig/ps-nodes-config/src/adapters/openai/openai_chat.ts index 6b12911..8b9c4e5 100644 --- a/packages/@pufflig/ps-nodes-config/src/adapters/openai/openai_chat.ts +++ b/packages/@pufflig/ps-nodes-config/src/adapters/openai/openai_chat.ts @@ -1,10 +1,12 @@ import { NodeConfig } from "@pufflig/ps-types"; import { chatModels } from "./openai_models"; +import { OPENAI_API_KEY } from "./openai_settings"; export const openaiChatConfig: NodeConfig = { name: "OpenAI (Chat)", description: "OpenAI Chat", tags: ["adapter", "chat"], + globals: [OPENAI_API_KEY], execution: { inputs: [ { @@ -18,15 +20,6 @@ export const openaiChatConfig: NodeConfig = { }, ], }, - parameters: [ - { - id: "api_key", - name: "API Key", - type: "secret", - description: "The API key for OpenAI", - defaultValue: "${{ps:ref:secret:openai/api_key}}", - }, - ], outputs: [ { id: "message", diff --git a/packages/@pufflig/ps-nodes-config/src/adapters/openai/openai_completion.ts b/packages/@pufflig/ps-nodes-config/src/adapters/openai/openai_completion.ts index 620f6cc..12062fd 100644 --- a/packages/@pufflig/ps-nodes-config/src/adapters/openai/openai_completion.ts +++ b/packages/@pufflig/ps-nodes-config/src/adapters/openai/openai_completion.ts @@ -1,10 +1,12 @@ import { NodeConfig } from "@pufflig/ps-types"; import { completionModels } from "./openai_models"; +import { OPENAI_API_KEY } from "./openai_settings"; export const openaiCompletionConfig: NodeConfig = { name: "OpenAI (Completion)", description: "OpenAI Completion", tags: ["adapter", "text"], + globals: [OPENAI_API_KEY], execution: { inputs: [ { @@ -18,15 +20,6 @@ export const openaiCompletionConfig: NodeConfig = { }, ], }, - parameters: [ - { - id: "api_key", - name: "API Key", - type: "secret", - description: "The API key for OpenAI", - defaultValue: "${{ps:ref:secret:openai/api_key}}", - }, - ], outputs: [ { id: "completion", diff --git a/packages/@pufflig/ps-nodes-config/src/adapters/openai/openai_embedding.ts b/packages/@pufflig/ps-nodes-config/src/adapters/openai/openai_embedding.ts index 5ea1cf7..bccf717 100644 --- a/packages/@pufflig/ps-nodes-config/src/adapters/openai/openai_embedding.ts +++ b/packages/@pufflig/ps-nodes-config/src/adapters/openai/openai_embedding.ts @@ -1,5 +1,6 @@ import { NodeConfig } from "@pufflig/ps-types"; import { embeddingModels } from "./openai_models"; +import { OPENAI_API_KEY } from "./openai_settings"; export const openaiEmbeddingNodeType = "adapter/openai_embedding" as const; @@ -7,6 +8,7 @@ export const openaiEmbeddingConfig: NodeConfig = { name: "OpenAI (Embedding)", description: "OpenAI Embedding", tags: ["adapter", "embedding"], + globals: [OPENAI_API_KEY], execution: { inputs: [ { @@ -20,15 +22,6 @@ export const openaiEmbeddingConfig: NodeConfig = { }, ], }, - parameters: [ - { - id: "api_key", - name: "API Key", - type: "secret", - description: "The API key for OpenAI", - defaultValue: "${{ps:ref:secret:openai/api_key}}", - }, - ], outputs: [ { id: "embedding", diff --git a/packages/@pufflig/ps-nodes-config/src/adapters/openai/openai_models.ts b/packages/@pufflig/ps-nodes-config/src/adapters/openai/openai_models.ts index dd303a1..f71dba9 100644 --- a/packages/@pufflig/ps-nodes-config/src/adapters/openai/openai_models.ts +++ b/packages/@pufflig/ps-nodes-config/src/adapters/openai/openai_models.ts @@ -8,7 +8,7 @@ export const chatModels: ModelDefinition = { id: "temperature", type: "number", name: "Temperature", - max: 1, + max: 2, min: 0, step: 0.1, defaultValue: 0.4, @@ -66,7 +66,7 @@ export const chatModels: ModelDefinition = { id: "temperature", type: "number", name: "Temperature", - max: 1, + max: 2, min: 0, step: 0.1, defaultValue: 0.4, @@ -124,7 +124,7 @@ export const chatModels: ModelDefinition = { id: "temperature", type: "number", name: "Temperature", - max: 1, + max: 2, min: 0, step: 0.1, defaultValue: 0.4, @@ -182,7 +182,7 @@ export const chatModels: ModelDefinition = { id: "temperature", type: "number", name: "Temperature", - max: 1, + max: 2, min: 0, step: 0.1, defaultValue: 0.4, @@ -243,7 +243,7 @@ export const completionModels: ModelDefinition = { id: "temperature", type: "number", name: "Temperature", - max: 1, + max: 2, min: 0, step: 0.1, defaultValue: 0.4, @@ -301,7 +301,7 @@ export const completionModels: ModelDefinition = { id: "temperature", type: "number", name: "Temperature", - max: 1, + max: 2, min: 0, step: 0.1, defaultValue: 0.4, @@ -359,7 +359,7 @@ export const completionModels: ModelDefinition = { id: "temperature", type: "number", name: "Temperature", - max: 1, + max: 2, min: 0, step: 0.1, defaultValue: 0.4, @@ -417,7 +417,7 @@ export const completionModels: ModelDefinition = { id: "temperature", type: "number", name: "Temperature", - max: 1, + max: 2, min: 0, step: 0.1, defaultValue: 0.4, diff --git a/packages/@pufflig/ps-nodes-config/src/adapters/openai/openai_settings.ts b/packages/@pufflig/ps-nodes-config/src/adapters/openai/openai_settings.ts index 28c5f3a..8ae1992 100644 --- a/packages/@pufflig/ps-nodes-config/src/adapters/openai/openai_settings.ts +++ b/packages/@pufflig/ps-nodes-config/src/adapters/openai/openai_settings.ts @@ -1,10 +1,12 @@ import { UserSettings } from "../../types"; +export const OPENAI_API_KEY = "openai/api_key"; + export const openAISettings: UserSettings = { name: "OpenAI", description: "OpenAI Settings", settings: { - ["openai/api_key"]: { + [OPENAI_API_KEY]: { name: "API Key", description: "Your OpenAI API key", type: "secret", diff --git a/packages/@pufflig/ps-nodes-config/src/core/forin.ts b/packages/@pufflig/ps-nodes-config/src/core/forin.ts index 485bb5d..5d8d019 100644 --- a/packages/@pufflig/ps-nodes-config/src/core/forin.ts +++ b/packages/@pufflig/ps-nodes-config/src/core/forin.ts @@ -23,7 +23,6 @@ export const forinNodeConfig: NodeConfig = { }, ], }, - parameters: [], outputs: [ { id: "item", diff --git a/packages/@pufflig/ps-nodes-config/src/core/input.ts b/packages/@pufflig/ps-nodes-config/src/core/input.ts index 2792765..c2d9eab 100644 --- a/packages/@pufflig/ps-nodes-config/src/core/input.ts +++ b/packages/@pufflig/ps-nodes-config/src/core/input.ts @@ -15,7 +15,6 @@ export const inputNodeConfig: NodeConfig = { ], }, customSchema: "output", - parameters: [], outputs: [], inputs: [], }; diff --git a/packages/@pufflig/ps-nodes-config/src/core/output.ts b/packages/@pufflig/ps-nodes-config/src/core/output.ts index 4f2a48f..773e1d3 100644 --- a/packages/@pufflig/ps-nodes-config/src/core/output.ts +++ b/packages/@pufflig/ps-nodes-config/src/core/output.ts @@ -15,7 +15,6 @@ export const outputNodeConfig: NodeConfig = { outputs: [], }, customSchema: "input", - parameters: [], outputs: [], inputs: [], }; diff --git a/packages/@pufflig/ps-nodes-config/src/data/message/message.ts b/packages/@pufflig/ps-nodes-config/src/data/message/message.ts index 1cf1770..be125ce 100644 --- a/packages/@pufflig/ps-nodes-config/src/data/message/message.ts +++ b/packages/@pufflig/ps-nodes-config/src/data/message/message.ts @@ -6,7 +6,6 @@ export const message: NodeConfig = { name: "Message", description: "", tags: ["data", "message"], - parameters: [], outputs: [ { id: "message", diff --git a/packages/@pufflig/ps-nodes-config/src/data/object/object.ts b/packages/@pufflig/ps-nodes-config/src/data/object/object.ts index eea39a6..b9b7857 100644 --- a/packages/@pufflig/ps-nodes-config/src/data/object/object.ts +++ b/packages/@pufflig/ps-nodes-config/src/data/object/object.ts @@ -6,7 +6,6 @@ export const objectNode: NodeConfig = { name: "Object", description: "Map various input into an object", tags: ["data", "text"], - parameters: [], customSchema: "input", inputs: [], outputs: [ diff --git a/packages/@pufflig/ps-nodes-config/src/data/text/text.ts b/packages/@pufflig/ps-nodes-config/src/data/text/text.ts index 41a8b0b..790d62a 100644 --- a/packages/@pufflig/ps-nodes-config/src/data/text/text.ts +++ b/packages/@pufflig/ps-nodes-config/src/data/text/text.ts @@ -6,7 +6,6 @@ export const text: NodeConfig = { name: "Text", description: "Text data", tags: ["data", "text"], - parameters: [], outputs: [ { id: "text", diff --git a/packages/@pufflig/ps-nodes-config/src/index.ts b/packages/@pufflig/ps-nodes-config/src/index.ts index 9d1296f..b459de5 100644 --- a/packages/@pufflig/ps-nodes-config/src/index.ts +++ b/packages/@pufflig/ps-nodes-config/src/index.ts @@ -1,4 +1,5 @@ import { adapterNodeTypes, adapterNodes, adapterSettings, modelConfig } from "./adapters"; +import { OPENAI_API_KEY } from "./adapters/openai/openai_settings"; import { coreNodeTypes, coreNodes } from "./core"; import { dataNodeTypes, dataNodes } from "./data"; import { modifierNodes } from "./modifiers"; @@ -19,6 +20,10 @@ export const userSettings = { ...adapterSettings, }; +export const secretId = { + OPENAI_API_KEY, +}; + export const models = { ...modelConfig, }; diff --git a/packages/@pufflig/ps-nodes-config/src/modifiers/append_to/append_to_chat.ts b/packages/@pufflig/ps-nodes-config/src/modifiers/append_to/append_to_chat.ts index 7a014b6..3eeb2a4 100644 --- a/packages/@pufflig/ps-nodes-config/src/modifiers/append_to/append_to_chat.ts +++ b/packages/@pufflig/ps-nodes-config/src/modifiers/append_to/append_to_chat.ts @@ -4,7 +4,6 @@ export const appendToChat: NodeConfig = { name: "Append To (Chat)", description: "Append a message to a chat", tags: ["modifier", "chat"], - parameters: [], outputs: [ { id: "chat", diff --git a/packages/@pufflig/ps-nodes-config/src/modifiers/handlebar_template/handlebar_template_chat.ts b/packages/@pufflig/ps-nodes-config/src/modifiers/handlebar_template/handlebar_template_chat.ts index 4f7fe18..868bf14 100644 --- a/packages/@pufflig/ps-nodes-config/src/modifiers/handlebar_template/handlebar_template_chat.ts +++ b/packages/@pufflig/ps-nodes-config/src/modifiers/handlebar_template/handlebar_template_chat.ts @@ -4,7 +4,6 @@ export const handlebarTemplateChat: NodeConfig = { name: "Handlebar Template (Chat)", description: "", tags: ["modifier", "chat"], - parameters: [], outputs: [ { id: "chat", diff --git a/packages/@pufflig/ps-nodes-config/src/modifiers/handlebar_template/handlebar_template_completion.ts b/packages/@pufflig/ps-nodes-config/src/modifiers/handlebar_template/handlebar_template_completion.ts index e7dc145..926016d 100644 --- a/packages/@pufflig/ps-nodes-config/src/modifiers/handlebar_template/handlebar_template_completion.ts +++ b/packages/@pufflig/ps-nodes-config/src/modifiers/handlebar_template/handlebar_template_completion.ts @@ -4,7 +4,6 @@ export const handlebarTemplateCompletion: NodeConfig = { name: "Handlebar Template (Completion)", description: "", tags: ["modifier", "text"], - parameters: [], outputs: [ { id: "text", diff --git a/packages/@pufflig/ps-nodes/src/adapters/openai/openai_chat.ts b/packages/@pufflig/ps-nodes/src/adapters/openai/openai_chat.ts index a2d631d..2c738a1 100644 --- a/packages/@pufflig/ps-nodes/src/adapters/openai/openai_chat.ts +++ b/packages/@pufflig/ps-nodes/src/adapters/openai/openai_chat.ts @@ -1,12 +1,11 @@ -import { nodes } from "@pufflig/ps-nodes-config"; -import { Chat, ChatMessage, ModelValue, Node, ParamValueMap } from "@pufflig/ps-types"; +import { nodes, secretId } from "@pufflig/ps-nodes-config"; +import { Chat, ChatMessage, Execute, ModelValue, Node, ParamValueMap } from "@pufflig/ps-types"; import { ChatCompletionRequestMessage, Configuration, OpenAIApi } from "openai"; import { v4 as uuid } from "uuid"; export const openaiChatNodeType = "adapter/openai_chat" as const; export interface OpenAIChatInput extends ParamValueMap { - api_key: string; chat: Chat; model: ModelValue; } @@ -15,11 +14,12 @@ export interface OpenAIChatOutput extends ParamValueMap { message: ChatMessage; } -export const execute = async (input: OpenAIChatInput) => { - const { chat, model, api_key } = input; +export const execute: Execute = async (input, options = {}) => { + const { chat, model } = input; const { modelId, parameters } = model; + const { globals } = options; - const configuration = new Configuration({ apiKey: api_key }); + const configuration = new Configuration({ apiKey: globals?.[secretId.OPENAI_API_KEY] }); const openai = new OpenAIApi(configuration); const params = { ...parameters, model: modelId }; @@ -27,6 +27,7 @@ export const execute = async (input: OpenAIChatInput) => { content: m.content, role: m.role, })); + const completion = await openai.createChatCompletion({ ...params, messages, functions: chat.functions }); const chatCompletion = completion.data.choices[0].message; diff --git a/packages/@pufflig/ps-nodes/src/adapters/openai/openai_completion.ts b/packages/@pufflig/ps-nodes/src/adapters/openai/openai_completion.ts index 6598d49..eb18740 100644 --- a/packages/@pufflig/ps-nodes/src/adapters/openai/openai_completion.ts +++ b/packages/@pufflig/ps-nodes/src/adapters/openai/openai_completion.ts @@ -1,11 +1,10 @@ -import { nodes } from "@pufflig/ps-nodes-config"; -import { ModelValue, Node, ParamValueMap } from "@pufflig/ps-types"; +import { nodes, secretId } from "@pufflig/ps-nodes-config"; +import { Execute, ModelValue, Node, ParamValueMap } from "@pufflig/ps-types"; import { Configuration, OpenAIApi } from "openai"; export const openaiCompletionNodeType = "adapter/openai_completion" as const; export interface OpenAICompletionInput { - api_key: string; prompt: string; model: ModelValue; } @@ -14,11 +13,12 @@ export interface OpenAICompletionOutput extends ParamValueMap { completion: string; } -export const execute = async (input: OpenAICompletionInput) => { - const { prompt, model, api_key } = input; +export const execute: Execute = async (input, options = {}) => { + const { prompt, model } = input; const { modelId, parameters } = model; + const { globals } = options; - const configuration = new Configuration({ apiKey: api_key }); + const configuration = new Configuration({ apiKey: globals?.[secretId.OPENAI_API_KEY] }); const openai = new OpenAIApi(configuration); const params = { ...parameters, model: modelId }; diff --git a/packages/@pufflig/ps-nodes/src/adapters/openai/openai_embedding.ts b/packages/@pufflig/ps-nodes/src/adapters/openai/openai_embedding.ts index a7e0237..a3ee736 100644 --- a/packages/@pufflig/ps-nodes/src/adapters/openai/openai_embedding.ts +++ b/packages/@pufflig/ps-nodes/src/adapters/openai/openai_embedding.ts @@ -1,5 +1,5 @@ -import { nodes, nodeTypes } from "@pufflig/ps-nodes-config"; -import { ModelValue, Node } from "@pufflig/ps-types"; +import { nodes, nodeTypes, secretId } from "@pufflig/ps-nodes-config"; +import { Execute, ModelValue, Node } from "@pufflig/ps-types"; import { Configuration, OpenAIApi } from "openai"; export interface OpenAIEmbeddingInput { @@ -12,10 +12,11 @@ export interface OpenAIEmbeddingOutput { embedding: number[]; } -export const execute = async (input: OpenAIEmbeddingInput) => { - const { model, api_key, text } = input as OpenAIEmbeddingInput; +export const execute: Execute = async (input, options = {}) => { + const { model, text } = input; + const { globals } = options; - const configuration = new Configuration({ apiKey: api_key }); + const configuration = new Configuration({ apiKey: globals?.[secretId.OPENAI_API_KEY] }); const openai = new OpenAIApi(configuration); const response = await openai.createEmbedding({ diff --git a/packages/@pufflig/ps-nodes/src/modifiers/handlebar_template/handlebar_template_chat.test.ts b/packages/@pufflig/ps-nodes/src/modifiers/handlebar_template/handlebar_template_chat.test.ts index cbb8dd0..151118c 100644 --- a/packages/@pufflig/ps-nodes/src/modifiers/handlebar_template/handlebar_template_chat.test.ts +++ b/packages/@pufflig/ps-nodes/src/modifiers/handlebar_template/handlebar_template_chat.test.ts @@ -194,15 +194,17 @@ test("mapInput - keep default values from the previous state", async () => { variables: [], }, { - variables: [ - { - id: "longText", - name: "longText", - type: "text", - defaultValue: "some long text", - description: "", - }, - ], + prevInput: { + variables: [ + { + id: "longText", + name: "longText", + type: "text", + defaultValue: "some long text", + description: "", + }, + ], + }, } ); expect(variables).toMatchInlineSnapshot(` @@ -256,15 +258,17 @@ test("mapInput - override values from the previous state with the new value", as ], }, { - variables: [ - { - id: "longText", - name: "longText", - type: "text", - defaultValue: "old long text", - description: "", - }, - ], + prevInput: { + variables: [ + { + id: "longText", + name: "longText", + type: "text", + defaultValue: "old long text", + description: "", + }, + ], + }, } ); expect(variables).toMatchInlineSnapshot(` diff --git a/packages/@pufflig/ps-nodes/src/modifiers/handlebar_template/handlebar_template_chat.ts b/packages/@pufflig/ps-nodes/src/modifiers/handlebar_template/handlebar_template_chat.ts index f3e96fb..d33ef18 100644 --- a/packages/@pufflig/ps-nodes/src/modifiers/handlebar_template/handlebar_template_chat.ts +++ b/packages/@pufflig/ps-nodes/src/modifiers/handlebar_template/handlebar_template_chat.ts @@ -1,5 +1,5 @@ import { nodes } from "@pufflig/ps-nodes-config"; -import { Chat, Node, NumberParam, ObjectDefinition, TextParam } from "@pufflig/ps-types"; +import { Chat, MapInput, Node, NumberParam, ObjectDefinition, TextParam } from "@pufflig/ps-types"; import _ from "lodash"; import Mustache from "mustache"; import { objectDefinitionToMap } from "../../utils/objectDefinitionToMap"; @@ -42,8 +42,9 @@ export const execute = async (input: HandlebarTemplateChatInput) => { * @param prev * @returns */ -export const mapInput = async (input: HandlebarTemplateChatInput, prev?: Partial) => { +export const mapInput: MapInput = async (input, options = {}) => { const { chat, variables } = input; + const { prevInput } = options; if (chat === undefined) { return input; @@ -69,7 +70,7 @@ export const mapInput = async (input: HandlebarTemplateChatInput, prev?: Partial if (uniqueVariables) { // extracted variables that already existed in the previous input are assigned the previous value const variablesObject = uniqueVariables.map((variable) => { - const prevVariable = (prev?.variables || []).find((v) => v.id === variable?.id); + const prevVariable = (prevInput?.variables || []).find((v) => v.id === variable?.id); if (prevVariable) { return { ...variable, diff --git a/packages/@pufflig/ps-nodes/src/modifiers/handlebar_template/handlebar_template_completion.test.ts b/packages/@pufflig/ps-nodes/src/modifiers/handlebar_template/handlebar_template_completion.test.ts index 873387c..9240f2e 100644 --- a/packages/@pufflig/ps-nodes/src/modifiers/handlebar_template/handlebar_template_completion.test.ts +++ b/packages/@pufflig/ps-nodes/src/modifiers/handlebar_template/handlebar_template_completion.test.ts @@ -89,15 +89,17 @@ test("mapInput - keep default values from the previous state", async () => { variables: [], }, { - variables: [ - { - id: "longText", - name: "longText", - type: "text", - defaultValue: "some long text", - description: "", - }, - ], + prevInput: { + variables: [ + { + id: "longText", + name: "longText", + type: "text", + defaultValue: "some long text", + description: "", + }, + ], + }, } ); expect(variables).toMatchInlineSnapshot(` @@ -131,15 +133,17 @@ test("mapInput - override values from the previous state with the new value", as ], }, { - variables: [ - { - id: "longText", - name: "longText", - type: "text", - defaultValue: "old long text", - description: "", - }, - ], + prevInput: { + variables: [ + { + id: "longText", + name: "longText", + type: "text", + defaultValue: "old long text", + description: "", + }, + ], + }, } ); expect(variables).toMatchInlineSnapshot(` diff --git a/packages/@pufflig/ps-nodes/src/modifiers/handlebar_template/handlebar_template_completion.ts b/packages/@pufflig/ps-nodes/src/modifiers/handlebar_template/handlebar_template_completion.ts index eb8e804..1f15f63 100644 --- a/packages/@pufflig/ps-nodes/src/modifiers/handlebar_template/handlebar_template_completion.ts +++ b/packages/@pufflig/ps-nodes/src/modifiers/handlebar_template/handlebar_template_completion.ts @@ -2,7 +2,7 @@ import _ from "lodash"; import Mustache from "mustache"; import { objectDefinitionToMap } from "../../utils/objectDefinitionToMap"; import { extractVariables } from "./utils/extractVariables"; -import { Node, ObjectDefinition } from "@pufflig/ps-types"; +import { MapInput, Node, ObjectDefinition } from "@pufflig/ps-types"; import { nodes } from "@pufflig/ps-nodes-config"; export const handlebarTemplateCompletionNodeType = "modifier/handlebar_template_completion"; @@ -32,11 +32,9 @@ export const execute = async (input: HandlebarTemplateCompletionInput) => { * @param prev * @returns */ -export const mapInput = async ( - input: HandlebarTemplateCompletionInput, - prev?: Partial -) => { +export const mapInput: MapInput = async (input, options = {}) => { const { template, variables } = input; + const { prevInput } = options; if (template === undefined) { return input; @@ -47,7 +45,7 @@ export const mapInput = async ( if (extractedVariables) { // extracted variables that already existed in the previous input are assigned the previous value const variablesObject = extractedVariables.map((variable) => { - const prevVariable = (prev?.variables || []).find((v) => v.id === variable.id); + const prevVariable = (prevInput?.variables || []).find((v) => v.id === variable.id); if (prevVariable) { return { ...variable, diff --git a/packages/@pufflig/ps-types/src/types/nodes.ts b/packages/@pufflig/ps-types/src/types/nodes.ts index f477a47..0752dc5 100644 --- a/packages/@pufflig/ps-types/src/types/nodes.ts +++ b/packages/@pufflig/ps-types/src/types/nodes.ts @@ -15,21 +15,26 @@ export interface NodeConfig { description?: string; tags?: string[]; customSchema?: "input" | "output" | "both"; + globals?: string[]; execution?: { inputs: Exec[]; outputs: Exec[]; }; - parameters: Param[]; inputs: Param[]; outputs: Param[]; } -export type Execute = (input: I, prevInput?: Partial) => Promise; -export type MapInput = (input: I, prevInput?: Partial) => Promise | null>; +export interface NodeOptions { + prevInput?: Partial; + globals?: Record; +} + +export type Execute = (input: I, options?: NodeOptions) => Promise; +export type MapInput = (input: I, options?: NodeOptions) => Promise | null>; export type GetTargets = ( input: I, - prevInput?: Partial, - result?: O + result?: O, + options?: NodeOptions ) => Promise>[]>; export interface NodeActions { diff --git a/websites/docs/pages/api/run-flow.md b/websites/docs/pages/api/run-flow.md index cb0e08a..20782c6 100644 --- a/websites/docs/pages/api/run-flow.md +++ b/websites/docs/pages/api/run-flow.md @@ -1,8 +1,8 @@ # Run a workflow -Run a workflow you created in Prompt Studio from within your application given some input values. This endpoint returns the results of the flow. You can retrieve the `version_id` of the workflow from the workflow editor. +Run a workflow you created in Prompt Studio from within your application given some input values. This endpoint returns the results of the flow. You can retrieve the `deployment_id` of the workflow from the workflow editor. -## `POST` `/v1/workflows/:version_id/run` +## `POST` `/v1/workflows/:deployment_id/run` diff --git a/websites/docs/pages/changelog.md b/websites/docs/pages/changelog.md index 36f78c3..de46c8d 100644 --- a/websites/docs/pages/changelog.md +++ b/websites/docs/pages/changelog.md @@ -9,7 +9,17 @@ head: # Changelog -**Note**: the API for the packages in this repo will be highly unstable until we reach v1.0.0" +**Note**: the API for the Prompt Studio packages will be changing rapidly until we reach v1.0.0" + +## 0.17.0 + +:warning: Breaking changes + +### Features + +- :warning: **API** [@pufflig/ps-chains] pass `NodeOptions` as parameter to the `execute`, `mapInput` and `getTarget` lifecycle methods. Node options now contains the `prevInput` value as well as `global` values. `global` values are variables common for the entire flow, they can be secrets or other references provided as part of the `runOptions`. +- :warning: **API** [@pufflig/ps-nodes-config] remove `parameters` field as it isn't needed. +- [@pufflig/ps-nodes-config] fix OpenAI model temperatures max ## 0.16.0