@loopstack/meeting-notes-example-workflow 0.20.0 → 0.20.2

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
@@ -12,61 +12,23 @@ By using this workflow as a reference, you'll learn how to:
12
12
 
13
13
  - Use manual triggers to pause workflows for user input
14
14
  - Create interactive documents with action buttons
15
- - Handle transition payloads from user interactions
15
+ - Handle transition payloads from user interactions via `runtime.transition.payload`
16
16
  - Transform unstructured text into structured data with AI
17
17
  - Build review-and-confirm patterns for AI outputs
18
+ - Use `@State` to manage workflow state with schemas
19
+ - Use `@Input` to define workflow arguments and document content schemas
18
20
 
19
21
  This example is essential for developers building workflows that require human oversight or approval steps.
20
22
 
21
23
  ## Installation
22
24
 
23
- You can add this module using the `loopstack` cli or via `npm`.
24
-
25
- ### a) Add Sources via `loopstack add` (recommended)
26
-
27
- ```bash
28
- loopstack add @loopstack/meeting-notes-example-workflow
29
- ```
30
-
31
- This command copies the source files into your `src` directory.
32
-
33
- - It is a great way to explore the code to learn new concepts or add own customizations
34
- - It will set up the module for you, so you do not need to manually update your application
35
-
36
- ### b) Install via `npm install`
37
-
38
- ```bash
39
- npm install --save @loopstack/meeting-notes-example-workflow
40
- ```
41
-
42
- Use npm install if you want to use and maintain the module as node dependency.
43
-
44
- - Use this, if you do not need to make changes to the code or want to review the source code.
45
-
46
- ## Setup
47
-
48
- ### 1. Configure API Key
49
-
50
- Set your OpenAI API key as an environment variable:
51
-
52
- ```bash
53
- OPENAI_API_KEY=sk-...
54
- ```
55
-
56
- ### 2. Manual setup (optional)
57
-
58
- > This step is automatically done for you when using the `loopstack add` command.
59
-
60
- - Add `MeetingNotesExampleModule` to the imports of `default.module.ts` or any other custom module.
61
- - Inject the `MeetingNotesWorkflow` workflow to your workspace class using the `@InjectWorkflow()` decorator.
62
-
63
- See here for more information about working with [Modules](https://loopstack.ai/docs/building-with-loopstack/creating-a-module) and [Workspaces](https://loopstack.ai/docs/building-with-loopstack/creating-workspaces)
25
+ See [SETUP.md](./SETUP.md) for installation and setup instructions.
64
26
 
65
27
  ## How It Works
66
28
 
67
29
  ### Workflow Flow
68
30
 
69
- 1. **Start** - User provides unstructured meeting notes
31
+ 1. **Start** - User provides unstructured meeting notes via the input form
70
32
  2. **Wait for Input** - User can edit the notes, then clicks "Optimize Notes"
71
33
  3. **AI Processing** - LLM extracts structured information into a formatted document
72
34
  4. **Review** - User reviews and can edit the structured output
@@ -74,7 +36,37 @@ See here for more information about working with [Modules](https://loopstack.ai/
74
36
 
75
37
  ### Key Concepts
76
38
 
77
- #### 1. Manual Triggers
39
+ #### 1. Workflow Input and State
40
+
41
+ Define input parameters with `@Input` and workflow state with `@State`:
42
+
43
+ ```typescript
44
+ @Input({
45
+ schema: z.object({
46
+ inputText: z
47
+ .string()
48
+ .default(
49
+ '- meeting 1.1.2025\n- budget: need 2 cut costs sarah said\n...',
50
+ ),
51
+ }),
52
+ })
53
+ args: {
54
+ inputText: string;
55
+ };
56
+
57
+ @State({
58
+ schema: z.object({
59
+ meetingNotes: MeetingNotesDocumentSchema.optional(),
60
+ optimizedNotes: OptimizedMeetingNotesDocumentSchema.optional(),
61
+ }),
62
+ })
63
+ state: {
64
+ meetingNotes?: z.infer<typeof MeetingNotesDocumentSchema>;
65
+ optimizedNotes?: z.infer<typeof OptimizedMeetingNotesDocumentSchema>;
66
+ };
67
+ ```
68
+
69
+ #### 2. Manual Triggers
78
70
 
79
71
  Use `trigger: manual` to pause the workflow and wait for user interaction:
80
72
 
@@ -87,11 +79,13 @@ Use `trigger: manual` to pause the workflow and wait for user interaction:
87
79
 
88
80
  The workflow pauses at `waiting_for_response` until the user triggers the transition.
89
81
 
90
- #### 2. Document Actions with Buttons
82
+ #### 3. Document Actions with Buttons
91
83
 
92
- Add action buttons to documents that trigger transitions:
84
+ Add action buttons to documents that trigger transitions. These are defined in the document's YAML config:
93
85
 
94
86
  ```yaml
87
+ # meeting-notes-document.yaml
88
+ type: document
95
89
  ui:
96
90
  form:
97
91
  properties:
@@ -108,25 +102,52 @@ ui:
108
102
 
109
103
  When clicked, the button triggers the `user_response` transition with the current document content.
110
104
 
111
- #### 3. Transition Payloads
105
+ #### 4. Transition Payloads
112
106
 
113
- Access user input from the transition payload:
107
+ Access user input from the transition payload using `runtime.transition.payload`:
114
108
 
115
109
  ```yaml
116
110
  - id: user_response
111
+ from: waiting_for_response
112
+ to: response_received
117
113
  trigger: manual
118
114
  call:
119
- - tool: createDocument
115
+ - id: create_response
116
+ tool: createDocument
120
117
  args:
118
+ id: input
119
+ document: meetingNotesDocument
121
120
  update:
122
- content: ${ transition.payload }
121
+ content: ${{ runtime.transition.payload }}
123
122
  assign:
124
- meetingNotes: ${ result.data.content }
123
+ meetingNotes: ${{ result.data.content }}
125
124
  ```
126
125
 
127
- The `transition.payload` contains the document content when the user clicked the button.
126
+ The `runtime.transition.payload` contains the document content when the user clicked the button. The result is saved to workflow state via `assign`.
127
+
128
+ #### 5. Custom Document Schemas
128
129
 
129
- #### 4. Structured Output Documents
130
+ Define document content schemas using `@Input` on the `content` property:
131
+
132
+ ```typescript
133
+ export const MeetingNotesDocumentSchema = z.object({
134
+ text: z.string(),
135
+ });
136
+
137
+ @Document({
138
+ configFile: __dirname + '/meeting-notes-document.yaml',
139
+ })
140
+ export class MeetingNotesDocument implements DocumentInterface {
141
+ @Input({
142
+ schema: MeetingNotesDocumentSchema,
143
+ })
144
+ content: {
145
+ text: string;
146
+ };
147
+ }
148
+ ```
149
+
150
+ #### 6. Structured Output Documents
130
151
 
131
152
  Define complex document schemas for structured AI output:
132
153
 
@@ -140,14 +161,25 @@ export const OptimizedMeetingNotesDocumentSchema = z.object({
140
161
  });
141
162
  ```
142
163
 
143
- #### 5. Array Fields with Collapsible UI
144
-
145
- Configure array fields with custom item titles and collapsed display:
164
+ Configure the document UI with ordering, collapsible arrays, and confirm button:
146
165
 
147
166
  ```yaml
167
+ # optimized-notes-document.yaml
168
+ type: document
148
169
  ui:
149
170
  form:
171
+ order:
172
+ - date
173
+ - summary
174
+ - participants
175
+ - decisions
176
+ - actionItems
150
177
  properties:
178
+ date:
179
+ title: Date
180
+ summary:
181
+ title: Summary
182
+ widget: textarea
151
183
  participants:
152
184
  title: Participants
153
185
  collapsed: true
@@ -158,33 +190,40 @@ ui:
158
190
  collapsed: true
159
191
  items:
160
192
  title: Action Item
193
+ actions:
194
+ - type: button
195
+ widget: button
196
+ transition: confirm
197
+ options:
198
+ label: 'Confirm'
161
199
  ```
162
200
 
163
- #### 6. AI Document Generation
201
+ #### 7. AI Document Generation
164
202
 
165
- Use `aiGenerateDocument` to populate a structured document:
203
+ Use `aiGenerateDocument` to populate a structured document. Reference state values with `state.<name>`:
166
204
 
167
205
  ```yaml
168
- - tool: aiGenerateDocument
169
- args:
170
- llm:
171
- provider: openai
172
- model: gpt-4o
173
- response:
174
- id: final
175
- document: optimizedNotesDocument
176
- prompt: |
177
- Extract all information from the provided meeting notes into the structured document.
178
-
179
- <Meeting Notes>
180
- {{ meetingNotes.text }}
181
- </Meeting Notes>
182
- assign:
183
- optimizedNotes: ${ result.data.content }
206
+ - id: optimize_notes
207
+ from: response_received
208
+ to: notes_optimized
209
+ call:
210
+ - id: prompt
211
+ tool: aiGenerateDocument
212
+ args:
213
+ llm:
214
+ provider: openai
215
+ model: gpt-4o
216
+ response:
217
+ id: final
218
+ document: optimizedNotesDocument
219
+ prompt: |
220
+ Extract all information from the provided meeting notes into the structured document.
221
+
222
+ <Meeting Notes>
223
+ {{ state.meetingNotes.text }}
224
+ </Meeting Notes>
184
225
  ```
185
226
 
186
- The LLM automatically fills in the document fields based on the schema.
187
-
188
227
  ## Dependencies
189
228
 
190
229
  This workflow uses the following Loopstack modules:
@@ -1 +1 @@
1
- {"version":3,"file":"meeting-notes-document.d.ts","sourceRoot":"","sources":["../../src/documents/meeting-notes-document.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAY,iBAAiB,EAAS,MAAM,mBAAmB,CAAC;AAEvE,eAAO,MAAM,0BAA0B;;iBAErC,CAAC;AAEH,qBAIa,oBAAqB,YAAW,iBAAiB;IAI5D,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH"}
1
+ {"version":3,"file":"meeting-notes-document.d.ts","sourceRoot":"","sources":["../../src/documents/meeting-notes-document.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAY,iBAAiB,EAAS,MAAM,mBAAmB,CAAC;AAEvE,eAAO,MAAM,0BAA0B;;iBAErC,CAAC;AAEH,qBAGa,oBAAqB,YAAW,iBAAiB;IAI5D,OAAO,EAAE;QACP,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH"}
@@ -10,9 +10,8 @@ var __metadata = (this && this.__metadata) || function (k, v) {
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.MeetingNotesDocument = exports.MeetingNotesDocumentSchema = void 0;
13
- const common_1 = require("@nestjs/common");
14
13
  const zod_1 = require("zod");
15
- const common_2 = require("@loopstack/common");
14
+ const common_1 = require("@loopstack/common");
16
15
  exports.MeetingNotesDocumentSchema = zod_1.z.object({
17
16
  text: zod_1.z.string(),
18
17
  });
@@ -21,14 +20,13 @@ let MeetingNotesDocument = class MeetingNotesDocument {
21
20
  };
22
21
  exports.MeetingNotesDocument = MeetingNotesDocument;
23
22
  __decorate([
24
- (0, common_2.Input)({
23
+ (0, common_1.Input)({
25
24
  schema: exports.MeetingNotesDocumentSchema,
26
25
  }),
27
26
  __metadata("design:type", Object)
28
27
  ], MeetingNotesDocument.prototype, "content", void 0);
29
28
  exports.MeetingNotesDocument = MeetingNotesDocument = __decorate([
30
- (0, common_1.Injectable)(),
31
- (0, common_2.Document)({
29
+ (0, common_1.Document)({
32
30
  configFile: __dirname + '/meeting-notes-document.yaml',
33
31
  })
34
32
  ], MeetingNotesDocument);
@@ -1 +1 @@
1
- {"version":3,"file":"meeting-notes-document.js","sourceRoot":"","sources":["../../src/documents/meeting-notes-document.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAC5C,6BAAwB;AACxB,8CAAuE;AAE1D,QAAA,0BAA0B,GAAG,OAAC,CAAC,MAAM,CAAC;IACjD,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE;CACjB,CAAC,CAAC;AAMI,IAAM,oBAAoB,GAA1B,MAAM,oBAAoB;IAI/B,OAAO,CAEL;CACH,CAAA;AAPY,oDAAoB;AAI/B;IAHC,IAAA,cAAK,EAAC;QACL,MAAM,EAAE,kCAA0B;KACnC,CAAC;;qDAGA;+BANS,oBAAoB;IAJhC,IAAA,mBAAU,GAAE;IACZ,IAAA,iBAAQ,EAAC;QACR,UAAU,EAAE,SAAS,GAAG,8BAA8B;KACvD,CAAC;GACW,oBAAoB,CAOhC"}
1
+ {"version":3,"file":"meeting-notes-document.js","sourceRoot":"","sources":["../../src/documents/meeting-notes-document.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,6BAAwB;AACxB,8CAAuE;AAE1D,QAAA,0BAA0B,GAAG,OAAC,CAAC,MAAM,CAAC;IACjD,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE;CACjB,CAAC,CAAC;AAKI,IAAM,oBAAoB,GAA1B,MAAM,oBAAoB;IAI/B,OAAO,CAEL;CACH,CAAA;AAPY,oDAAoB;AAI/B;IAHC,IAAA,cAAK,EAAC;QACL,MAAM,EAAE,kCAA0B;KACnC,CAAC;;qDAGA;+BANS,oBAAoB;IAHhC,IAAA,iBAAQ,EAAC;QACR,UAAU,EAAE,SAAS,GAAG,8BAA8B;KACvD,CAAC;GACW,oBAAoB,CAOhC"}
@@ -1 +1 @@
1
- {"version":3,"file":"optimized-notes-document.d.ts","sourceRoot":"","sources":["../../src/documents/optimized-notes-document.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAY,iBAAiB,EAAS,MAAM,mBAAmB,CAAC;AAEvE,eAAO,MAAM,mCAAmC;;;;;;iBAM9C,CAAC;AAEH,qBAIa,sBAAuB,YAAW,iBAAiB;IAI9D,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,mCAAmC,CAAC,CAAC;CAC9D"}
1
+ {"version":3,"file":"optimized-notes-document.d.ts","sourceRoot":"","sources":["../../src/documents/optimized-notes-document.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAY,iBAAiB,EAAS,MAAM,mBAAmB,CAAC;AAEvE,eAAO,MAAM,mCAAmC;;;;;;iBAM9C,CAAC;AAEH,qBAGa,sBAAuB,YAAW,iBAAiB;IAI9D,OAAO,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,mCAAmC,CAAC,CAAC;CAC9D"}
@@ -10,9 +10,8 @@ var __metadata = (this && this.__metadata) || function (k, v) {
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.OptimizedNotesDocument = exports.OptimizedMeetingNotesDocumentSchema = void 0;
13
- const common_1 = require("@nestjs/common");
14
13
  const zod_1 = require("zod");
15
- const common_2 = require("@loopstack/common");
14
+ const common_1 = require("@loopstack/common");
16
15
  exports.OptimizedMeetingNotesDocumentSchema = zod_1.z.object({
17
16
  date: zod_1.z.string(),
18
17
  summary: zod_1.z.string(),
@@ -25,14 +24,13 @@ let OptimizedNotesDocument = class OptimizedNotesDocument {
25
24
  };
26
25
  exports.OptimizedNotesDocument = OptimizedNotesDocument;
27
26
  __decorate([
28
- (0, common_2.Input)({
27
+ (0, common_1.Input)({
29
28
  schema: exports.OptimizedMeetingNotesDocumentSchema,
30
29
  }),
31
30
  __metadata("design:type", Object)
32
31
  ], OptimizedNotesDocument.prototype, "content", void 0);
33
32
  exports.OptimizedNotesDocument = OptimizedNotesDocument = __decorate([
34
- (0, common_1.Injectable)(),
35
- (0, common_2.Document)({
33
+ (0, common_1.Document)({
36
34
  configFile: __dirname + '/optimized-notes-document.yaml',
37
35
  })
38
36
  ], OptimizedNotesDocument);
@@ -1 +1 @@
1
- {"version":3,"file":"optimized-notes-document.js","sourceRoot":"","sources":["../../src/documents/optimized-notes-document.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAC5C,6BAAwB;AACxB,8CAAuE;AAE1D,QAAA,mCAAmC,GAAG,OAAC,CAAC,MAAM,CAAC;IAC1D,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE;IAChB,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE;IACnB,YAAY,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC;IACjC,SAAS,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC;IAC9B,WAAW,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC;CACjC,CAAC,CAAC;AAMI,IAAM,sBAAsB,GAA5B,MAAM,sBAAsB;IAIjC,OAAO,CAAsD;CAC9D,CAAA;AALY,wDAAsB;AAIjC;IAHC,IAAA,cAAK,EAAC;QACL,MAAM,EAAE,2CAAmC;KAC5C,CAAC;;uDAC2D;iCAJlD,sBAAsB;IAJlC,IAAA,mBAAU,GAAE;IACZ,IAAA,iBAAQ,EAAC;QACR,UAAU,EAAE,SAAS,GAAG,gCAAgC;KACzD,CAAC;GACW,sBAAsB,CAKlC"}
1
+ {"version":3,"file":"optimized-notes-document.js","sourceRoot":"","sources":["../../src/documents/optimized-notes-document.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,6BAAwB;AACxB,8CAAuE;AAE1D,QAAA,mCAAmC,GAAG,OAAC,CAAC,MAAM,CAAC;IAC1D,IAAI,EAAE,OAAC,CAAC,MAAM,EAAE;IAChB,OAAO,EAAE,OAAC,CAAC,MAAM,EAAE;IACnB,YAAY,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC;IACjC,SAAS,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC;IAC9B,WAAW,EAAE,OAAC,CAAC,KAAK,CAAC,OAAC,CAAC,MAAM,EAAE,CAAC;CACjC,CAAC,CAAC;AAKI,IAAM,sBAAsB,GAA5B,MAAM,sBAAsB;IAIjC,OAAO,CAAsD;CAC9D,CAAA;AALY,wDAAsB;AAIjC;IAHC,IAAA,cAAK,EAAC;QACL,MAAM,EAAE,2CAAmC;KAC5C,CAAC;;uDAC2D;iCAJlD,sBAAsB;IAHlC,IAAA,iBAAQ,EAAC;QACR,UAAU,EAAE,SAAS,GAAG,gCAAgC;KACzD,CAAC;GACW,sBAAsB,CAKlC"}
@@ -1 +1 @@
1
- {"version":3,"file":"meeting-notes.workflow.d.ts","sourceRoot":"","sources":["../src/meeting-notes.workflow.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AACtG,OAAO,EAAE,mCAAmC,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAEnH,qBAIa,oBAAoB;IACjB,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,cAAc,EAAE,cAAc,CAAC;IAC3B,oBAAoB,EAAE,oBAAoB,CAAC;IAC3C,sBAAsB,EAAE,sBAAsB,CAAC;IAWjE,IAAI,EAAE;QACJ,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IAQF,KAAK,EAAE;QACL,YAAY,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;QAC1D,cAAc,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,mCAAmC,CAAC,CAAC;KACtE,CAAC;IAGF,OAAO,EAAE,GAAG,CAAC;CACd"}
1
+ {"version":3,"file":"meeting-notes.workflow.d.ts","sourceRoot":"","sources":["../src/meeting-notes.workflow.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AACxB,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAC;AAE1D,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAC3D,OAAO,EAAE,oBAAoB,EAAE,0BAA0B,EAAE,MAAM,oCAAoC,CAAC;AACtG,OAAO,EAAE,mCAAmC,EAAE,sBAAsB,EAAE,MAAM,sCAAsC,CAAC;AAEnH,qBAGa,oBAAoB;IACjB,kBAAkB,EAAE,kBAAkB,CAAC;IACvC,cAAc,EAAE,cAAc,CAAC;IAC3B,oBAAoB,EAAE,oBAAoB,CAAC;IAC3C,sBAAsB,EAAE,sBAAsB,CAAC;IAWjE,IAAI,EAAE;QACJ,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IAQF,KAAK,EAAE;QACL,YAAY,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,0BAA0B,CAAC,CAAC;QAC1D,cAAc,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,OAAO,mCAAmC,CAAC,CAAC;KACtE,CAAC;IAGF,OAAO,EAAE,GAAG,CAAC;CACd"}
@@ -10,10 +10,9 @@ var __metadata = (this && this.__metadata) || function (k, v) {
10
10
  };
11
11
  Object.defineProperty(exports, "__esModule", { value: true });
12
12
  exports.MeetingNotesWorkflow = void 0;
13
- const common_1 = require("@nestjs/common");
14
13
  const zod_1 = require("zod");
15
14
  const ai_module_1 = require("@loopstack/ai-module");
16
- const common_2 = require("@loopstack/common");
15
+ const common_1 = require("@loopstack/common");
17
16
  const core_ui_module_1 = require("@loopstack/core-ui-module");
18
17
  const meeting_notes_document_1 = require("./documents/meeting-notes-document");
19
18
  const optimized_notes_document_1 = require("./documents/optimized-notes-document");
@@ -28,23 +27,23 @@ let MeetingNotesWorkflow = class MeetingNotesWorkflow {
28
27
  };
29
28
  exports.MeetingNotesWorkflow = MeetingNotesWorkflow;
30
29
  __decorate([
31
- (0, common_2.InjectTool)(),
30
+ (0, common_1.InjectTool)(),
32
31
  __metadata("design:type", ai_module_1.AiGenerateDocument)
33
32
  ], MeetingNotesWorkflow.prototype, "aiGenerateDocument", void 0);
34
33
  __decorate([
35
- (0, common_2.InjectTool)(),
34
+ (0, common_1.InjectTool)(),
36
35
  __metadata("design:type", core_ui_module_1.CreateDocument)
37
36
  ], MeetingNotesWorkflow.prototype, "createDocument", void 0);
38
37
  __decorate([
39
- (0, common_2.InjectDocument)(),
38
+ (0, common_1.InjectDocument)(),
40
39
  __metadata("design:type", meeting_notes_document_1.MeetingNotesDocument)
41
40
  ], MeetingNotesWorkflow.prototype, "meetingNotesDocument", void 0);
42
41
  __decorate([
43
- (0, common_2.InjectDocument)(),
42
+ (0, common_1.InjectDocument)(),
44
43
  __metadata("design:type", optimized_notes_document_1.OptimizedNotesDocument)
45
44
  ], MeetingNotesWorkflow.prototype, "optimizedNotesDocument", void 0);
46
45
  __decorate([
47
- (0, common_2.Input)({
46
+ (0, common_1.Input)({
48
47
  schema: zod_1.z.object({
49
48
  inputText: zod_1.z
50
49
  .string()
@@ -54,7 +53,7 @@ __decorate([
54
53
  __metadata("design:type", Object)
55
54
  ], MeetingNotesWorkflow.prototype, "args", void 0);
56
55
  __decorate([
57
- (0, common_2.State)({
56
+ (0, common_1.State)({
58
57
  schema: zod_1.z.object({
59
58
  meetingNotes: meeting_notes_document_1.MeetingNotesDocumentSchema.optional(),
60
59
  optimizedNotes: optimized_notes_document_1.OptimizedMeetingNotesDocumentSchema.optional(),
@@ -63,12 +62,11 @@ __decorate([
63
62
  __metadata("design:type", Object)
64
63
  ], MeetingNotesWorkflow.prototype, "state", void 0);
65
64
  __decorate([
66
- (0, common_2.Runtime)(),
65
+ (0, common_1.Runtime)(),
67
66
  __metadata("design:type", Object)
68
67
  ], MeetingNotesWorkflow.prototype, "runtime", void 0);
69
68
  exports.MeetingNotesWorkflow = MeetingNotesWorkflow = __decorate([
70
- (0, common_1.Injectable)(),
71
- (0, common_2.Workflow)({
69
+ (0, common_1.Workflow)({
72
70
  configFile: __dirname + '/meeting-notes.workflow.yaml',
73
71
  })
74
72
  ], MeetingNotesWorkflow);
@@ -1 +1 @@
1
- {"version":3,"file":"meeting-notes.workflow.js","sourceRoot":"","sources":["../src/meeting-notes.workflow.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,2CAA4C;AAC5C,6BAAwB;AACxB,oDAA0D;AAC1D,8CAAgG;AAChG,8DAA2D;AAC3D,+EAAsG;AACtG,mFAAmH;AAM5G,IAAM,oBAAoB,GAA1B,MAAM,oBAAoB;IACjB,kBAAkB,CAAqB;IACvC,cAAc,CAAiB;IAC3B,oBAAoB,CAAuB;IAC3C,sBAAsB,CAAyB;IAWjE,IAAI,CAEF;IAQF,KAAK,CAGH;IAGF,OAAO,CAAM;CACd,CAAA;AAhCY,oDAAoB;AACjB;IAAb,IAAA,mBAAU,GAAE;8BAAqB,8BAAkB;gEAAC;AACvC;IAAb,IAAA,mBAAU,GAAE;8BAAiB,+BAAc;4DAAC;AAC3B;IAAjB,IAAA,uBAAc,GAAE;8BAAuB,6CAAoB;kEAAC;AAC3C;IAAjB,IAAA,uBAAc,GAAE;8BAAyB,iDAAsB;oEAAC;AAWjE;IATC,IAAA,cAAK,EAAC;QACL,MAAM,EAAE,OAAC,CAAC,MAAM,CAAC;YACf,SAAS,EAAE,OAAC;iBACT,MAAM,EAAE;iBACR,OAAO,CACN,2IAA2I,CAC5I;SACJ,CAAC;KACH,CAAC;;kDAGA;AAQF;IANC,IAAA,cAAK,EAAC;QACL,MAAM,EAAE,OAAC,CAAC,MAAM,CAAC;YACf,YAAY,EAAE,mDAA0B,CAAC,QAAQ,EAAE;YACnD,cAAc,EAAE,8DAAmC,CAAC,QAAQ,EAAE;SAC/D,CAAC;KACH,CAAC;;mDAIA;AAGF;IADC,IAAA,gBAAO,GAAE;;qDACG;+BA/BF,oBAAoB;IAJhC,IAAA,mBAAU,GAAE;IACZ,IAAA,iBAAQ,EAAC;QACR,UAAU,EAAE,SAAS,GAAG,8BAA8B;KACvD,CAAC;GACW,oBAAoB,CAgChC"}
1
+ {"version":3,"file":"meeting-notes.workflow.js","sourceRoot":"","sources":["../src/meeting-notes.workflow.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,6BAAwB;AACxB,oDAA0D;AAC1D,8CAAgG;AAChG,8DAA2D;AAC3D,+EAAsG;AACtG,mFAAmH;AAK5G,IAAM,oBAAoB,GAA1B,MAAM,oBAAoB;IACjB,kBAAkB,CAAqB;IACvC,cAAc,CAAiB;IAC3B,oBAAoB,CAAuB;IAC3C,sBAAsB,CAAyB;IAWjE,IAAI,CAEF;IAQF,KAAK,CAGH;IAGF,OAAO,CAAM;CACd,CAAA;AAhCY,oDAAoB;AACjB;IAAb,IAAA,mBAAU,GAAE;8BAAqB,8BAAkB;gEAAC;AACvC;IAAb,IAAA,mBAAU,GAAE;8BAAiB,+BAAc;4DAAC;AAC3B;IAAjB,IAAA,uBAAc,GAAE;8BAAuB,6CAAoB;kEAAC;AAC3C;IAAjB,IAAA,uBAAc,GAAE;8BAAyB,iDAAsB;oEAAC;AAWjE;IATC,IAAA,cAAK,EAAC;QACL,MAAM,EAAE,OAAC,CAAC,MAAM,CAAC;YACf,SAAS,EAAE,OAAC;iBACT,MAAM,EAAE;iBACR,OAAO,CACN,2IAA2I,CAC5I;SACJ,CAAC;KACH,CAAC;;kDAGA;AAQF;IANC,IAAA,cAAK,EAAC;QACL,MAAM,EAAE,OAAC,CAAC,MAAM,CAAC;YACf,YAAY,EAAE,mDAA0B,CAAC,QAAQ,EAAE;YACnD,cAAc,EAAE,8DAAmC,CAAC,QAAQ,EAAE;SAC/D,CAAC;KACH,CAAC;;mDAIA;AAGF;IADC,IAAA,gBAAO,GAAE;;qDACG;+BA/BF,oBAAoB;IAHhC,IAAA,iBAAQ,EAAC;QACR,UAAU,EAAE,SAAS,GAAG,8BAA8B;KACvD,CAAC;GACW,oBAAoB,CAgChC"}
@@ -37,9 +37,9 @@ transitions:
37
37
  id: input
38
38
  document: meetingNotesDocument
39
39
  update:
40
- content: ${ runtime.transition.payload }
40
+ content: ${{ runtime.transition.payload }}
41
41
  assign:
42
- meetingNotes: ${ result.data.content }
42
+ meetingNotes: ${{ result.data.content }}
43
43
 
44
44
  - id: optimize_notes
45
45
  from: response_received
@@ -72,6 +72,6 @@ transitions:
72
72
  id: final
73
73
  document: optimizedNotesDocument
74
74
  update:
75
- content: ${ runtime.transition.payload }
75
+ content: ${{ runtime.transition.payload }}
76
76
  assign:
77
- optimizedNotes: ${ result.data.content }
77
+ optimizedNotes: ${{ result.data.content }}
package/package.json CHANGED
@@ -9,7 +9,7 @@
9
9
  "summary",
10
10
  "workflow"
11
11
  ],
12
- "version": "0.20.0",
12
+ "version": "0.20.2",
13
13
  "license": "Apache-2.0",
14
14
  "author": {
15
15
  "name": "Jakob Klippel",
@@ -30,9 +30,9 @@
30
30
  "watch": "nest build --watch"
31
31
  },
32
32
  "dependencies": {
33
- "@loopstack/ai-module": "^0.20.0",
34
- "@loopstack/common": "^0.20.0",
35
- "@loopstack/core-ui-module": "^0.20.0",
33
+ "@loopstack/ai-module": "^0.20.2",
34
+ "@loopstack/common": "^0.20.3",
35
+ "@loopstack/core-ui-module": "^0.20.2",
36
36
  "@nestjs/common": "^11.1.12",
37
37
  "zod": "^4.3.5"
38
38
  },
@@ -55,6 +55,10 @@
55
55
  "module": "src/meeting-notes-example.module.ts",
56
56
  "workflows": [
57
57
  "src/meeting-notes.workflow.ts"
58
+ ],
59
+ "installModes": [
60
+ "add",
61
+ "install"
58
62
  ]
59
63
  }
60
64
  }
@@ -62,7 +62,7 @@ describe('MeetingNotesWorkflow', () => {
62
62
  const result = await processor.process(workflow, {}, context);
63
63
 
64
64
  // Should execute without errors and stop at waiting_for_response (manual step)
65
- expect(result.error).toBe(false);
65
+ expect(result.hasError).toBe(false);
66
66
  expect(result.stop).toBe(true);
67
67
 
68
68
  // Should call CreateDocument once for the initial form
@@ -151,7 +151,7 @@ describe('MeetingNotesWorkflow', () => {
151
151
  const result = await processorWithState.process(workflowWithState, args, contextWithPayload);
152
152
 
153
153
  // Should execute and stop at notes_optimized (next manual step)
154
- expect(result.error).toBe(false);
154
+ expect(result.hasError).toBe(false);
155
155
  expect(result.stop).toBe(true);
156
156
 
157
157
  // Should call CreateDocument once for user response
@@ -241,7 +241,7 @@ describe('MeetingNotesWorkflow', () => {
241
241
  const result = await processorWithState.process(workflowWithState, args, contextWithPayload);
242
242
 
243
243
  // Should complete and reach end state
244
- expect(result.error).toBe(false);
244
+ expect(result.hasError).toBe(false);
245
245
  expect(result.stop).toBe(false);
246
246
 
247
247
  // Should call CreateDocument once for final confirmation
@@ -1,4 +1,3 @@
1
- import { Injectable } from '@nestjs/common';
2
1
  import { z } from 'zod';
3
2
  import { Document, DocumentInterface, Input } from '@loopstack/common';
4
3
 
@@ -6,7 +5,6 @@ export const MeetingNotesDocumentSchema = z.object({
6
5
  text: z.string(),
7
6
  });
8
7
 
9
- @Injectable()
10
8
  @Document({
11
9
  configFile: __dirname + '/meeting-notes-document.yaml',
12
10
  })
@@ -1,4 +1,3 @@
1
- import { Injectable } from '@nestjs/common';
2
1
  import { z } from 'zod';
3
2
  import { Document, DocumentInterface, Input } from '@loopstack/common';
4
3
 
@@ -10,7 +9,6 @@ export const OptimizedMeetingNotesDocumentSchema = z.object({
10
9
  actionItems: z.array(z.string()),
11
10
  });
12
11
 
13
- @Injectable()
14
12
  @Document({
15
13
  configFile: __dirname + '/optimized-notes-document.yaml',
16
14
  })
@@ -1,4 +1,3 @@
1
- import { Injectable } from '@nestjs/common';
2
1
  import { z } from 'zod';
3
2
  import { AiGenerateDocument } from '@loopstack/ai-module';
4
3
  import { InjectDocument, InjectTool, Input, Runtime, State, Workflow } from '@loopstack/common';
@@ -6,7 +5,6 @@ import { CreateDocument } from '@loopstack/core-ui-module';
6
5
  import { MeetingNotesDocument, MeetingNotesDocumentSchema } from './documents/meeting-notes-document';
7
6
  import { OptimizedMeetingNotesDocumentSchema, OptimizedNotesDocument } from './documents/optimized-notes-document';
8
7
 
9
- @Injectable()
10
8
  @Workflow({
11
9
  configFile: __dirname + '/meeting-notes.workflow.yaml',
12
10
  })
@@ -37,9 +37,9 @@ transitions:
37
37
  id: input
38
38
  document: meetingNotesDocument
39
39
  update:
40
- content: ${ runtime.transition.payload }
40
+ content: ${{ runtime.transition.payload }}
41
41
  assign:
42
- meetingNotes: ${ result.data.content }
42
+ meetingNotes: ${{ result.data.content }}
43
43
 
44
44
  - id: optimize_notes
45
45
  from: response_received
@@ -72,6 +72,6 @@ transitions:
72
72
  id: final
73
73
  document: optimizedNotesDocument
74
74
  update:
75
- content: ${ runtime.transition.payload }
75
+ content: ${{ runtime.transition.payload }}
76
76
  assign:
77
- optimizedNotes: ${ result.data.content }
77
+ optimizedNotes: ${{ result.data.content }}