From 575016901cefa1cbdb5094999ddc33c4662b72bd Mon Sep 17 00:00:00 2001 From: snakajima Date: Wed, 8 May 2024 21:21:36 -0700 Subject: [PATCH 1/7] regex --- src/node.ts | 11 +++++++++ tests/graphai/test_params.ts | 47 ++++++++++++++++++++++++++++++++++++ 2 files changed, 58 insertions(+) create mode 100644 tests/graphai/test_params.ts diff --git a/src/node.ts b/src/node.ts index 35a62a9b6..1c2cd5d92 100644 --- a/src/node.ts +++ b/src/node.ts @@ -53,6 +53,7 @@ export class ComputedNode extends Node { public readonly graphId: string; public readonly isResult: boolean; public readonly params: NodeDataParams; // Agent-specific parameters + private readonly dynamicParams: Record; public readonly nestedGraph?: GraphData; public readonly retryLimit: number; public retryCount: number = 0; @@ -75,6 +76,16 @@ export class ComputedNode extends Node { super(nodeId, graph); this.graphId = graphId; this.params = data.params ?? {}; + const regex = /^\$\{(.+)\}$/; + this.dynamicParams = Object.keys(this.params).reduce((tmp:Record, key) => { + const value = this.params[key]; + const match = (typeof value === "string") ? value.match(regex) : null; + if (match) { + tmp[key] = parseNodeName(match[1]); + } + return tmp; + }, {}); + console.log("****", this.dynamicParams); this.nestedGraph = data.graph; if (typeof data.agent === "string") { this.agentId = data.agent; diff --git a/tests/graphai/test_params.ts b/tests/graphai/test_params.ts new file mode 100644 index 000000000..dabb15d71 --- /dev/null +++ b/tests/graphai/test_params.ts @@ -0,0 +1,47 @@ +import { AgentFunction } from "@/graphai"; +import { rejectTest, graphDataTestRunner } from "~/utils/runner"; +import { defaultTestAgents } from "@/utils/test_agents"; + +import test from "node:test"; +import assert from "node:assert"; + + +const testAgent: AgentFunction, string> = async () => { + return "test"; +}; + + +const graphData_literal = { + version: 0.2, + nodes: { + source: { + value: "apple", + }, + source2: { + value: { apple: "red" }, + }, + step1: { + agent: "stringTemplateAgent", + params: { + template: "${0}, ${1}, ${2}.", + foo: "${source2}", + bar: "${source2.bar}", + }, + inputs: ["source", "\"orange\"", undefined], + isResult: true, + }, + step2: { + agent: "sleeperAgent", + inputs: ["source2", { lemon: "yellow" }], + isResult: true, + }, + }, +}; + +test("test retry", async () => { + const result = await graphDataTestRunner(__filename, graphData_literal, defaultTestAgents, () => {}, false); + assert.deepStrictEqual(result, { + step1: "apple, orange, undefined.", + step2: { apple: "red", lemon: "yellow" }, + }); +}); From 9c923dbb5ced6f1ae92b842394eebb603479ca28 Mon Sep 17 00:00:00 2001 From: snakajima Date: Thu, 9 May 2024 03:01:08 -0700 Subject: [PATCH 2/7] pendings --- src/node.ts | 26 +++++++++++++++----------- tests/graphai/test_params.ts | 14 ++++++-------- 2 files changed, 21 insertions(+), 19 deletions(-) diff --git a/src/node.ts b/src/node.ts index 1c2cd5d92..6eba1f3df 100644 --- a/src/node.ts +++ b/src/node.ts @@ -75,17 +75,8 @@ export class ComputedNode extends Node { constructor(graphId: string, nodeId: string, data: ComputedNodeData, graph: GraphAI) { super(nodeId, graph); this.graphId = graphId; - this.params = data.params ?? {}; const regex = /^\$\{(.+)\}$/; - this.dynamicParams = Object.keys(this.params).reduce((tmp:Record, key) => { - const value = this.params[key]; - const match = (typeof value === "string") ? value.match(regex) : null; - if (match) { - tmp[key] = parseNodeName(match[1]); - } - return tmp; - }, {}); - console.log("****", this.dynamicParams); + this.params = data.params ?? {}; this.nestedGraph = data.graph; if (typeof data.agent === "string") { this.agentId = data.agent; @@ -108,6 +99,18 @@ export class ComputedNode extends Node { assert(!!this.ifSource.nodeId, `Invalid data source ${data.if}`); this.pendings.add(this.ifSource.nodeId); } + this.dynamicParams = Object.keys(this.params).reduce((tmp:Record, key) => { + const value = this.params[key]; + const match = (typeof value === "string") ? value.match(regex) : null; + if (match) { + const dataSource = parseNodeName(match[1]); + tmp[key] = dataSource; + assert(!!dataSource.nodeId, `Invalid data source ${key}:${value}`); + this.pendings.add(dataSource.nodeId); + } + return tmp; + }, {}); + console.log("****", this.dynamicParams); this.log.initForComputedNode(this); } @@ -252,8 +255,9 @@ export class ComputedNode extends Node { try { const callback = this.agentFunction ?? this.graph.getCallback(this.agentId); const localLog: TransactionLog[] = []; + const params = { ...this.params }; const context: AgentFunctionContext = { - params: this.params, + params: params, inputs: previousResults, debugInfo: { nodeId: this.nodeId, diff --git a/tests/graphai/test_params.ts b/tests/graphai/test_params.ts index dabb15d71..72cd8a762 100644 --- a/tests/graphai/test_params.ts +++ b/tests/graphai/test_params.ts @@ -6,11 +6,10 @@ import test from "node:test"; import assert from "node:assert"; -const testAgent: AgentFunction, string> = async () => { - return "test"; +const testAgent: AgentFunction, any> = async ({params}) => { + return params; }; - const graphData_literal = { version: 0.2, nodes: { @@ -21,9 +20,8 @@ const graphData_literal = { value: { apple: "red" }, }, step1: { - agent: "stringTemplateAgent", + agent: "testAgent", params: { - template: "${0}, ${1}, ${2}.", foo: "${source2}", bar: "${source2.bar}", }, @@ -31,15 +29,15 @@ const graphData_literal = { isResult: true, }, step2: { - agent: "sleeperAgent", + agent: "testAgent", inputs: ["source2", { lemon: "yellow" }], isResult: true, }, }, }; -test("test retry", async () => { - const result = await graphDataTestRunner(__filename, graphData_literal, defaultTestAgents, () => {}, false); +test("test params", async () => { + const result = await graphDataTestRunner(__filename, graphData_literal, { testAgent }, () => {}, false); assert.deepStrictEqual(result, { step1: "apple, orange, undefined.", step2: { apple: "red", lemon: "yellow" }, From d53e67573c03e8e3095b57defd9f71ed31b3d304 Mon Sep 17 00:00:00 2001 From: snakajima Date: Thu, 9 May 2024 03:14:13 -0700 Subject: [PATCH 3/7] code complete --- src/node.ts | 7 +++++-- tests/graphai/test_params.ts | 37 ++++++++++++++++++++++++------------ 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/src/node.ts b/src/node.ts index 6eba1f3df..e52e10904 100644 --- a/src/node.ts +++ b/src/node.ts @@ -110,7 +110,6 @@ export class ComputedNode extends Node { } return tmp; }, {}); - console.log("****", this.dynamicParams); this.log.initForComputedNode(this); } @@ -255,7 +254,11 @@ export class ComputedNode extends Node { try { const callback = this.agentFunction ?? this.graph.getCallback(this.agentId); const localLog: TransactionLog[] = []; - const params = { ...this.params }; + const params = Object.keys(this.dynamicParams).reduce((tmp, key) => { + const [result] = this.graph.resultsOf([this.dynamicParams[key]]); + tmp[key] = result; + return tmp; + }, { ...this.params }); const context: AgentFunctionContext = { params: params, inputs: previousResults, diff --git a/tests/graphai/test_params.ts b/tests/graphai/test_params.ts index 72cd8a762..97a2f951c 100644 --- a/tests/graphai/test_params.ts +++ b/tests/graphai/test_params.ts @@ -13,33 +13,46 @@ const testAgent: AgentFunction, any> = async ({params}) => const graphData_literal = { version: 0.2, nodes: { - source: { - value: "apple", + source1: { + value: { apple: "red" }, }, source2: { - value: { apple: "red" }, + value: { lemon: "yellow" }, + }, + delayed1: { + agent: "sleeperAgent", + inputs:["source1"], + }, + delayed2: { + agent: "sleeperAgent", + params: { + duration: 100 + }, + inputs:["source2"], }, - step1: { + test1: { agent: "testAgent", params: { - foo: "${source2}", - bar: "${source2.bar}", + fruit: "${source1}", + color: "${source2.lemon}", }, - inputs: ["source", "\"orange\"", undefined], isResult: true, }, - step2: { + test2: { agent: "testAgent", - inputs: ["source2", { lemon: "yellow" }], + params: { + fruit: "${delayed1}", + color: "${delayed2.lemon}", + }, isResult: true, }, }, }; test("test params", async () => { - const result = await graphDataTestRunner(__filename, graphData_literal, { testAgent }, () => {}, false); + const result = await graphDataTestRunner(__filename, graphData_literal, { testAgent, ...defaultTestAgents }, () => {}, false); assert.deepStrictEqual(result, { - step1: "apple, orange, undefined.", - step2: { apple: "red", lemon: "yellow" }, + test1: { fruit: { apple: 'red' }, color: 'yellow' }, + test2: { fruit: { apple: 'red' }, color: 'yellow' } }); }); From 0d2debcf6bbe2bf3757d6b5a088c2802e94f28bf Mon Sep 17 00:00:00 2001 From: snakajima Date: Thu, 9 May 2024 03:18:17 -0700 Subject: [PATCH 4/7] format --- src/node.ts | 17 ++++++++++------- tests/graphai/test_params.ts | 13 ++++++------- 2 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/node.ts b/src/node.ts index e52e10904..1e4e0cad1 100644 --- a/src/node.ts +++ b/src/node.ts @@ -99,9 +99,9 @@ export class ComputedNode extends Node { assert(!!this.ifSource.nodeId, `Invalid data source ${data.if}`); this.pendings.add(this.ifSource.nodeId); } - this.dynamicParams = Object.keys(this.params).reduce((tmp:Record, key) => { + this.dynamicParams = Object.keys(this.params).reduce((tmp: Record, key) => { const value = this.params[key]; - const match = (typeof value === "string") ? value.match(regex) : null; + const match = typeof value === "string" ? value.match(regex) : null; if (match) { const dataSource = parseNodeName(match[1]); tmp[key] = dataSource; @@ -254,11 +254,14 @@ export class ComputedNode extends Node { try { const callback = this.agentFunction ?? this.graph.getCallback(this.agentId); const localLog: TransactionLog[] = []; - const params = Object.keys(this.dynamicParams).reduce((tmp, key) => { - const [result] = this.graph.resultsOf([this.dynamicParams[key]]); - tmp[key] = result; - return tmp; - }, { ...this.params }); + const params = Object.keys(this.dynamicParams).reduce( + (tmp, key) => { + const [result] = this.graph.resultsOf([this.dynamicParams[key]]); + tmp[key] = result; + return tmp; + }, + { ...this.params }, + ); const context: AgentFunctionContext = { params: params, inputs: previousResults, diff --git a/tests/graphai/test_params.ts b/tests/graphai/test_params.ts index 97a2f951c..f7a737e38 100644 --- a/tests/graphai/test_params.ts +++ b/tests/graphai/test_params.ts @@ -5,8 +5,7 @@ import { defaultTestAgents } from "@/utils/test_agents"; import test from "node:test"; import assert from "node:assert"; - -const testAgent: AgentFunction, any> = async ({params}) => { +const testAgent: AgentFunction, any> = async ({ params }) => { return params; }; @@ -21,14 +20,14 @@ const graphData_literal = { }, delayed1: { agent: "sleeperAgent", - inputs:["source1"], + inputs: ["source1"], }, delayed2: { agent: "sleeperAgent", params: { - duration: 100 + duration: 100, }, - inputs:["source2"], + inputs: ["source2"], }, test1: { agent: "testAgent", @@ -52,7 +51,7 @@ const graphData_literal = { test("test params", async () => { const result = await graphDataTestRunner(__filename, graphData_literal, { testAgent, ...defaultTestAgents }, () => {}, false); assert.deepStrictEqual(result, { - test1: { fruit: { apple: 'red' }, color: 'yellow' }, - test2: { fruit: { apple: 'red' }, color: 'yellow' } + test1: { fruit: { apple: "red" }, color: "yellow" }, + test2: { fruit: { apple: "red" }, color: "yellow" }, }); }); From 1d1a79d39606bc6df1ca780629b7969b25a48ab7 Mon Sep 17 00:00:00 2001 From: snakajima Date: Thu, 9 May 2024 03:18:56 -0700 Subject: [PATCH 5/7] eslint --- tests/graphai/test_params.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/graphai/test_params.ts b/tests/graphai/test_params.ts index f7a737e38..f5c28bbc1 100644 --- a/tests/graphai/test_params.ts +++ b/tests/graphai/test_params.ts @@ -1,5 +1,5 @@ import { AgentFunction } from "@/graphai"; -import { rejectTest, graphDataTestRunner } from "~/utils/runner"; +import { graphDataTestRunner } from "~/utils/runner"; import { defaultTestAgents } from "@/utils/test_agents"; import test from "node:test"; From da63a0779cf79834474b60e990632cabe80f37ba Mon Sep 17 00:00:00 2001 From: snakajima Date: Thu, 9 May 2024 03:21:01 -0700 Subject: [PATCH 6/7] moved regex --- src/node.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/node.ts b/src/node.ts index 1e4e0cad1..af73a832f 100644 --- a/src/node.ts +++ b/src/node.ts @@ -75,7 +75,6 @@ export class ComputedNode extends Node { constructor(graphId: string, nodeId: string, data: ComputedNodeData, graph: GraphAI) { super(nodeId, graph); this.graphId = graphId; - const regex = /^\$\{(.+)\}$/; this.params = data.params ?? {}; this.nestedGraph = data.graph; if (typeof data.agent === "string") { @@ -99,6 +98,7 @@ export class ComputedNode extends Node { assert(!!this.ifSource.nodeId, `Invalid data source ${data.if}`); this.pendings.add(this.ifSource.nodeId); } + const regex = /^\$\{(.+)\}$/; this.dynamicParams = Object.keys(this.params).reduce((tmp: Record, key) => { const value = this.params[key]; const match = typeof value === "string" ? value.match(regex) : null; From 106933d7d6dc5ec200db52ea525d852508fafb4c Mon Sep 17 00:00:00 2001 From: snakajima Date: Thu, 9 May 2024 03:26:05 -0700 Subject: [PATCH 7/7] better regex --- src/node.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/node.ts b/src/node.ts index af73a832f..331edb7b2 100644 --- a/src/node.ts +++ b/src/node.ts @@ -98,7 +98,7 @@ export class ComputedNode extends Node { assert(!!this.ifSource.nodeId, `Invalid data source ${data.if}`); this.pendings.add(this.ifSource.nodeId); } - const regex = /^\$\{(.+)\}$/; + const regex = /^\$\{([^{}]+)\}$/; this.dynamicParams = Object.keys(this.params).reduce((tmp: Record, key) => { const value = this.params[key]; const match = typeof value === "string" ? value.match(regex) : null;