@loopstack/accessing-tool-results-example-workflow 0.21.2 → 0.21.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/README.md CHANGED
@@ -2,16 +2,15 @@
2
2
 
3
3
  > A module for the [Loopstack AI](https://loopstack.ai) automation framework.
4
4
 
5
- This module provides an example workflow demonstrating different methods for accessing tool results within and across workflow transitions.
5
+ This module provides an example workflow demonstrating how to store and access data across workflow transitions using instance properties.
6
6
 
7
7
  ## Overview
8
8
 
9
- The Tool Results Example Workflow shows how to retrieve and use data returned by tools in subsequent workflow steps. Understanding these patterns is essential for building workflows that pass data between operations.
9
+ The Workflow State Example shows how to persist data between transitions using class instance properties. Understanding these patterns is essential for building workflows that pass data between operations.
10
10
 
11
11
  By using this workflow as a reference, you'll learn how to:
12
12
 
13
- - Call tools using `@InjectTool()` and access their return values directly
14
- - Store tool results as workflow instance properties for use across transitions
13
+ - Store data as workflow instance properties for use across transitions
15
14
  - Access stored data in later transitions via instance properties
16
15
  - Create private helper methods to encapsulate data access logic
17
16
 
@@ -25,45 +24,36 @@ See [SETUP.md](./SETUP.md) for installation and setup instructions.
25
24
 
26
25
  ### Workflow Class
27
26
 
28
- The workflow extends `BaseWorkflow` and declares tools via `@InjectTool()`. Tool results are stored as instance properties and accessed across transitions:
27
+ The workflow extends `BaseWorkflow` and stores data as instance properties that persist across transitions:
29
28
 
30
29
  ```typescript
31
30
  @Workflow({
32
31
  uiConfig: __dirname + '/workflow-tool-results.ui.yaml',
33
32
  })
34
33
  export class WorkflowToolResultsWorkflow extends BaseWorkflow {
35
- @InjectTool() private createValue: CreateValue;
36
- @InjectTool() private createChatMessage: CreateChatMessage;
37
-
38
34
  storedMessage?: string;
39
35
  }
40
36
  ```
41
37
 
42
38
  ### Key Concepts
43
39
 
44
- #### 1. Calling Tools and Storing Results
40
+ #### 1. Storing Data in State
45
41
 
46
- In a transition method, call a tool with `this.tool.call(args)` and store the result as an instance property:
42
+ In a transition method, assign values to instance properties:
47
43
 
48
44
  ```typescript
49
45
  @Initial({ to: 'data_created' })
50
46
  async createSomeData() {
51
- const result = await this.createValue.call({ input: 'Hello World.' });
52
- this.storedMessage = result.data as string;
53
-
54
- await this.createChatMessage.call({
55
- role: 'assistant',
56
- content: `Data from specific call id: ${this.storedMessage}`,
57
- });
47
+ this.storedMessage = 'Hello World.';
58
48
 
59
- await this.createChatMessage.call({
49
+ await this.repository.save(MessageDocument, {
60
50
  role: 'assistant',
61
- content: `Data from first tool call: ${this.storedMessage}`,
51
+ content: `Stored in initial transition: ${this.storedMessage}`,
62
52
  });
63
53
  }
64
54
  ```
65
55
 
66
- The `createValue` tool returns a `ToolResult` object with a `data` property containing the output. This value is stored in `this.storedMessage` for later use.
56
+ The value is stored in `this.storedMessage` for later use.
67
57
 
68
58
  #### 2. Accessing Data Across Transitions
69
59
 
@@ -72,14 +62,14 @@ Instance properties persist across transitions. In a subsequent `@Final` method,
72
62
  ```typescript
73
63
  @Final({ from: 'data_created' })
74
64
  async accessData() {
75
- await this.createChatMessage.call({
65
+ await this.repository.save(MessageDocument, {
76
66
  role: 'assistant',
77
- content: `Data from previous transition: ${this.storedMessage}`,
67
+ content: `Accessed from previous transition: ${this.storedMessage}`,
78
68
  });
79
69
 
80
- await this.createChatMessage.call({
70
+ await this.repository.save(MessageDocument, {
81
71
  role: 'assistant',
82
- content: `Data access using custom helper: ${this.theMessage()}`,
72
+ content: `Accessed via helper method: ${this.theMessage()}`,
83
73
  });
84
74
  }
85
75
  ```
@@ -99,45 +89,35 @@ These are standard TypeScript methods -- no decorator needed. Call them from any
99
89
  ### Complete Workflow
100
90
 
101
91
  ```typescript
102
- import { BaseWorkflow, Final, Initial, InjectTool, Workflow } from '@loopstack/common';
103
- import { CreateChatMessage } from '@loopstack/create-chat-message-tool';
104
- import { CreateValue } from '@loopstack/create-value-tool';
92
+ import { BaseWorkflow, Final, Initial, Workflow } from '@loopstack/common';
93
+ import { MessageDocument } from '@loopstack/common';
105
94
 
106
95
  @Workflow({
107
96
  uiConfig: __dirname + '/workflow-tool-results.ui.yaml',
108
97
  })
109
98
  export class WorkflowToolResultsWorkflow extends BaseWorkflow {
110
- @InjectTool() private createValue: CreateValue;
111
- @InjectTool() private createChatMessage: CreateChatMessage;
112
-
113
99
  storedMessage?: string;
114
100
 
115
101
  @Initial({ to: 'data_created' })
116
102
  async createSomeData() {
117
- const result = await this.createValue.call({ input: 'Hello World.' });
118
- this.storedMessage = result.data as string;
119
-
120
- await this.createChatMessage.call({
121
- role: 'assistant',
122
- content: `Data from specific call id: ${this.storedMessage}`,
123
- });
103
+ this.storedMessage = 'Hello World.';
124
104
 
125
- await this.createChatMessage.call({
105
+ await this.repository.save(MessageDocument, {
126
106
  role: 'assistant',
127
- content: `Data from first tool call: ${this.storedMessage}`,
107
+ content: `Stored in initial transition: ${this.storedMessage}`,
128
108
  });
129
109
  }
130
110
 
131
111
  @Final({ from: 'data_created' })
132
112
  async accessData() {
133
- await this.createChatMessage.call({
113
+ await this.repository.save(MessageDocument, {
134
114
  role: 'assistant',
135
- content: `Data from previous transition: ${this.storedMessage}`,
115
+ content: `Accessed from previous transition: ${this.storedMessage}`,
136
116
  });
137
117
 
138
- await this.createChatMessage.call({
118
+ await this.repository.save(MessageDocument, {
139
119
  role: 'assistant',
140
- content: `Data access using custom helper: ${this.theMessage()}`,
120
+ content: `Accessed via helper method: ${this.theMessage()}`,
141
121
  });
142
122
  }
143
123
 
@@ -152,14 +132,13 @@ export class WorkflowToolResultsWorkflow extends BaseWorkflow {
152
132
  This workflow uses the following Loopstack modules:
153
133
 
154
134
  - `@loopstack/common` - Base classes, decorators, and tool injection
155
- - `@loopstack/create-chat-message-tool` - Provides `CreateChatMessage` tool
156
- - `@loopstack/create-value-tool` - Provides `CreateValue` tool
135
+ - `@loopstack/common` - Provides `MessageDocument` for chat messages
157
136
 
158
137
  ## About
159
138
 
160
139
  Author: [Jakob Klippel](https://www.linkedin.com/in/jakob-klippel/)
161
140
 
162
- License: Apache-2.0
141
+ License: MIT
163
142
 
164
143
  ### Additional Resources
165
144
 
@@ -1 +1 @@
1
- {"version":3,"file":"tool-results-example.module.d.ts","sourceRoot":"","sources":["../src/tool-results-example.module.ts"],"names":[],"mappings":"AAMA,qBAKa,wBAAwB;CAAG"}
1
+ {"version":3,"file":"tool-results-example.module.d.ts","sourceRoot":"","sources":["../src/tool-results-example.module.ts"],"names":[],"mappings":"AAGA,qBAIa,wBAAwB;CAAG"}
@@ -8,16 +8,12 @@ var __decorate = (this && this.__decorate) || function (decorators, target, key,
8
8
  Object.defineProperty(exports, "__esModule", { value: true });
9
9
  exports.ToolResultsExampleModule = void 0;
10
10
  const common_1 = require("@nestjs/common");
11
- const core_1 = require("@loopstack/core");
12
- const create_chat_message_tool_1 = require("@loopstack/create-chat-message-tool");
13
- const create_value_tool_1 = require("@loopstack/create-value-tool");
14
11
  const workflow_tool_results_workflow_1 = require("./workflow-tool-results.workflow");
15
12
  let ToolResultsExampleModule = class ToolResultsExampleModule {
16
13
  };
17
14
  exports.ToolResultsExampleModule = ToolResultsExampleModule;
18
15
  exports.ToolResultsExampleModule = ToolResultsExampleModule = __decorate([
19
16
  (0, common_1.Module)({
20
- imports: [core_1.LoopCoreModule, create_value_tool_1.CreateValueToolModule, create_chat_message_tool_1.CreateChatMessageToolModule],
21
17
  providers: [workflow_tool_results_workflow_1.WorkflowToolResultsWorkflow],
22
18
  exports: [workflow_tool_results_workflow_1.WorkflowToolResultsWorkflow],
23
19
  })
@@ -1 +1 @@
1
- {"version":3,"file":"tool-results-example.module.js","sourceRoot":"","sources":["../src/tool-results-example.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwC;AACxC,0CAAiD;AACjD,kFAAkF;AAClF,oEAAqE;AACrE,qFAA+E;AAOxE,IAAM,wBAAwB,GAA9B,MAAM,wBAAwB;CAAG,CAAA;AAA3B,4DAAwB;mCAAxB,wBAAwB;IALpC,IAAA,eAAM,EAAC;QACN,OAAO,EAAE,CAAC,qBAAc,EAAE,yCAAqB,EAAE,sDAA2B,CAAC;QAC7E,SAAS,EAAE,CAAC,4DAA2B,CAAC;QACxC,OAAO,EAAE,CAAC,4DAA2B,CAAC;KACvC,CAAC;GACW,wBAAwB,CAAG"}
1
+ {"version":3,"file":"tool-results-example.module.js","sourceRoot":"","sources":["../src/tool-results-example.module.ts"],"names":[],"mappings":";;;;;;;;;AAAA,2CAAwC;AACxC,qFAA+E;AAMxE,IAAM,wBAAwB,GAA9B,MAAM,wBAAwB;CAAG,CAAA;AAA3B,4DAAwB;mCAAxB,wBAAwB;IAJpC,IAAA,eAAM,EAAC;QACN,SAAS,EAAE,CAAC,4DAA2B,CAAC;QACxC,OAAO,EAAE,CAAC,4DAA2B,CAAC;KACvC,CAAC;GACW,wBAAwB,CAAG"}
@@ -1,7 +1,5 @@
1
1
  import { BaseWorkflow } from '@loopstack/common';
2
2
  export declare class WorkflowToolResultsWorkflow extends BaseWorkflow {
3
- private createValue;
4
- private createChatMessage;
5
3
  storedMessage?: string;
6
4
  createSomeData(): Promise<void>;
7
5
  accessData(): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"workflow-tool-results.workflow.d.ts","sourceRoot":"","sources":["../src/workflow-tool-results.workflow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAwC,MAAM,mBAAmB,CAAC;AAIvF,qBAGa,2BAA4B,SAAQ,YAAY;IAC7C,OAAO,CAAC,WAAW,CAAc;IACjC,OAAO,CAAC,iBAAiB,CAAoB;IAE3D,aAAa,CAAC,EAAE,MAAM,CAAC;IAGjB,cAAc;IAgBd,UAAU;IAYhB,OAAO,CAAC,UAAU;CAGnB"}
1
+ {"version":3,"file":"workflow-tool-results.workflow.d.ts","sourceRoot":"","sources":["../src/workflow-tool-results.workflow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAA6C,MAAM,mBAAmB,CAAC;AAE5F,qBAGa,2BAA4B,SAAQ,YAAY;IAC3D,aAAa,CAAC,EAAE,MAAM,CAAC;IAGjB,cAAc;IAUd,UAAU;IAYhB,OAAO,CAAC,UAAU;CAGnB"}
@@ -11,32 +11,23 @@ var __metadata = (this && this.__metadata) || function (k, v) {
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.WorkflowToolResultsWorkflow = void 0;
13
13
  const common_1 = require("@loopstack/common");
14
- const create_chat_message_tool_1 = require("@loopstack/create-chat-message-tool");
15
- const create_value_tool_1 = require("@loopstack/create-value-tool");
16
14
  let WorkflowToolResultsWorkflow = class WorkflowToolResultsWorkflow extends common_1.BaseWorkflow {
17
- createValue;
18
- createChatMessage;
19
15
  storedMessage;
20
16
  async createSomeData() {
21
- const result = await this.createValue.call({ input: 'Hello World.' });
22
- this.storedMessage = result.data;
23
- await this.createChatMessage.call({
17
+ this.storedMessage = 'Hello World.';
18
+ await this.repository.save(common_1.MessageDocument, {
24
19
  role: 'assistant',
25
- content: `Data from specific call id: ${this.storedMessage}`,
26
- });
27
- await this.createChatMessage.call({
28
- role: 'assistant',
29
- content: `Data from first tool call: ${this.storedMessage}`,
20
+ content: `Stored in initial transition: ${this.storedMessage}`,
30
21
  });
31
22
  }
32
23
  async accessData() {
33
- await this.createChatMessage.call({
24
+ await this.repository.save(common_1.MessageDocument, {
34
25
  role: 'assistant',
35
- content: `Data from previous transition: ${this.storedMessage}`,
26
+ content: `Accessed from previous transition: ${this.storedMessage}`,
36
27
  });
37
- await this.createChatMessage.call({
28
+ await this.repository.save(common_1.MessageDocument, {
38
29
  role: 'assistant',
39
- content: `Data access using custom helper: ${this.theMessage()}`,
30
+ content: `Accessed via helper method: ${this.theMessage()}`,
40
31
  });
41
32
  }
42
33
  theMessage() {
@@ -44,14 +35,6 @@ let WorkflowToolResultsWorkflow = class WorkflowToolResultsWorkflow extends comm
44
35
  }
45
36
  };
46
37
  exports.WorkflowToolResultsWorkflow = WorkflowToolResultsWorkflow;
47
- __decorate([
48
- (0, common_1.InjectTool)(),
49
- __metadata("design:type", create_value_tool_1.CreateValue)
50
- ], WorkflowToolResultsWorkflow.prototype, "createValue", void 0);
51
- __decorate([
52
- (0, common_1.InjectTool)(),
53
- __metadata("design:type", create_chat_message_tool_1.CreateChatMessage)
54
- ], WorkflowToolResultsWorkflow.prototype, "createChatMessage", void 0);
55
38
  __decorate([
56
39
  (0, common_1.Initial)({ to: 'data_created' }),
57
40
  __metadata("design:type", Function),
@@ -1 +1 @@
1
- {"version":3,"file":"workflow-tool-results.workflow.js","sourceRoot":"","sources":["../src/workflow-tool-results.workflow.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,8CAAuF;AACvF,kFAAwE;AACxE,oEAA2D;AAKpD,IAAM,2BAA2B,GAAjC,MAAM,2BAA4B,SAAQ,qBAAY;IACrC,WAAW,CAAc;IACzB,iBAAiB,CAAoB;IAE3D,aAAa,CAAU;IAGjB,AAAN,KAAK,CAAC,cAAc;QAClB,MAAM,MAAM,GAAG,MAAM,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,cAAc,EAAE,CAAC,CAAC;QACtE,IAAI,CAAC,aAAa,GAAG,MAAM,CAAC,IAAc,CAAC;QAE3C,MAAM,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC;YAChC,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,+BAA+B,IAAI,CAAC,aAAa,EAAE;SAC7D,CAAC,CAAC;QAEH,MAAM,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC;YAChC,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,8BAA8B,IAAI,CAAC,aAAa,EAAE;SAC5D,CAAC,CAAC;IACL,CAAC;IAGK,AAAN,KAAK,CAAC,UAAU;QACd,MAAM,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC;YAChC,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,kCAAkC,IAAI,CAAC,aAAa,EAAE;SAChE,CAAC,CAAC;QAEH,MAAM,IAAI,CAAC,iBAAiB,CAAC,IAAI,CAAC;YAChC,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,oCAAoC,IAAI,CAAC,UAAU,EAAE,EAAE;SACjE,CAAC,CAAC;IACL,CAAC;IAEO,UAAU;QAChB,OAAO,IAAI,CAAC,aAAc,CAAC;IAC7B,CAAC;CACF,CAAA;AAtCY,kEAA2B;AAChB;IAArB,IAAA,mBAAU,GAAE;8BAAsB,+BAAW;gEAAC;AACzB;IAArB,IAAA,mBAAU,GAAE;8BAA4B,4CAAiB;sEAAC;AAKrD;IADL,IAAA,gBAAO,EAAC,EAAE,EAAE,EAAE,cAAc,EAAE,CAAC;;;;iEAc/B;AAGK;IADL,IAAA,cAAK,EAAC,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC;;;;6DAW/B;sCAjCU,2BAA2B;IAHvC,IAAA,iBAAQ,EAAC;QACR,QAAQ,EAAE,SAAS,GAAG,gCAAgC;KACvD,CAAC;GACW,2BAA2B,CAsCvC"}
1
+ {"version":3,"file":"workflow-tool-results.workflow.js","sourceRoot":"","sources":["../src/workflow-tool-results.workflow.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,8CAA4F;AAKrF,IAAM,2BAA2B,GAAjC,MAAM,2BAA4B,SAAQ,qBAAY;IAC3D,aAAa,CAAU;IAGjB,AAAN,KAAK,CAAC,cAAc;QAClB,IAAI,CAAC,aAAa,GAAG,cAAc,CAAC;QAEpC,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,wBAAe,EAAE;YAC1C,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,iCAAiC,IAAI,CAAC,aAAa,EAAE;SAC/D,CAAC,CAAC;IACL,CAAC;IAGK,AAAN,KAAK,CAAC,UAAU;QACd,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,wBAAe,EAAE;YAC1C,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,sCAAsC,IAAI,CAAC,aAAa,EAAE;SACpE,CAAC,CAAC;QAEH,MAAM,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,wBAAe,EAAE;YAC1C,IAAI,EAAE,WAAW;YACjB,OAAO,EAAE,+BAA+B,IAAI,CAAC,UAAU,EAAE,EAAE;SAC5D,CAAC,CAAC;IACL,CAAC;IAEO,UAAU;QAChB,OAAO,IAAI,CAAC,aAAc,CAAC;IAC7B,CAAC;CACF,CAAA;AA7BY,kEAA2B;AAIhC;IADL,IAAA,gBAAO,EAAC,EAAE,EAAE,EAAE,cAAc,EAAE,CAAC;;;;iEAQ/B;AAGK;IADL,IAAA,cAAK,EAAC,EAAE,IAAI,EAAE,cAAc,EAAE,CAAC;;;;6DAW/B;sCAxBU,2BAA2B;IAHvC,IAAA,iBAAQ,EAAC;QACR,QAAQ,EAAE,SAAS,GAAG,gCAAgC;KACvD,CAAC;GACW,2BAA2B,CA6BvC"}
package/package.json CHANGED
@@ -10,8 +10,8 @@
10
10
  "tool",
11
11
  "workflow"
12
12
  ],
13
- "version": "0.21.2",
14
- "license": "Apache-2.0",
13
+ "version": "0.21.4",
14
+ "license": "MIT",
15
15
  "author": {
16
16
  "name": "Jakob Klippel",
17
17
  "url": "https://www.linkedin.com/in/jakob-klippel/"
@@ -31,10 +31,8 @@
31
31
  "watch": "nest build --watch"
32
32
  },
33
33
  "dependencies": {
34
- "@loopstack/common": "^0.25.1",
35
- "@loopstack/core": "^0.25.1",
36
- "@loopstack/create-chat-message-tool": "^0.21.2",
37
- "@loopstack/create-value-tool": "^0.21.2",
34
+ "@loopstack/common": "^0.26.0",
35
+ "@loopstack/core": "^0.26.0",
38
36
  "@nestjs/common": "^11.1.19",
39
37
  "zod": "^4.3.6"
40
38
  },
@@ -51,12 +49,7 @@
51
49
  "rootDir": "src",
52
50
  "testRegex": ".*\\.spec\\.ts$",
53
51
  "transform": {
54
- "^.+\\.ts$": [
55
- "ts-jest",
56
- {
57
- "tsconfig": "tsconfig.spec.json"
58
- }
59
- ]
52
+ "^.+\\.ts$": "ts-jest"
60
53
  },
61
54
  "collectCoverageFrom": [
62
55
  "**/*.(t|j)s"
@@ -1,8 +1,6 @@
1
1
  import { TestingModule } from '@nestjs/testing';
2
- import { LoopCoreModule, WorkflowProcessorService } from '@loopstack/core';
3
- import { CreateChatMessage, CreateChatMessageToolModule } from '@loopstack/create-chat-message-tool';
4
- import { CreateValue, CreateValueToolModule } from '@loopstack/create-value-tool';
5
- import { ToolMock, createStatelessContext, createWorkflowTest } from '@loopstack/testing';
2
+ import { WorkflowProcessorService } from '@loopstack/core';
3
+ import { createStatelessContext, createWorkflowTest } from '@loopstack/testing';
6
4
  import { WorkflowToolResultsWorkflow } from '../workflow-tool-results.workflow';
7
5
 
8
6
  describe('WorkflowToolResultsWorkflow', () => {
@@ -10,22 +8,11 @@ describe('WorkflowToolResultsWorkflow', () => {
10
8
  let workflow: WorkflowToolResultsWorkflow;
11
9
  let processor: WorkflowProcessorService;
12
10
 
13
- let mockCreateValue: ToolMock;
14
- let mockCreateChatMessage: ToolMock;
15
-
16
11
  beforeEach(async () => {
17
- module = await createWorkflowTest()
18
- .forWorkflow(WorkflowToolResultsWorkflow)
19
- .withImports(LoopCoreModule, CreateValueToolModule, CreateChatMessageToolModule)
20
- .withToolOverride(CreateValue)
21
- .withToolOverride(CreateChatMessage)
22
- .compile();
12
+ module = await createWorkflowTest().forWorkflow(WorkflowToolResultsWorkflow).compile();
23
13
 
24
14
  workflow = module.get(WorkflowToolResultsWorkflow);
25
15
  processor = module.get(WorkflowProcessorService);
26
-
27
- mockCreateValue = module.get(CreateValue);
28
- mockCreateChatMessage = module.get(CreateChatMessage);
29
16
  });
30
17
 
31
18
  afterEach(async () => {
@@ -36,64 +23,61 @@ describe('WorkflowToolResultsWorkflow', () => {
36
23
  expect(workflow).toBeDefined();
37
24
  });
38
25
 
39
- describe('tool result access', () => {
40
- it('should access tool results by call id and index in same transition', async () => {
26
+ describe('state persistence across transitions', () => {
27
+ it('should store data in the initial transition', async () => {
41
28
  const context = createStatelessContext();
42
- mockCreateValue.call.mockResolvedValue({ data: 'Hello World.' });
43
- mockCreateChatMessage.call.mockResolvedValue({ data: undefined });
44
-
45
- await processor.process(workflow, {}, context);
46
-
47
- // Verify CreateValue was called
48
- expect(mockCreateValue.call).toHaveBeenCalledWith({ input: 'Hello World.' }, undefined);
49
29
 
50
- // Verify CreateChatMessage received resolved template values
51
- expect(mockCreateChatMessage.call).toHaveBeenCalledWith(
52
- {
53
- role: 'assistant',
54
- content: 'Data from specific call id: Hello World.',
55
- },
56
- undefined,
57
- );
58
-
59
- expect(mockCreateChatMessage.call).toHaveBeenCalledWith(
60
- {
61
- role: 'assistant',
62
- content: 'Data from first tool call: Hello World.',
63
- },
64
- undefined,
30
+ const result = await processor.process(workflow, {}, context);
31
+
32
+ expect(result.hasError).toBe(false);
33
+ expect(result.documents).toEqual(
34
+ expect.arrayContaining([
35
+ expect.objectContaining({
36
+ className: 'MessageDocument',
37
+ content: expect.objectContaining({
38
+ role: 'assistant',
39
+ content: 'Stored in initial transition: Hello World.',
40
+ }),
41
+ }),
42
+ ]),
65
43
  );
66
44
  });
67
45
 
68
- it('should access tool results from previous transition', async () => {
46
+ it('should access stored data from a previous transition', async () => {
69
47
  const context = createStatelessContext();
70
- mockCreateValue.call.mockResolvedValue({ data: 'Hello World.' });
71
- mockCreateChatMessage.call.mockResolvedValue({ data: undefined });
72
48
 
73
- await processor.process(workflow, {}, context);
74
-
75
- expect(mockCreateChatMessage.call).toHaveBeenCalledWith(
76
- {
77
- role: 'assistant',
78
- content: 'Data from previous transition: Hello World.',
79
- },
80
- undefined,
49
+ const result = await processor.process(workflow, {}, context);
50
+
51
+ expect(result.hasError).toBe(false);
52
+ expect(result.documents).toEqual(
53
+ expect.arrayContaining([
54
+ expect.objectContaining({
55
+ className: 'MessageDocument',
56
+ content: expect.objectContaining({
57
+ role: 'assistant',
58
+ content: 'Accessed from previous transition: Hello World.',
59
+ }),
60
+ }),
61
+ ]),
81
62
  );
82
63
  });
83
64
 
84
- it('should access tool results using custom helper', async () => {
65
+ it('should access stored data via a helper method', async () => {
85
66
  const context = createStatelessContext();
86
- mockCreateValue.call.mockResolvedValue({ data: 'Hello World.' });
87
- mockCreateChatMessage.call.mockResolvedValue({ data: undefined });
88
-
89
- await processor.process(workflow, {}, context);
90
67
 
91
- expect(mockCreateChatMessage.call).toHaveBeenCalledWith(
92
- {
93
- role: 'assistant',
94
- content: 'Data access using custom helper: Hello World.',
95
- },
96
- undefined,
68
+ const result = await processor.process(workflow, {}, context);
69
+
70
+ expect(result.hasError).toBe(false);
71
+ expect(result.documents).toEqual(
72
+ expect.arrayContaining([
73
+ expect.objectContaining({
74
+ className: 'MessageDocument',
75
+ content: expect.objectContaining({
76
+ role: 'assistant',
77
+ content: 'Accessed via helper method: Hello World.',
78
+ }),
79
+ }),
80
+ ]),
97
81
  );
98
82
  });
99
83
  });
@@ -1,11 +1,7 @@
1
1
  import { Module } from '@nestjs/common';
2
- import { LoopCoreModule } from '@loopstack/core';
3
- import { CreateChatMessageToolModule } from '@loopstack/create-chat-message-tool';
4
- import { CreateValueToolModule } from '@loopstack/create-value-tool';
5
2
  import { WorkflowToolResultsWorkflow } from './workflow-tool-results.workflow';
6
3
 
7
4
  @Module({
8
- imports: [LoopCoreModule, CreateValueToolModule, CreateChatMessageToolModule],
9
5
  providers: [WorkflowToolResultsWorkflow],
10
6
  exports: [WorkflowToolResultsWorkflow],
11
7
  })
@@ -1,42 +1,31 @@
1
- import { BaseWorkflow, Final, Initial, InjectTool, Workflow } from '@loopstack/common';
2
- import { CreateChatMessage } from '@loopstack/create-chat-message-tool';
3
- import { CreateValue } from '@loopstack/create-value-tool';
1
+ import { BaseWorkflow, Final, Initial, MessageDocument, Workflow } from '@loopstack/common';
4
2
 
5
3
  @Workflow({
6
4
  uiConfig: __dirname + '/workflow-tool-results.ui.yaml',
7
5
  })
8
6
  export class WorkflowToolResultsWorkflow extends BaseWorkflow {
9
- @InjectTool() private createValue: CreateValue;
10
- @InjectTool() private createChatMessage: CreateChatMessage;
11
-
12
7
  storedMessage?: string;
13
8
 
14
9
  @Initial({ to: 'data_created' })
15
10
  async createSomeData() {
16
- const result = await this.createValue.call({ input: 'Hello World.' });
17
- this.storedMessage = result.data as string;
18
-
19
- await this.createChatMessage.call({
20
- role: 'assistant',
21
- content: `Data from specific call id: ${this.storedMessage}`,
22
- });
11
+ this.storedMessage = 'Hello World.';
23
12
 
24
- await this.createChatMessage.call({
13
+ await this.repository.save(MessageDocument, {
25
14
  role: 'assistant',
26
- content: `Data from first tool call: ${this.storedMessage}`,
15
+ content: `Stored in initial transition: ${this.storedMessage}`,
27
16
  });
28
17
  }
29
18
 
30
19
  @Final({ from: 'data_created' })
31
20
  async accessData() {
32
- await this.createChatMessage.call({
21
+ await this.repository.save(MessageDocument, {
33
22
  role: 'assistant',
34
- content: `Data from previous transition: ${this.storedMessage}`,
23
+ content: `Accessed from previous transition: ${this.storedMessage}`,
35
24
  });
36
25
 
37
- await this.createChatMessage.call({
26
+ await this.repository.save(MessageDocument, {
38
27
  role: 'assistant',
39
- content: `Data access using custom helper: ${this.theMessage()}`,
28
+ content: `Accessed via helper method: ${this.theMessage()}`,
40
29
  });
41
30
  }
42
31