graphai 0.6.18 → 0.6.20

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/graphai.d.ts CHANGED
@@ -6,7 +6,7 @@ export declare const defaultConcurrency = 8;
6
6
  export declare const graphDataLatestVersion = 0.5;
7
7
  export declare class GraphAI {
8
8
  readonly version: number;
9
- private readonly graphId;
9
+ readonly graphId: string;
10
10
  private readonly graphData;
11
11
  private readonly loop?;
12
12
  private readonly logs;
@@ -30,6 +30,7 @@ export declare class GraphAI {
30
30
  constructor(graphData: GraphData, agentFunctionInfoDictionary: AgentFunctionInfoDictionary, options?: GraphOptions);
31
31
  getAgentFunctionInfo(agentId?: string): import("./type").AgentFunctionInfo | {
32
32
  agent: () => Promise<null>;
33
+ hasGraphData: boolean;
33
34
  inputs: null;
34
35
  cacheType: undefined;
35
36
  };
@@ -41,6 +42,8 @@ export declare class GraphAI {
41
42
  pushQueueIfReadyAndRunning(node: ComputedNode): void;
42
43
  pushQueue(node: ComputedNode): void;
43
44
  run<T = DefaultResultData>(all?: boolean): Promise<ResultDataDictionary<T>>;
45
+ abort(): void;
46
+ resetPending(): void;
44
47
  isRunning(): boolean;
45
48
  onExecutionComplete(node: ComputedNode): void;
46
49
  private processLoopIfNecessary;
package/lib/graphai.js CHANGED
@@ -16,7 +16,7 @@ class GraphAI {
16
16
  createNodes(graphData) {
17
17
  const nodes = Object.keys(graphData.nodes).reduce((_nodes, nodeId) => {
18
18
  const nodeData = graphData.nodes[nodeId];
19
- if ("agent" in nodeData) {
19
+ if ((0, utils_1.isComputedNodeData)(nodeData)) {
20
20
  _nodes[nodeId] = new node_1.ComputedNode(this.graphId, nodeId, nodeData, this);
21
21
  }
22
22
  else {
@@ -109,7 +109,7 @@ class GraphAI {
109
109
  this.graphLoader = options.graphLoader;
110
110
  this.loop = graphData.loop;
111
111
  this.verbose = graphData.verbose === true;
112
- this.onComplete = () => {
112
+ this.onComplete = (__isAbort) => {
113
113
  throw new Error("SOMETHING IS WRONG: onComplete is called without run()");
114
114
  };
115
115
  (0, validator_1.validateGraphData)(graphData, [...Object.keys(agentFunctionInfoDictionary), ...this.bypassAgentIds]);
@@ -126,6 +126,7 @@ class GraphAI {
126
126
  agent: async () => {
127
127
  return null;
128
128
  },
129
+ hasGraphData: false,
129
130
  inputs: null,
130
131
  cacheType: undefined, // for node.getContext
131
132
  };
@@ -205,10 +206,10 @@ class GraphAI {
205
206
  return {};
206
207
  }
207
208
  return new Promise((resolve, reject) => {
208
- this.onComplete = () => {
209
+ this.onComplete = (isAbort = false) => {
209
210
  const errors = this.errors();
210
211
  const nodeIds = Object.keys(errors);
211
- if (nodeIds.length > 0) {
212
+ if (nodeIds.length > 0 || isAbort) {
212
213
  reject(errors[nodeIds[0]]);
213
214
  }
214
215
  else {
@@ -217,6 +218,19 @@ class GraphAI {
217
218
  };
218
219
  });
219
220
  }
221
+ abort() {
222
+ if (this.isRunning()) {
223
+ this.resetPending();
224
+ }
225
+ this.onComplete(this.isRunning());
226
+ }
227
+ resetPending() {
228
+ Object.values(this.nodes).map((node) => {
229
+ if (node.isComputedNode) {
230
+ node.resetPending();
231
+ }
232
+ });
233
+ }
220
234
  // Public only for testing
221
235
  isRunning() {
222
236
  return this.taskManager.isRunning(this.graphId);
@@ -227,7 +241,7 @@ class GraphAI {
227
241
  if (this.isRunning() || this.processLoopIfNecessary()) {
228
242
  return; // continue running
229
243
  }
230
- this.onComplete(); // Nothing to run. Finish it.
244
+ this.onComplete(false); // Nothing to run. Finish it.
231
245
  }
232
246
  // Must be called only from onExecutionComplete righ after removeRunning
233
247
  // Check if there is any running computed nodes.
package/lib/index.d.ts CHANGED
@@ -2,6 +2,6 @@ export { GraphAI, defaultConcurrency, graphDataLatestVersion } from "./graphai";
2
2
  export type { AgentFunction, AgentFunctionInfo, AgentFunctionInfoDictionary, AgentFunctionInfoSample, AgentFunctionContext, GraphData, ResultDataDictionary, ResultData, AgentFilterFunction, AgentFilterInfo, NodeData, StaticNodeData, ComputedNodeData, DefaultResultData, DefaultInputData, DefaultParamsType, GraphDataLoaderOption, GraphDataLoader, ConfigDataDictionary, DefaultConfigData, } from "./type";
3
3
  export { NodeState } from "./type";
4
4
  export type { TransactionLog } from "./transaction_log";
5
- export { defaultAgentInfo, agentInfoWrapper, defaultTestContext, strIntentionalError, assert, sleep, isObject, parseNodeName, debugResultKey, } from "./utils/utils";
5
+ export { defaultAgentInfo, agentInfoWrapper, defaultTestContext, strIntentionalError, assert, sleep, isObject, parseNodeName, debugResultKey, isComputedNodeData, isStaticNodeData, } from "./utils/utils";
6
6
  export { inputs2dataSources } from "./utils/nodeUtils";
7
7
  export { ValidationError } from "./validators/common";
package/lib/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.ValidationError = exports.inputs2dataSources = exports.debugResultKey = exports.parseNodeName = exports.isObject = exports.sleep = exports.assert = exports.strIntentionalError = exports.defaultTestContext = exports.agentInfoWrapper = exports.defaultAgentInfo = exports.NodeState = exports.graphDataLatestVersion = exports.defaultConcurrency = exports.GraphAI = void 0;
3
+ exports.ValidationError = exports.inputs2dataSources = exports.isStaticNodeData = exports.isComputedNodeData = exports.debugResultKey = exports.parseNodeName = exports.isObject = exports.sleep = exports.assert = exports.strIntentionalError = exports.defaultTestContext = exports.agentInfoWrapper = exports.defaultAgentInfo = exports.NodeState = exports.graphDataLatestVersion = exports.defaultConcurrency = exports.GraphAI = void 0;
4
4
  var graphai_1 = require("./graphai");
5
5
  Object.defineProperty(exports, "GraphAI", { enumerable: true, get: function () { return graphai_1.GraphAI; } });
6
6
  Object.defineProperty(exports, "defaultConcurrency", { enumerable: true, get: function () { return graphai_1.defaultConcurrency; } });
@@ -17,6 +17,8 @@ Object.defineProperty(exports, "sleep", { enumerable: true, get: function () { r
17
17
  Object.defineProperty(exports, "isObject", { enumerable: true, get: function () { return utils_1.isObject; } });
18
18
  Object.defineProperty(exports, "parseNodeName", { enumerable: true, get: function () { return utils_1.parseNodeName; } });
19
19
  Object.defineProperty(exports, "debugResultKey", { enumerable: true, get: function () { return utils_1.debugResultKey; } });
20
+ Object.defineProperty(exports, "isComputedNodeData", { enumerable: true, get: function () { return utils_1.isComputedNodeData; } });
21
+ Object.defineProperty(exports, "isStaticNodeData", { enumerable: true, get: function () { return utils_1.isStaticNodeData; } });
20
22
  var nodeUtils_1 = require("./utils/nodeUtils");
21
23
  Object.defineProperty(exports, "inputs2dataSources", { enumerable: true, get: function () { return nodeUtils_1.inputs2dataSources; } });
22
24
  var common_1 = require("./validators/common");
package/lib/node.d.ts CHANGED
@@ -38,12 +38,14 @@ export declare class ComputedNode extends Node {
38
38
  private unlessSource?;
39
39
  private defaultValue?;
40
40
  private isSkip;
41
+ private debugInfo?;
41
42
  readonly isStaticNode = false;
42
43
  readonly isComputedNode = true;
43
44
  constructor(graphId: string, nodeId: string, data: ComputedNodeData, graph: GraphAI);
44
45
  getAgentId(): string;
45
46
  private getConfig;
46
47
  private addPendingNode;
48
+ resetPending(): void;
47
49
  isReadyNode(): boolean;
48
50
  private retry;
49
51
  private checkDataAvailability;
package/lib/node.js CHANGED
@@ -126,6 +126,18 @@ class ComputedNode extends Node {
126
126
  this.pendings.add(source.nodeId);
127
127
  return source;
128
128
  }
129
+ resetPending() {
130
+ this.pendings.clear();
131
+ if (this.state === type_1.NodeState.Executing) {
132
+ this.state = type_1.NodeState.Abort;
133
+ if (this.debugInfo) {
134
+ this.debugInfo.state = type_1.NodeState.Abort;
135
+ }
136
+ }
137
+ if (this.debugInfo && this.debugInfo.subGraphs) {
138
+ this.debugInfo.subGraphs.forEach((graph) => graph.abort());
139
+ }
140
+ }
129
141
  isReadyNode() {
130
142
  if (this.state !== type_1.NodeState.Waiting || this.pendings.size !== 0) {
131
143
  return false;
@@ -235,7 +247,8 @@ class ComputedNode extends Node {
235
247
  if (typeof agentId === "function") {
236
248
  this.agentFunction = agentId;
237
249
  }
238
- const config = this.getConfig(!!this.nestedGraph, agentId);
250
+ const hasNestedGraph = Boolean(this.nestedGraph) || Boolean(agentId && this.graph.getAgentFunctionInfo(agentId).hasGraphData);
251
+ const config = this.getConfig(hasNestedGraph, agentId);
239
252
  const transactionId = Date.now();
240
253
  this.prepareExecute(transactionId, Object.values(previousResults));
241
254
  if (this.timeout && this.timeout > 0) {
@@ -249,10 +262,14 @@ class ComputedNode extends Node {
249
262
  const context = this.getContext(previousResults, localLog, agentId, config);
250
263
  // NOTE: We use the existence of graph object in the agent-specific params to determine
251
264
  // if this is a nested agent or not.
252
- if (this.nestedGraph) {
265
+ if (hasNestedGraph) {
253
266
  this.graph.taskManager.prepareForNesting();
254
267
  context.forNestedGraph = {
255
- graphData: "nodes" in this.nestedGraph ? this.nestedGraph : this.graph.resultOf(this.nestedGraph), // HACK: compiler work-around
268
+ graphData: this.nestedGraph
269
+ ? "nodes" in this.nestedGraph
270
+ ? this.nestedGraph
271
+ : this.graph.resultOf(this.nestedGraph) // HACK: compiler work-around
272
+ : { version: 0, nodes: {} },
256
273
  agents: this.graph.agentFunctionInfoDictionary,
257
274
  graphOptions: {
258
275
  agentFilters: this.graph.agentFilters,
@@ -267,7 +284,7 @@ class ComputedNode extends Node {
267
284
  this.beforeConsoleLog(context);
268
285
  const result = await this.agentFilterHandler(context, agentFunction, agentId);
269
286
  this.afterConsoleLog(result);
270
- if (this.nestedGraph) {
287
+ if (hasNestedGraph) {
271
288
  this.graph.taskManager.restoreAfterNesting();
272
289
  }
273
290
  if (!this.isCurrentTransaction(transactionId)) {
@@ -284,6 +301,9 @@ class ComputedNode extends Node {
284
301
  }
285
302
  }
286
303
  afterExecute(result, localLog) {
304
+ if (this.state == type_1.NodeState.Abort) {
305
+ return;
306
+ }
287
307
  this.state = type_1.NodeState.Completed;
288
308
  this.result = this.getResult(result);
289
309
  if (this.output) {
@@ -323,11 +343,14 @@ class ComputedNode extends Node {
323
343
  }
324
344
  }
325
345
  getContext(previousResults, localLog, agentId, config) {
346
+ // Pass debugInfo by reference, and the state of this node will be received by agent/agentFilter.
347
+ // From graphAgent(nested, map), set the instance of graphai, and use abort on the child graphai.
348
+ this.debugInfo = this.getDebugInfo(agentId);
326
349
  const context = {
327
350
  params: this.graph.resultsOf(this.params),
328
351
  namedInputs: previousResults,
329
352
  inputSchema: this.agentFunction ? undefined : this.graph.getAgentFunctionInfo(agentId)?.inputs,
330
- debugInfo: this.getDebugInfo(agentId),
353
+ debugInfo: this.debugInfo,
331
354
  cacheType: this.agentFunction ? undefined : this.graph.getAgentFunctionInfo(agentId)?.cacheType,
332
355
  filterParams: this.filterParams,
333
356
  agentFilters: this.graph.agentFilters,
@@ -352,6 +375,8 @@ class ComputedNode extends Node {
352
375
  nodeId: this.nodeId,
353
376
  agentId,
354
377
  retry: this.retryCount,
378
+ state: this.state,
379
+ subGraphs: new Map(),
355
380
  verbose: this.graph.verbose,
356
381
  version: this.graph.version,
357
382
  isResult: this.isResult,
package/lib/type.d.ts CHANGED
@@ -1,5 +1,6 @@
1
1
  import type { TransactionLog } from "./transaction_log";
2
2
  import type { TaskManager } from "./task_manager";
3
+ import type { GraphAI } from "./graphai";
3
4
  export declare enum NodeState {
4
5
  Waiting = "waiting",
5
6
  Queued = "queued",
@@ -7,6 +8,7 @@ export declare enum NodeState {
7
8
  ExecutingServer = "executing-server",
8
9
  Failed = "failed",
9
10
  TimedOut = "timed-out",
11
+ Abort = "abort",
10
12
  Completed = "completed",
11
13
  Injected = "injected",
12
14
  Skipped = "skipped"
@@ -85,20 +87,23 @@ export type GraphOptions = {
85
87
  graphLoader?: GraphDataLoader;
86
88
  };
87
89
  export type CacheTypes = "pureAgent" | "impureAgent";
90
+ export type AgentFunctionContextDebugInfo = {
91
+ verbose: boolean;
92
+ nodeId: string;
93
+ state: string;
94
+ subGraphs: Map<string, GraphAI>;
95
+ retry: number;
96
+ agentId?: string;
97
+ version?: number;
98
+ isResult?: boolean;
99
+ };
88
100
  export type AgentFunctionContext<ParamsType = DefaultParamsType, NamedInputDataType = DefaultInputData, ConfigType = DefaultConfigData> = {
89
101
  params: NodeDataParams<ParamsType>;
90
102
  inputSchema?: any;
91
103
  namedInputs: NamedInputDataType;
92
- debugInfo: {
93
- verbose: boolean;
94
- nodeId: string;
95
- retry: number;
96
- agentId?: string;
97
- version?: number;
98
- isResult?: boolean;
99
- };
104
+ debugInfo: AgentFunctionContextDebugInfo;
100
105
  forNestedGraph?: {
101
- graphData: GraphData;
106
+ graphData?: GraphData;
102
107
  agents: AgentFunctionInfoDictionary;
103
108
  graphOptions: GraphOptions;
104
109
  onLogCallback?: (log: TransactionLog, isUpdate: boolean) => void;
@@ -142,6 +147,7 @@ export type AgentFunctionInfo = {
142
147
  license: string;
143
148
  cacheType?: CacheTypes;
144
149
  environmentVariables?: string[];
150
+ hasGraphData?: boolean;
145
151
  stream?: boolean;
146
152
  apiKeys?: string[];
147
153
  npms?: string[];
package/lib/type.js CHANGED
@@ -9,6 +9,7 @@ var NodeState;
9
9
  NodeState["ExecutingServer"] = "executing-server";
10
10
  NodeState["Failed"] = "failed";
11
11
  NodeState["TimedOut"] = "timed-out";
12
+ NodeState["Abort"] = "abort";
12
13
  NodeState["Completed"] = "completed";
13
14
  NodeState["Injected"] = "injected";
14
15
  NodeState["Skipped"] = "skipped";
@@ -1,4 +1,4 @@
1
- import { DataSource, AgentFunction, DefaultInputData } from "../type";
1
+ import { DataSource, AgentFunction, AgentFunctionInfo, DefaultInputData, NodeData, StaticNodeData, ComputedNodeData, NodeState } from "../type";
2
2
  export declare const sleep: (milliseconds: number) => Promise<unknown>;
3
3
  export declare const parseNodeName: (inputNodeId: any, isSelfNode?: boolean) => DataSource;
4
4
  export declare function assert(condition: boolean, message: string, isWarn?: boolean): asserts condition;
@@ -18,21 +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>) => {
22
- name: string;
23
- samples: {
24
- inputs: never[];
25
- params: {};
26
- result: {};
27
- }[];
28
- description: string;
29
- category: never[];
30
- author: string;
31
- repository: string;
32
- license: string;
33
- agent: AgentFunction<any, any, any, any>;
34
- mock: AgentFunction<any, any, any, any>;
35
- };
21
+ export declare const agentInfoWrapper: (agent: AgentFunction<any, any, any, any>) => AgentFunctionInfo;
36
22
  export declare const debugResultKey: (agentId: string, result: any) => string[];
37
23
  export declare const isLogicallyTrue: (value: any) => boolean;
38
24
  export declare const defaultTestContext: {
@@ -40,6 +26,8 @@ export declare const defaultTestContext: {
40
26
  nodeId: string;
41
27
  retry: number;
42
28
  verbose: boolean;
29
+ state: NodeState;
30
+ subGraphs: Map<any, any>;
43
31
  };
44
32
  params: {};
45
33
  filterParams: {};
@@ -47,3 +35,5 @@ export declare const defaultTestContext: {
47
35
  log: never[];
48
36
  };
49
37
  export declare const isNamedInputs: <NamedInput = DefaultInputData>(namedInputs: NamedInput) => boolean;
38
+ export declare const isComputedNodeData: (node: NodeData) => node is ComputedNodeData;
39
+ export declare const isStaticNodeData: (node: NodeData) => node is StaticNodeData;
@@ -1,7 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.isNamedInputs = exports.defaultTestContext = exports.isLogicallyTrue = exports.debugResultKey = exports.agentInfoWrapper = exports.defaultAgentInfo = exports.strIntentionalError = exports.isNull = exports.isObject = exports.parseNodeName = exports.sleep = void 0;
3
+ exports.isStaticNodeData = exports.isComputedNodeData = exports.isNamedInputs = exports.defaultTestContext = exports.isLogicallyTrue = exports.debugResultKey = exports.agentInfoWrapper = exports.defaultAgentInfo = exports.strIntentionalError = exports.isNull = exports.isObject = exports.parseNodeName = exports.sleep = void 0;
4
4
  exports.assert = assert;
5
+ const type_1 = require("../type");
5
6
  const sleep = async (milliseconds) => {
6
7
  return await new Promise((resolve) => setTimeout(resolve, milliseconds));
7
8
  };
@@ -118,6 +119,8 @@ exports.defaultTestContext = {
118
119
  nodeId: "test",
119
120
  retry: 0,
120
121
  verbose: true,
122
+ state: type_1.NodeState.Executing,
123
+ subGraphs: new Map(),
121
124
  },
122
125
  params: {},
123
126
  filterParams: {},
@@ -128,3 +131,11 @@ const isNamedInputs = (namedInputs) => {
128
131
  return (0, exports.isObject)(namedInputs) && !Array.isArray(namedInputs) && Object.keys(namedInputs || {}).length > 0;
129
132
  };
130
133
  exports.isNamedInputs = isNamedInputs;
134
+ const isComputedNodeData = (node) => {
135
+ return "agent" in node;
136
+ };
137
+ exports.isComputedNodeData = isComputedNodeData;
138
+ const isStaticNodeData = (node) => {
139
+ return !("agent" in node);
140
+ };
141
+ exports.isStaticNodeData = isStaticNodeData;
package/lib/validator.js CHANGED
@@ -1,6 +1,7 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.validateAgent = exports.validateGraphData = void 0;
4
+ const utils_1 = require("./utils/utils");
4
5
  const graph_data_validator_1 = require("./validators/graph_data_validator");
5
6
  const nodeValidator_1 = require("./validators/nodeValidator");
6
7
  const static_node_validator_1 = require("./validators/static_node_validator");
@@ -16,7 +17,7 @@ const validateGraphData = (data, agentIds) => {
16
17
  const graphAgentIds = new Set();
17
18
  Object.keys(data.nodes).forEach((nodeId) => {
18
19
  const node = data.nodes[nodeId];
19
- const isStaticNode = !("agent" in node);
20
+ const isStaticNode = (0, utils_1.isStaticNodeData)(node);
20
21
  (0, nodeValidator_1.nodeValidator)(node);
21
22
  const agentId = isStaticNode ? "" : node.agent;
22
23
  isStaticNode && (0, static_node_validator_1.staticNodeValidator)(node) && staticNodeIds.push(nodeId);
@@ -24,7 +24,7 @@ const relationValidator = (graphData, staticNodeIds, computedNodeIds) => {
24
24
  }
25
25
  });
26
26
  };
27
- if ("agent" in nodeData && nodeData) {
27
+ if (nodeData && (0, utils_1.isComputedNodeData)(nodeData)) {
28
28
  if (nodeData.inputs) {
29
29
  const sourceNodeIds = (0, nodeUtils_1.dataSourceNodeIds)((0, nodeUtils_1.inputs2dataSources)(nodeData.inputs));
30
30
  dataSourceValidator("Inputs", sourceNodeIds);
@@ -54,7 +54,7 @@ const relationValidator = (graphData, staticNodeIds, computedNodeIds) => {
54
54
  // TODO. validate update
55
55
  staticNodeIds.forEach((staticNodeId) => {
56
56
  const nodeData = graphData.nodes[staticNodeId];
57
- if ("value" in nodeData && nodeData.update) {
57
+ if ((0, utils_1.isStaticNodeData)(nodeData) && nodeData.update) {
58
58
  const update = nodeData.update;
59
59
  const updateNodeId = (0, utils_1.parseNodeName)(update).nodeId;
60
60
  if (!updateNodeId) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "graphai",
3
- "version": "0.6.18",
3
+ "version": "0.6.20",
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.5"
30
+ "typedoc": "^0.27.6"
31
31
  },
32
32
  "types": "./lib/index.d.ts",
33
33
  "directories": {