ai-sdk-graph 0.1.3 → 0.2.0

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.
Files changed (2) hide show
  1. package/dist/index.js +29 -19
  2. package/package.json +1 -1
package/dist/index.js CHANGED
@@ -98,8 +98,12 @@ class Graph {
98
98
  let context;
99
99
  return createUIMessageStream({
100
100
  execute: async ({ writer }) => {
101
- context = await this.createExecutionContext(runId, initialState, writer);
102
- await this.onStart({ state: context.state, writer });
101
+ const result = await this.createExecutionContext(runId, initialState, writer);
102
+ context = result.context;
103
+ const firstTime = result.firstTime;
104
+ if (firstTime) {
105
+ await this.onStart({ state: context.state, writer });
106
+ }
103
107
  await this.runExecutionLoop(context);
104
108
  },
105
109
  onFinish: async () => {
@@ -110,7 +114,7 @@ class Graph {
110
114
  });
111
115
  }
112
116
  async executeInternal(runId, initialState, writer) {
113
- const context = await this.createExecutionContext(runId, initialState, writer);
117
+ const { context } = await this.createExecutionContext(runId, initialState, writer);
114
118
  await this.runExecutionLoopInternal(context);
115
119
  return context.state;
116
120
  }
@@ -124,8 +128,8 @@ class Graph {
124
128
  this.edgeRegistry.set(edge.from, existingEdges);
125
129
  }
126
130
  async createExecutionContext(runId, initialState, writer) {
127
- const restored = await this.restoreCheckpoint(runId, initialState);
128
- return { runId, writer, ...restored };
131
+ const { context, firstTime } = await this.restoreCheckpoint(runId, initialState, writer);
132
+ return { context: { ...context, runId, writer }, firstTime };
129
133
  }
130
134
  async runExecutionLoop(context) {
131
135
  await this.executeWithStrategy(context, "return");
@@ -174,12 +178,12 @@ class Graph {
174
178
  hasNodesToExecute(context) {
175
179
  return context.currentNodes.length > 0;
176
180
  }
177
- async restoreCheckpoint(runId, initialState) {
181
+ async restoreCheckpoint(runId, initialState, writer) {
178
182
  const checkpoint = await this.storage.load(runId);
179
183
  if (this.isValidCheckpoint(checkpoint)) {
180
- return this.restoreFromCheckpoint(checkpoint, initialState);
184
+ return { context: this.restoreFromCheckpoint(checkpoint, initialState, writer), firstTime: false };
181
185
  }
182
- return this.createFreshExecution(initialState);
186
+ return { context: this.createFreshExecution(initialState, writer), firstTime: true };
183
187
  }
184
188
  isValidCheckpoint(checkpoint) {
185
189
  return this.hasNodeIds(checkpoint) && this.hasAtLeastOneNode(checkpoint);
@@ -190,16 +194,16 @@ class Graph {
190
194
  hasAtLeastOneNode(checkpoint) {
191
195
  return checkpoint.nodeIds.length > 0;
192
196
  }
193
- restoreFromCheckpoint(checkpoint, initialState) {
194
- const state = this.stateManager.resolve(initialState, checkpoint.state);
197
+ restoreFromCheckpoint(checkpoint, initialState, writer) {
198
+ const state = this.stateManager.resolve(initialState, checkpoint.state, writer);
195
199
  return {
196
200
  state,
197
201
  currentNodes: this.resolveNodeIds(checkpoint.nodeIds),
198
202
  suspendedNodes: this.resolveNodeIds(checkpoint.suspendedNodes)
199
203
  };
200
204
  }
201
- createFreshExecution(initialState) {
202
- const state = this.stateManager.resolve(initialState, undefined);
205
+ createFreshExecution(initialState, writer) {
206
+ const state = this.stateManager.resolve(initialState, undefined, writer);
203
207
  const startNode = this.nodeRegistry.get(BUILT_IN_NODES.START);
204
208
  return {
205
209
  state,
@@ -242,7 +246,7 @@ class Graph {
242
246
  writer: context.writer,
243
247
  suspense: this.createSuspenseFunction(),
244
248
  update: (update) => {
245
- context.state = this.stateManager.apply(context.state, update);
249
+ context.state = this.stateManager.apply(context.state, update, context.writer);
246
250
  }
247
251
  };
248
252
  }
@@ -253,7 +257,7 @@ class Graph {
253
257
  try {
254
258
  const childFinalState = await subgraph.executeInternal(subgraphRunId, options.input(context.state), context.writer);
255
259
  const parentUpdate = options.output(childFinalState, context.state);
256
- context.state = this.stateManager.apply(context.state, parentUpdate);
260
+ context.state = this.stateManager.apply(context.state, parentUpdate, context.writer);
257
261
  this.emitter.emitEnd(context.writer, node.id);
258
262
  return null;
259
263
  } catch (error) {
@@ -312,17 +316,23 @@ class NodeEventEmitter {
312
316
  }
313
317
 
314
318
  class StateManager {
315
- apply(state, update) {
316
- return {
319
+ apply(state, update, writer) {
320
+ const newState = {
317
321
  ...state,
318
322
  ...typeof update === "function" ? update(state) : update
319
323
  };
324
+ writer.write({ type: "data-state", data: newState });
325
+ return newState;
320
326
  }
321
- resolve(initialState, existingState) {
327
+ resolve(initialState, existingState, writer) {
322
328
  if (this.isStateFactory(initialState)) {
323
- return initialState(existingState);
329
+ const newState2 = initialState(existingState);
330
+ writer.write({ type: "data-state", data: newState2 });
331
+ return newState2;
324
332
  }
325
- return existingState ?? initialState;
333
+ const newState = existingState ?? initialState;
334
+ writer.write({ type: "data-state", data: newState });
335
+ return newState;
326
336
  }
327
337
  isStateFactory(initialState) {
328
338
  return typeof initialState === "function";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ai-sdk-graph",
3
- "version": "0.1.3",
3
+ "version": "0.2.0",
4
4
  "description": "Graph-based workflows for the AI SDK",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",