@loopstack/accessing-tool-results-example-workflow 0.21.3 → 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 +25 -46
- package/dist/tool-results-example.module.d.ts.map +1 -1
- package/dist/tool-results-example.module.js +0 -4
- package/dist/tool-results-example.module.js.map +1 -1
- package/dist/workflow-tool-results.workflow.d.ts +0 -2
- package/dist/workflow-tool-results.workflow.d.ts.map +1 -1
- package/dist/workflow-tool-results.workflow.js +7 -24
- package/dist/workflow-tool-results.workflow.js.map +1 -1
- package/package.json +5 -7
- package/src/__tests__/workflow-tool-results.workflow.spec.ts +46 -62
- package/src/tool-results-example.module.ts +0 -4
- package/src/workflow-tool-results.workflow.ts +8 -19
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
|
|
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
|
|
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
|
-
-
|
|
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
|
|
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.
|
|
40
|
+
#### 1. Storing Data in State
|
|
45
41
|
|
|
46
|
-
In a transition method,
|
|
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
|
-
|
|
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.
|
|
49
|
+
await this.repository.save(MessageDocument, {
|
|
60
50
|
role: 'assistant',
|
|
61
|
-
content: `
|
|
51
|
+
content: `Stored in initial transition: ${this.storedMessage}`,
|
|
62
52
|
});
|
|
63
53
|
}
|
|
64
54
|
```
|
|
65
55
|
|
|
66
|
-
The
|
|
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.
|
|
65
|
+
await this.repository.save(MessageDocument, {
|
|
76
66
|
role: 'assistant',
|
|
77
|
-
content: `
|
|
67
|
+
content: `Accessed from previous transition: ${this.storedMessage}`,
|
|
78
68
|
});
|
|
79
69
|
|
|
80
|
-
await this.
|
|
70
|
+
await this.repository.save(MessageDocument, {
|
|
81
71
|
role: 'assistant',
|
|
82
|
-
content: `
|
|
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,
|
|
103
|
-
import {
|
|
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
|
-
|
|
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.
|
|
105
|
+
await this.repository.save(MessageDocument, {
|
|
126
106
|
role: 'assistant',
|
|
127
|
-
content: `
|
|
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.
|
|
113
|
+
await this.repository.save(MessageDocument, {
|
|
134
114
|
role: 'assistant',
|
|
135
|
-
content: `
|
|
115
|
+
content: `Accessed from previous transition: ${this.storedMessage}`,
|
|
136
116
|
});
|
|
137
117
|
|
|
138
|
-
await this.
|
|
118
|
+
await this.repository.save(MessageDocument, {
|
|
139
119
|
role: 'assistant',
|
|
140
|
-
content: `
|
|
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/
|
|
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:
|
|
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":"
|
|
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,
|
|
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 +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,
|
|
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
|
-
|
|
22
|
-
this.
|
|
23
|
-
await this.createChatMessage.call({
|
|
17
|
+
this.storedMessage = 'Hello World.';
|
|
18
|
+
await this.repository.save(common_1.MessageDocument, {
|
|
24
19
|
role: 'assistant',
|
|
25
|
-
content: `
|
|
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.
|
|
24
|
+
await this.repository.save(common_1.MessageDocument, {
|
|
34
25
|
role: 'assistant',
|
|
35
|
-
content: `
|
|
26
|
+
content: `Accessed from previous transition: ${this.storedMessage}`,
|
|
36
27
|
});
|
|
37
|
-
await this.
|
|
28
|
+
await this.repository.save(common_1.MessageDocument, {
|
|
38
29
|
role: 'assistant',
|
|
39
|
-
content: `
|
|
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,
|
|
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.
|
|
14
|
-
"license": "
|
|
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,11 +31,9 @@
|
|
|
31
31
|
"watch": "nest build --watch"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@loopstack/common": "^0.
|
|
35
|
-
"@loopstack/core": "^0.
|
|
36
|
-
"@
|
|
37
|
-
"@loopstack/create-value-tool": "^0.21.3",
|
|
38
|
-
"@nestjs/common": "^11.1.14",
|
|
34
|
+
"@loopstack/common": "^0.26.0",
|
|
35
|
+
"@loopstack/core": "^0.26.0",
|
|
36
|
+
"@nestjs/common": "^11.1.19",
|
|
39
37
|
"zod": "^4.3.6"
|
|
40
38
|
},
|
|
41
39
|
"files": [
|
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
import { TestingModule } from '@nestjs/testing';
|
|
2
|
-
import {
|
|
3
|
-
import {
|
|
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('
|
|
40
|
-
it('should
|
|
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
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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
|
|
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(
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
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
|
|
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
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
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,
|
|
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
|
-
|
|
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.
|
|
13
|
+
await this.repository.save(MessageDocument, {
|
|
25
14
|
role: 'assistant',
|
|
26
|
-
content: `
|
|
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.
|
|
21
|
+
await this.repository.save(MessageDocument, {
|
|
33
22
|
role: 'assistant',
|
|
34
|
-
content: `
|
|
23
|
+
content: `Accessed from previous transition: ${this.storedMessage}`,
|
|
35
24
|
});
|
|
36
25
|
|
|
37
|
-
await this.
|
|
26
|
+
await this.repository.save(MessageDocument, {
|
|
38
27
|
role: 'assistant',
|
|
39
|
-
content: `
|
|
28
|
+
content: `Accessed via helper method: ${this.theMessage()}`,
|
|
40
29
|
});
|
|
41
30
|
}
|
|
42
31
|
|