graphai 0.6.2 → 0.6.4

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.
package/lib/node.d.ts CHANGED
@@ -19,7 +19,6 @@ export declare class ComputedNode extends Node {
19
19
  readonly isResult: boolean;
20
20
  readonly params: NodeDataParams;
21
21
  private readonly filterParams;
22
- private readonly dynamicParams;
23
22
  readonly nestedGraph?: GraphData | DataSource;
24
23
  readonly retryLimit: number;
25
24
  retryCount: number;
@@ -33,10 +32,11 @@ export declare class ComputedNode extends Node {
33
32
  readonly anyInput: boolean;
34
33
  dataSources: DataSource[];
35
34
  private inputs?;
36
- isNamedInputs: boolean;
37
35
  pendings: Set<string>;
38
36
  private ifSource?;
39
37
  private unlessSource?;
38
+ private defaultValue?;
39
+ private isSkip;
40
40
  readonly isStaticNode = false;
41
41
  readonly isComputedNode = true;
42
42
  constructor(graphId: string, nodeId: string, data: ComputedNodeData, graph: GraphAI);
@@ -52,9 +52,9 @@ export declare class ComputedNode extends Node {
52
52
  private shouldApplyAgentFilter;
53
53
  private agentFilterHandler;
54
54
  execute(): Promise<void>;
55
+ private afterExecute;
55
56
  private prepareExecute;
56
57
  private errorProcess;
57
- private getParams;
58
58
  private getContext;
59
59
  private getResult;
60
60
  private getDebugInfo;
package/lib/node.js CHANGED
@@ -45,7 +45,7 @@ class ComputedNode extends Node {
45
45
  super(nodeId, graph);
46
46
  this.retryCount = 0;
47
47
  this.dataSources = []; // no longer needed. This is for transaction log.
48
- this.isNamedInputs = false;
48
+ this.isSkip = false;
49
49
  this.isStaticNode = false;
50
50
  this.isComputedNode = true;
51
51
  this.graphId = graphId;
@@ -59,8 +59,7 @@ class ComputedNode extends Node {
59
59
  this.priority = data.priority ?? 0;
60
60
  this.anyInput = data.anyInput ?? false;
61
61
  this.inputs = data.inputs;
62
- // this.isNamedInputs = isObject(data.inputs) && !Array.isArray(data.inputs);
63
- this.dataSources = data.inputs ? (0, nodeUtils_1.inputs2dataSources)(data.inputs).flat(10) : [];
62
+ this.dataSources = [...(data.inputs ? (0, nodeUtils_1.inputs2dataSources)(data.inputs).flat(10) : []), ...(data.params ? (0, nodeUtils_1.inputs2dataSources)(data.params).flat(10) : [])];
64
63
  if (data.inputs && Array.isArray(data.inputs)) {
65
64
  throw new Error(`array inputs have been deprecated. nodeId: ${nodeId}: see https://github.com/receptron/graphai/blob/main/docs/NamedInputs.md`);
66
65
  }
@@ -71,7 +70,6 @@ class ComputedNode extends Node {
71
70
  }
72
71
  else {
73
72
  const agent = data.agent;
74
- // this.agentFunction = this.isNamedInputs ? async ({ namedInputs, params }) => agent(namedInputs, params) : async ({ inputs }) => agent(...inputs);
75
73
  this.agentFunction = async ({ namedInputs, params }) => agent(namedInputs, params);
76
74
  }
77
75
  if (data.graph) {
@@ -86,15 +84,10 @@ class ComputedNode extends Node {
86
84
  if (data.unless) {
87
85
  this.unlessSource = this.addPendingNode(data.unless);
88
86
  }
89
- this.dynamicParams = Object.keys(this.params).reduce((tmp, key) => {
90
- const dataSource = (0, utils_2.parseNodeName)(this.params[key]);
91
- if (dataSource.nodeId) {
92
- (0, utils_2.assert)(!this.anyInput, "Dynamic params are not supported with anyInput");
93
- tmp[key] = dataSource;
94
- this.pendings.add(dataSource.nodeId);
95
- }
96
- return tmp;
97
- }, {});
87
+ if (data.defaultValue) {
88
+ this.defaultValue = data.defaultValue;
89
+ }
90
+ this.isSkip = false;
98
91
  this.log.initForComputedNode(this, graph);
99
92
  }
100
93
  getAgentId() {
@@ -110,8 +103,9 @@ class ComputedNode extends Node {
110
103
  if (this.state !== type_1.NodeState.Waiting || this.pendings.size !== 0) {
111
104
  return false;
112
105
  }
113
- if ((this.ifSource && !(0, utils_2.isLogicallyTrue)(this.graph.resultOf(this.ifSource))) ||
114
- (this.unlessSource && (0, utils_2.isLogicallyTrue)(this.graph.resultOf(this.unlessSource)))) {
106
+ this.isSkip = !!((this.ifSource && !(0, utils_2.isLogicallyTrue)(this.graph.resultOf(this.ifSource))) ||
107
+ (this.unlessSource && (0, utils_2.isLogicallyTrue)(this.graph.resultOf(this.unlessSource))));
108
+ if (this.isSkip && this.defaultValue === undefined) {
115
109
  this.state = type_1.NodeState.Skipped;
116
110
  this.log.onSkipped(this, this.graph);
117
111
  return false;
@@ -205,6 +199,10 @@ class ComputedNode extends Node {
205
199
  // then it removes itself from the "running node" list of the graph.
206
200
  // Notice that setting the result of this node may make other nodes ready to run.
207
201
  async execute() {
202
+ if (this.isSkip) {
203
+ this.afterExecute(this.defaultValue, []);
204
+ return;
205
+ }
208
206
  const previousResults = this.graph.resultsOf(this.inputs, this.anyInput);
209
207
  const transactionId = Date.now();
210
208
  this.prepareExecute(transactionId, Object.values(previousResults));
@@ -221,18 +219,10 @@ class ComputedNode extends Node {
221
219
  // if this is a nested agent or not.
222
220
  if (this.nestedGraph) {
223
221
  this.graph.taskManager.prepareForNesting();
224
- context.taskManager = this.graph.taskManager;
225
222
  context.onLogCallback = this.graph.onLogCallback;
226
- if ("nodes" in this.nestedGraph) {
227
- context.graphData = this.nestedGraph;
228
- }
229
- else {
230
- context.graphData = this.graph.resultOf(this.nestedGraph); // HACK: compiler work-around
231
- }
232
- context.agents = this.graph.agentFunctionInfoDictionary;
233
223
  context.forNestedGraph = {
234
- graphData: context.graphData,
235
- agents: context.agents,
224
+ graphData: "nodes" in this.nestedGraph ? this.nestedGraph : this.graph.resultOf(this.nestedGraph), // HACK: compiler work-around
225
+ agents: this.graph.agentFunctionInfoDictionary,
236
226
  graphOptions: {
237
227
  agentFilters: this.graph.agentFilters,
238
228
  taskManager: this.graph.taskManager,
@@ -240,6 +230,7 @@ class ComputedNode extends Node {
240
230
  config: this.graph.config,
241
231
  graphLoader: this.graph.graphLoader,
242
232
  },
233
+ onLogCallback: this.graph.onLogCallback,
243
234
  };
244
235
  }
245
236
  this.beforeConsoleLog(context);
@@ -254,16 +245,20 @@ class ComputedNode extends Node {
254
245
  console.log(`-- transactionId mismatch with ${this.nodeId} (probably timeout)`);
255
246
  return;
256
247
  }
257
- this.state = type_1.NodeState.Completed;
258
- this.result = this.getResult(result);
259
- this.log.onComplete(this, this.graph, localLog);
260
- this.onSetResult();
261
- this.graph.onExecutionComplete(this);
248
+ // after process
249
+ this.afterExecute(result, localLog);
262
250
  }
263
251
  catch (error) {
264
252
  this.errorProcess(error, transactionId, previousResults);
265
253
  }
266
254
  }
255
+ afterExecute(result, localLog) {
256
+ this.state = type_1.NodeState.Completed;
257
+ this.result = this.getResult(result);
258
+ this.log.onComplete(this, this.graph, localLog);
259
+ this.onSetResult();
260
+ this.graph.onExecutionComplete(this);
261
+ }
267
262
  // This private method (called only by execute()) prepares the ComputedNode object
268
263
  // for execution, and create a new transaction to record it.
269
264
  prepareExecute(transactionId, inputs) {
@@ -293,25 +288,9 @@ class ComputedNode extends Node {
293
288
  this.retry(type_1.NodeState.Failed, Error("Unknown"));
294
289
  }
295
290
  }
296
- getParams() {
297
- return Object.keys(this.dynamicParams).reduce((tmp, key) => {
298
- const result = this.graph.resultOf(this.dynamicParams[key]);
299
- tmp[key] = result;
300
- return tmp;
301
- }, { ...this.params });
302
- }
303
- /*
304
- private getInputs(previousResults: Record<string, ResultData | undefined>) {
305
- if (Array.isArray(this.inputs)) {
306
- return (this.inputs ?? []).map((key) => previousResults[String(key)]).filter((a) => !this.anyInput || a);
307
- }
308
- return [];
309
- }
310
- */
311
291
  getContext(previousResults, localLog) {
312
292
  const context = {
313
- params: this.getParams(),
314
- // inputs: this.getInputs(previousResults),
293
+ params: this.graph.resultsOf(this.params),
315
294
  namedInputs: previousResults,
316
295
  inputSchema: this.agentFunction ? undefined : this.graph.getAgentFunctionInfo(this.agentId)?.inputs,
317
296
  debugInfo: this.getDebugInfo(),
@@ -346,7 +325,6 @@ class ComputedNode extends Node {
346
325
  }
347
326
  beforeConsoleLog(context) {
348
327
  if (this.console.before === true) {
349
- // console.log(JSON.stringify(this.isNamedInputs ? context.namedInputs : context.inputs, null, 2));
350
328
  console.log(JSON.stringify(context.namedInputs, null, 2));
351
329
  }
352
330
  else if (this.console.before) {
package/lib/type.d.ts CHANGED
@@ -24,7 +24,7 @@ export type DataSource = {
24
24
  propIds?: string[];
25
25
  };
26
26
  export type StaticNodeData = {
27
- value: ResultData;
27
+ value?: ResultData;
28
28
  update?: string;
29
29
  isResult?: boolean;
30
30
  console?: Record<string, string | boolean>;
@@ -45,6 +45,7 @@ export type ComputedNodeData = {
45
45
  timeout?: number;
46
46
  if?: string;
47
47
  unless?: string;
48
+ defaultValue?: ResultData;
48
49
  graph?: GraphData | string;
49
50
  graphLoader?: GraphDataLoaderOption;
50
51
  isResult?: boolean;
@@ -87,9 +88,6 @@ export type AgentFunctionContext<ParamsType = DefaultParamsType, NamedInputDataT
87
88
  version?: number;
88
89
  isResult?: boolean;
89
90
  };
90
- graphData?: GraphData;
91
- agents?: AgentFunctionInfoDictionary;
92
- taskManager?: TaskManager;
93
91
  forNestedGraph?: {
94
92
  graphData: GraphData;
95
93
  agents: AgentFunctionInfoDictionary;
@@ -103,8 +101,8 @@ export type AgentFunctionContext<ParamsType = DefaultParamsType, NamedInputDataT
103
101
  log?: TransactionLog[];
104
102
  config?: Record<string, unknown>;
105
103
  };
106
- export type AgentFunction<ParamsType = DefaultParamsType, ResultType = DefaultResultData, InputDataType = DefaultInputData, NamedInputDataType = undefined> = NamedInputDataType extends undefined ? (context: AgentFunctionContext<ParamsType, InputDataType>) => Promise<ResultData<ResultType>> : (context: AgentFunctionContext<ParamsType, NamedInputDataType>) => Promise<ResultData<ResultType>>;
107
- export type AgentFilterFunction<ParamsType = DefaultParamsType, ResultType = DefaultResultData, InputDataType = DefaultInputData, NamedInputDataType = undefined> = NamedInputDataType extends undefined ? (context: AgentFunctionContext<ParamsType, InputDataType>, agent: AgentFunction) => Promise<ResultData<ResultType>> : (context: AgentFunctionContext<ParamsType, NamedInputDataType>, agent: AgentFunction) => Promise<ResultData<ResultType>>;
104
+ export type AgentFunction<ParamsType = DefaultParamsType, ResultType = DefaultResultData, NamedInputDataType = DefaultInputData> = (context: AgentFunctionContext<ParamsType, NamedInputDataType>) => Promise<ResultData<ResultType>>;
105
+ export type AgentFilterFunction<ParamsType = DefaultParamsType, ResultType = DefaultResultData, NamedInputDataType = DefaultInputData> = (context: AgentFunctionContext<ParamsType, NamedInputDataType>, agent: AgentFunction) => Promise<ResultData<ResultType>>;
108
106
  export type AgentFilterInfo = {
109
107
  name: string;
110
108
  agent: AgentFilterFunction;
@@ -120,8 +118,8 @@ export type AgentFunctionInfoSample = {
120
118
  };
121
119
  export type AgentFunctionInfo = {
122
120
  name: string;
123
- agent: AgentFunction<any, any, any, any>;
124
- mock: AgentFunction<any, any, any, any>;
121
+ agent: AgentFunction<any, any, any>;
122
+ mock: AgentFunction<any, any, any>;
125
123
  inputs?: any;
126
124
  output?: any;
127
125
  outputFormat?: any;
@@ -18,7 +18,7 @@ const propArrayFunction = (result, propId) => {
18
18
  return result.length === 0;
19
19
  }
20
20
  // array join
21
- const matchJoin = propId.match(/^join\(([,-]?)\)$/);
21
+ const matchJoin = propId.match(/^join\(([,-\s]?)\)$/);
22
22
  if (matchJoin && Array.isArray(matchJoin)) {
23
23
  return result.join(matchJoin[1] ?? "");
24
24
  }
@@ -56,6 +56,16 @@ const propStringFunction = (result, propId) => {
56
56
  return ret;
57
57
  }
58
58
  }
59
+ if (propId === "trim()") {
60
+ return result.trim();
61
+ }
62
+ if (propId === "toLowerCase()") {
63
+ return result.toLowerCase();
64
+ }
65
+ if (propId === "toUpperCase()") {
66
+ return result.toUpperCase();
67
+ }
68
+ // split()
59
69
  }
60
70
  return undefined;
61
71
  };
@@ -18,7 +18,7 @@ export declare const defaultAgentInfo: {
18
18
  repository: string;
19
19
  license: string;
20
20
  };
21
- export declare const agentInfoWrapper: (agent: AgentFunction<any, any, any, any>) => {
21
+ export declare const agentInfoWrapper: (agent: AgentFunction<any, any, any>) => {
22
22
  name: string;
23
23
  samples: {
24
24
  inputs: never[];
@@ -30,8 +30,8 @@ export declare const agentInfoWrapper: (agent: AgentFunction<any, any, any, any>
30
30
  author: string;
31
31
  repository: string;
32
32
  license: string;
33
- agent: ((context: import("../type").AgentFunctionContext<any, any>) => Promise<any>) | ((context: import("../type").AgentFunctionContext<any, any>) => Promise<any>);
34
- mock: ((context: import("../type").AgentFunctionContext<any, any>) => Promise<any>) | ((context: import("../type").AgentFunctionContext<any, any>) => Promise<any>);
33
+ agent: AgentFunction<any, any, any>;
34
+ mock: AgentFunction<any, any, any>;
35
35
  };
36
36
  export declare const debugResultKey: (agentId: string, result: any) => string[];
37
37
  export declare const isLogicallyTrue: (value: any) => boolean;
package/lib/validator.js CHANGED
@@ -15,7 +15,7 @@ const validateGraphData = (data, agentIds) => {
15
15
  const graphAgentIds = new Set();
16
16
  Object.keys(data.nodes).forEach((nodeId) => {
17
17
  const node = data.nodes[nodeId];
18
- const isStaticNode = "value" in node;
18
+ const isStaticNode = !("agent" in node);
19
19
  (0, nodeValidator_1.nodeValidator)(node);
20
20
  const agentId = isStaticNode ? "" : node.agent;
21
21
  isStaticNode && (0, static_node_validator_1.staticNodeValidator)(node) && staticNodeIds.push(nodeId);
@@ -15,6 +15,7 @@ exports.computedNodeAttributeKeys = [
15
15
  "priority",
16
16
  "if",
17
17
  "unless",
18
+ "defaultValue",
18
19
  "filterParams",
19
20
  "console",
20
21
  "passThrough",
@@ -6,9 +6,9 @@ const nodeValidator = (nodeData) => {
6
6
  if (nodeData.agent && nodeData.value) {
7
7
  throw new common_1.ValidationError("Cannot set both agent and value");
8
8
  }
9
- if (!("agent" in nodeData) && !("value" in nodeData)) {
10
- throw new common_1.ValidationError("Either agent or value is required");
11
- }
9
+ // if (!("agent" in nodeData) && !("value" in nodeData)) {
10
+ // throw new ValidationError("Either agent or value is required");
11
+ // }
12
12
  return true;
13
13
  };
14
14
  exports.nodeValidator = nodeValidator;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "graphai",
3
- "version": "0.6.2",
3
+ "version": "0.6.4",
4
4
  "description": "Asynchronous data flow execution engine for agentic AI apps.",
5
5
  "main": "lib/bundle.cjs.js",
6
6
  "module": "lib/bundle.esm.js",
@@ -27,7 +27,7 @@
27
27
  },
28
28
  "homepage": "https://github.com/receptron/graphai#readme",
29
29
  "devDependencies": {
30
- "typedoc": "^0.27.2"
30
+ "typedoc": "^0.27.3"
31
31
  },
32
32
  "types": "./lib/index.d.ts",
33
33
  "directories": {