@nt-ai-lab/deterministic-agent-workflow-engine 0.3.5 → 0.4.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.
package/dist/index.d.ts
CHANGED
|
@@ -8,7 +8,7 @@ export { reflectionCategorySchema, reflectionConfidenceSchema, reflectionEvidenc
|
|
|
8
8
|
export type { ReflectionCategory, ReflectionEvidence, ReflectionFinding, ReflectionPayload, RecordReflectionInput, StoredReflection, } from './platform/domain/reflection-types';
|
|
9
9
|
export { reviewTypeSchema, reviewVerdictSchema, reviewFindingSeveritySchema, reviewFindingStatusSchema, reviewFindingSchema, reviewPayloadSchema, recordReviewInputSchema, storedReviewSchema, listedReviewSchema, reviewFiltersSchema, } from './platform/domain/review-types';
|
|
10
10
|
export type { ReviewType, ReviewVerdict, ReviewFindingSeverity, ReviewFindingStatus, ReviewFinding, ReviewPayload, RecordReviewInput, StoredReview, ListedReview, ReviewFilters, } from './platform/domain/review-types';
|
|
11
|
-
export { engineEventSchema } from './platform/domain/engine-events';
|
|
11
|
+
export { engineEventSchema, reviewRecordedEventSchema, } from './platform/domain/engine-events';
|
|
12
12
|
export type { EngineEvent, SessionStartedEvent, TransitionedEvent, AgentRegisteredEvent, AgentShutDownEvent, JournalEntryEvent, WriteCheckedEvent, BashCheckedEvent, PluginReadCheckedEvent, IdleCheckedEvent, IdentityVerifiedEvent, ContextRequestedEvent, ReviewRecordedEvent, } from './platform/domain/engine-events';
|
|
13
13
|
export { isPlatformOwnedEventExcludedFromWorkflowState } from './platform/domain/engine-events';
|
|
14
14
|
export { reduceWorkflowStateFromStoredEvents } from './platform/domain/workflow-state-reducer';
|
package/dist/index.js
CHANGED
|
@@ -3,7 +3,7 @@ export { baseEventSchema } from './platform/domain/base-event.js';
|
|
|
3
3
|
export { flattenStoredEvent, stripEnvelopeKeys, toPayload, } from './platform/domain/stored-event.js';
|
|
4
4
|
export { reflectionCategorySchema, reflectionConfidenceSchema, reflectionEvidenceSchema, reflectionFindingSchema, reflectionPayloadSchema, recordReflectionInputSchema, storedReflectionSchema, } from './platform/domain/reflection-types.js';
|
|
5
5
|
export { reviewTypeSchema, reviewVerdictSchema, reviewFindingSeveritySchema, reviewFindingStatusSchema, reviewFindingSchema, reviewPayloadSchema, recordReviewInputSchema, storedReviewSchema, listedReviewSchema, reviewFiltersSchema, } from './platform/domain/review-types.js';
|
|
6
|
-
export { engineEventSchema } from './platform/domain/engine-events.js';
|
|
6
|
+
export { engineEventSchema, reviewRecordedEventSchema, } from './platform/domain/engine-events.js';
|
|
7
7
|
export { isPlatformOwnedEventExcludedFromWorkflowState } from './platform/domain/engine-events.js';
|
|
8
8
|
export { reduceWorkflowStateFromStoredEvents } from './platform/domain/workflow-state-reducer.js';
|
|
9
9
|
export { repositoryMetadataEventSchema } from './platform/domain/repository-tracking-events.js';
|
|
@@ -208,7 +208,7 @@ declare const contextRequestedSchema: z.ZodObject<{
|
|
|
208
208
|
at: string;
|
|
209
209
|
agentName: string;
|
|
210
210
|
}>;
|
|
211
|
-
declare const
|
|
211
|
+
export declare const reviewRecordedEventSchema: z.ZodObject<{
|
|
212
212
|
type: z.ZodLiteral<"review-recorded">;
|
|
213
213
|
at: z.ZodString;
|
|
214
214
|
reviewId: z.ZodNumber;
|
|
@@ -471,5 +471,5 @@ export type IdentityVerifiedEvent = z.infer<typeof identityVerifiedSchema>;
|
|
|
471
471
|
/** @riviere-role value-object */
|
|
472
472
|
export type ContextRequestedEvent = z.infer<typeof contextRequestedSchema>;
|
|
473
473
|
/** @riviere-role value-object */
|
|
474
|
-
export type ReviewRecordedEvent = z.infer<typeof
|
|
474
|
+
export type ReviewRecordedEvent = z.infer<typeof reviewRecordedEventSchema>;
|
|
475
475
|
export {};
|
|
@@ -76,7 +76,7 @@ const contextRequestedSchema = z.object({
|
|
|
76
76
|
at: z.string(),
|
|
77
77
|
agentName: z.string(),
|
|
78
78
|
});
|
|
79
|
-
const
|
|
79
|
+
export const reviewRecordedEventSchema = z.object({
|
|
80
80
|
type: z.literal('review-recorded'),
|
|
81
81
|
at: z.string(),
|
|
82
82
|
reviewId: z.number().int().positive(),
|
|
@@ -95,7 +95,7 @@ export const engineEventSchema = z.discriminatedUnion('type', [
|
|
|
95
95
|
idleCheckedSchema,
|
|
96
96
|
identityVerifiedSchema,
|
|
97
97
|
contextRequestedSchema,
|
|
98
|
-
|
|
98
|
+
reviewRecordedEventSchema,
|
|
99
99
|
]);
|
|
100
100
|
const platformOwnedEventTypesExcludedFromWorkflowState = new Set([
|
|
101
101
|
'agent-registered',
|
|
@@ -107,7 +107,6 @@ const platformOwnedEventTypesExcludedFromWorkflowState = new Set([
|
|
|
107
107
|
'idle-checked',
|
|
108
108
|
'identity-verified',
|
|
109
109
|
'context-requested',
|
|
110
|
-
'review-recorded',
|
|
111
110
|
]);
|
|
112
111
|
/** @riviere-role domain-service */
|
|
113
112
|
export function isPlatformOwnedEventExcludedFromWorkflowState(type) {
|
|
@@ -1,9 +1,18 @@
|
|
|
1
1
|
import { describe, expect, it, } from 'vitest';
|
|
2
2
|
import { z } from 'zod';
|
|
3
|
-
import { pass, WorkflowEngine, WorkflowStateError, } from '../../index.js';
|
|
3
|
+
import { flattenStoredEvent, pass, reduceWorkflowStateFromStoredEvents, reviewRecordedEventSchema, WorkflowEngine, WorkflowStateError, } from '../../index.js';
|
|
4
4
|
function isSessionStartedEvent(event) {
|
|
5
5
|
return event.type === 'session-started';
|
|
6
6
|
}
|
|
7
|
+
function allowAgentRegistration(agentType, agentId) {
|
|
8
|
+
void agentType;
|
|
9
|
+
void agentId;
|
|
10
|
+
return pass();
|
|
11
|
+
}
|
|
12
|
+
function allowIdleCheck(agentName) {
|
|
13
|
+
void agentName;
|
|
14
|
+
return pass();
|
|
15
|
+
}
|
|
7
16
|
class StrictPlanningWorkflow {
|
|
8
17
|
state;
|
|
9
18
|
pendingEvents;
|
|
@@ -45,13 +54,40 @@ class StrictPlanningWorkflow {
|
|
|
45
54
|
return this.state.transcriptPath;
|
|
46
55
|
}
|
|
47
56
|
registerAgent(agentType, agentId) {
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
57
|
+
return allowAgentRegistration(agentType, agentId);
|
|
58
|
+
}
|
|
59
|
+
handleTeammateIdle(agentName) {
|
|
60
|
+
return allowIdleCheck(agentName);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
class ReviewTrackingWorkflow {
|
|
64
|
+
state;
|
|
65
|
+
constructor(state) {
|
|
66
|
+
this.state = state;
|
|
67
|
+
}
|
|
68
|
+
getState() {
|
|
69
|
+
return this.state;
|
|
70
|
+
}
|
|
71
|
+
appendEvent(event) {
|
|
72
|
+
void event;
|
|
73
|
+
throw new WorkflowStateError('appendEvent is not used in this test');
|
|
74
|
+
}
|
|
75
|
+
getPendingEvents() {
|
|
76
|
+
return [];
|
|
77
|
+
}
|
|
78
|
+
startSession(transcriptPath, repository) {
|
|
79
|
+
void transcriptPath;
|
|
80
|
+
void repository;
|
|
81
|
+
throw new WorkflowStateError('startSession is not used in this test');
|
|
82
|
+
}
|
|
83
|
+
getTranscriptPath() {
|
|
84
|
+
return '';
|
|
85
|
+
}
|
|
86
|
+
registerAgent(agentType, agentId) {
|
|
87
|
+
return allowAgentRegistration(agentType, agentId);
|
|
51
88
|
}
|
|
52
89
|
handleTeammateIdle(agentName) {
|
|
53
|
-
|
|
54
|
-
return pass();
|
|
90
|
+
return allowIdleCheck(agentName);
|
|
55
91
|
}
|
|
56
92
|
}
|
|
57
93
|
class InMemoryWorkflowEventStore {
|
|
@@ -147,6 +183,62 @@ const workflowDefinition = {
|
|
|
147
183
|
};
|
|
148
184
|
},
|
|
149
185
|
};
|
|
186
|
+
const reviewTrackingWorkflowDefinition = {
|
|
187
|
+
fold(state, event) {
|
|
188
|
+
const reviewRecordedEvent = reviewRecordedEventSchema.parse(event);
|
|
189
|
+
if (reviewRecordedEvent.reviewType !== 'code-review') {
|
|
190
|
+
return state;
|
|
191
|
+
}
|
|
192
|
+
return {
|
|
193
|
+
...state,
|
|
194
|
+
codeReviewPassed: reviewRecordedEvent.verdict === 'PASS',
|
|
195
|
+
};
|
|
196
|
+
},
|
|
197
|
+
buildWorkflow(state) {
|
|
198
|
+
return new ReviewTrackingWorkflow(state);
|
|
199
|
+
},
|
|
200
|
+
stateSchema: z.literal('REVIEWING'),
|
|
201
|
+
initialState() {
|
|
202
|
+
return {
|
|
203
|
+
currentStateMachineState: 'REVIEWING',
|
|
204
|
+
codeReviewPassed: false,
|
|
205
|
+
};
|
|
206
|
+
},
|
|
207
|
+
getRegistry() {
|
|
208
|
+
return {
|
|
209
|
+
REVIEWING: {
|
|
210
|
+
emoji: '🔎',
|
|
211
|
+
agentInstructions: 'states/reviewing.md',
|
|
212
|
+
canTransitionTo: [],
|
|
213
|
+
allowedWorkflowOperations: ['record-review'],
|
|
214
|
+
},
|
|
215
|
+
};
|
|
216
|
+
},
|
|
217
|
+
buildTransitionContext(state, from, to) {
|
|
218
|
+
return {
|
|
219
|
+
state,
|
|
220
|
+
from,
|
|
221
|
+
to,
|
|
222
|
+
gitInfo: {
|
|
223
|
+
currentBranch: 'main',
|
|
224
|
+
workingTreeClean: true,
|
|
225
|
+
headCommit: 'abc123',
|
|
226
|
+
changedFilesVsDefault: [],
|
|
227
|
+
hasCommitsVsDefault: false,
|
|
228
|
+
},
|
|
229
|
+
};
|
|
230
|
+
},
|
|
231
|
+
};
|
|
232
|
+
function buildStoredEvent(type, at, state, payload) {
|
|
233
|
+
return {
|
|
234
|
+
envelope: {
|
|
235
|
+
type,
|
|
236
|
+
at,
|
|
237
|
+
state,
|
|
238
|
+
},
|
|
239
|
+
payload,
|
|
240
|
+
};
|
|
241
|
+
}
|
|
150
242
|
function createEngine() {
|
|
151
243
|
const store = new InMemoryWorkflowEventStore();
|
|
152
244
|
const engineDeps = {
|
|
@@ -190,4 +282,24 @@ describe('WorkflowEngine platform-owned events', () => {
|
|
|
190
282
|
'write-checked',
|
|
191
283
|
]);
|
|
192
284
|
});
|
|
285
|
+
it('keeps review-recorded available to consumer workflow state reconstruction', () => {
|
|
286
|
+
const storedEvents = [buildStoredEvent('review-recorded', '2026-01-01T00:01:00Z', 'REVIEWING', {
|
|
287
|
+
reviewId: 7,
|
|
288
|
+
reviewType: 'code-review',
|
|
289
|
+
verdict: 'PASS',
|
|
290
|
+
})];
|
|
291
|
+
const state = reduceWorkflowStateFromStoredEvents(reviewTrackingWorkflowDefinition, storedEvents);
|
|
292
|
+
const flattenedEvent = flattenStoredEvent(storedEvents[0]);
|
|
293
|
+
expect(reviewRecordedEventSchema.parse(flattenedEvent)).toStrictEqual({
|
|
294
|
+
type: 'review-recorded',
|
|
295
|
+
at: '2026-01-01T00:01:00Z',
|
|
296
|
+
reviewId: 7,
|
|
297
|
+
reviewType: 'code-review',
|
|
298
|
+
verdict: 'PASS',
|
|
299
|
+
});
|
|
300
|
+
expect(state).toStrictEqual({
|
|
301
|
+
currentStateMachineState: 'REVIEWING',
|
|
302
|
+
codeReviewPassed: true,
|
|
303
|
+
});
|
|
304
|
+
});
|
|
193
305
|
});
|
package/package.json
CHANGED
|
@@ -1,8 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nt-ai-lab/deterministic-agent-workflow-engine",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.4.0",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
|
+
"repository": {
|
|
7
|
+
"type": "git",
|
|
8
|
+
"url": "git+https://github.com/NTCoding/deterministic-agent-workflows.git",
|
|
9
|
+
"directory": "packages/deterministic-agent-workflows-engine"
|
|
10
|
+
},
|
|
6
11
|
"exports": {
|
|
7
12
|
".": "./dist/index.js"
|
|
8
13
|
},
|