@nt-ai-lab/deterministic-agent-workflow-pi 0.5.2 → 0.5.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.
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import type { BaseWorkflowState, RehydratableWorkflow } from '@nt-ai-lab/deterministic-agent-workflow-engine';
|
|
1
|
+
import type { BaseWorkflowState, RehydratableWorkflow, TransitionContext } from '@nt-ai-lab/deterministic-agent-workflow-engine';
|
|
2
2
|
import type { PiWorkflowExtension, PiWorkflowExtensionConfig } from '../../../platform/domain/pi-workflow-extension-types';
|
|
3
|
-
export declare const PI_IDLE_RECOVERY_MESSAGE
|
|
3
|
+
export declare const PI_IDLE_RECOVERY_MESSAGE: string;
|
|
4
4
|
export declare const PI_SESSION_BRANCH_BLOCK_MESSAGE = "Pi session tree navigation and forks are disabled while a workflow is active.";
|
|
5
5
|
/** @riviere-role cli-entrypoint */
|
|
6
|
-
export declare function createPiWorkflowExtension<TWorkflow extends RehydratableWorkflow<TState>, TState extends BaseWorkflowState<TStateName>, TDeps, TStateName extends string = string, TOperation extends string = string>(config: PiWorkflowExtensionConfig<TWorkflow, TState, TDeps, TStateName, TOperation>): PiWorkflowExtension;
|
|
6
|
+
export declare function createPiWorkflowExtension<TWorkflow extends RehydratableWorkflow<TState>, TState extends BaseWorkflowState<TStateName>, TDeps, TStateName extends string = string, TOperation extends string = string, TTransitionContext extends TransitionContext<TState, TStateName> = TransitionContext<TState, TStateName>>(config: PiWorkflowExtensionConfig<TWorkflow, TState, TDeps, TStateName, TOperation, TTransitionContext>): PiWorkflowExtension;
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { join } from 'node:path';
|
|
2
2
|
import { WorkflowEngine } from '@nt-ai-lab/deterministic-agent-workflow-engine';
|
|
3
|
-
import { createPreToolUseHandler, createWorkflowRunner, getRepositoryName, } from '@nt-ai-lab/deterministic-agent-workflow-cli';
|
|
3
|
+
import { createPreToolUseHandler, createWorkflowRunner, formatStopPreventionMessage, getRepositoryName, } from '@nt-ai-lab/deterministic-agent-workflow-cli';
|
|
4
4
|
import { createStore } from '@nt-ai-lab/deterministic-agent-workflow-event-store';
|
|
5
5
|
import { Type } from 'typebox';
|
|
6
6
|
import { parsePiCommandArguments } from '../../../platform/domain/pi-command-arguments.js';
|
|
@@ -12,7 +12,7 @@ const DEFAULT_COMMAND_NAME = 'workflow';
|
|
|
12
12
|
const DEFAULT_TOOL_NAME = 'workflow';
|
|
13
13
|
const INITIALIZATION_PENDING_REASON = 'Pi workflow initialization has not completed safely. Tool execution is blocked.';
|
|
14
14
|
const INACTIVE_WORKFLOW_REASON = 'Pi workflow is inactive. Run the workflow init command before using workflow operations.';
|
|
15
|
-
export const PI_IDLE_RECOVERY_MESSAGE =
|
|
15
|
+
export const PI_IDLE_RECOVERY_MESSAGE = formatStopPreventionMessage();
|
|
16
16
|
export const PI_SESSION_BRANCH_BLOCK_MESSAGE = 'Pi session tree navigation and forks are disabled while a workflow is active.';
|
|
17
17
|
const workflowToolParameters = Type.Object({
|
|
18
18
|
operation: Type.String({ description: 'Workflow operation, for example init or transition' }),
|
|
@@ -40,23 +40,28 @@ export function createPiWorkflowExtension(config) {
|
|
|
40
40
|
questionToolName: PI_QUESTION_TOOL,
|
|
41
41
|
customGates: config.customGates,
|
|
42
42
|
});
|
|
43
|
+
function buildEngineDeps(ctx, store) {
|
|
44
|
+
const sessionId = ctx.sessionManager.getSessionId();
|
|
45
|
+
const now = () => new Date().toISOString();
|
|
46
|
+
const note = translationNote(toolName);
|
|
47
|
+
return {
|
|
48
|
+
store,
|
|
49
|
+
getPluginRoot: () => config.pluginRoot,
|
|
50
|
+
getEnvFilePath: () => join(config.pluginRoot, '.pi', 'unused.env'),
|
|
51
|
+
getRepositoryName: () => getRepositoryName(ctx.cwd),
|
|
52
|
+
readFile: (path) => readWorkflowInstruction(path, note),
|
|
53
|
+
appendToFile: () => undefined,
|
|
54
|
+
now,
|
|
55
|
+
transcriptReader: new PiTranscriptReader(() => ctx.sessionManager.getBranch()),
|
|
56
|
+
sessionContext: { getMainSessionId: () => sessionId },
|
|
57
|
+
};
|
|
58
|
+
}
|
|
43
59
|
function useEngine(ctx, operation) {
|
|
44
60
|
const store = createStore(databasePath);
|
|
45
61
|
try {
|
|
62
|
+
const engineDeps = buildEngineDeps(ctx, store);
|
|
63
|
+
const now = engineDeps.now;
|
|
46
64
|
const sessionId = ctx.sessionManager.getSessionId();
|
|
47
|
-
const now = () => new Date().toISOString();
|
|
48
|
-
const note = translationNote(toolName);
|
|
49
|
-
const engineDeps = {
|
|
50
|
-
store,
|
|
51
|
-
getPluginRoot: () => config.pluginRoot,
|
|
52
|
-
getEnvFilePath: () => join(config.pluginRoot, '.pi', 'unused.env'),
|
|
53
|
-
getRepositoryName: () => getRepositoryName(ctx.cwd),
|
|
54
|
-
readFile: (path) => readWorkflowInstruction(path, note),
|
|
55
|
-
appendToFile: () => undefined,
|
|
56
|
-
now,
|
|
57
|
-
transcriptReader: new PiTranscriptReader(() => ctx.sessionManager.getBranch()),
|
|
58
|
-
sessionContext: { getMainSessionId: () => sessionId },
|
|
59
|
-
};
|
|
60
65
|
const platform = {
|
|
61
66
|
getPluginRoot: () => config.pluginRoot,
|
|
62
67
|
now,
|
|
@@ -71,8 +76,22 @@ export function createPiWorkflowExtension(config) {
|
|
|
71
76
|
store.db.close();
|
|
72
77
|
}
|
|
73
78
|
}
|
|
79
|
+
function hasPersistedWorkflowState(sessionId) {
|
|
80
|
+
const store = createStore(databasePath);
|
|
81
|
+
try {
|
|
82
|
+
return store.hasSessionStarted(sessionId);
|
|
83
|
+
}
|
|
84
|
+
finally {
|
|
85
|
+
store.db.close();
|
|
86
|
+
}
|
|
87
|
+
}
|
|
74
88
|
function markInitializationFailed(ctx, sessionId, detail) {
|
|
75
|
-
|
|
89
|
+
return failSession(ctx, sessionId, `Pi workflow initialization failed: ${detail}`);
|
|
90
|
+
}
|
|
91
|
+
function markSafetyUnavailable(ctx, sessionId, detail) {
|
|
92
|
+
return failSession(ctx, sessionId, `Pi workflow safety is unavailable: ${detail}`);
|
|
93
|
+
}
|
|
94
|
+
function failSession(ctx, sessionId, reason) {
|
|
76
95
|
initializationBySession.set(sessionId, {
|
|
77
96
|
type: 'failed',
|
|
78
97
|
reason,
|
|
@@ -209,7 +228,7 @@ export function createPiWorkflowExtension(config) {
|
|
|
209
228
|
}
|
|
210
229
|
catch (error) {
|
|
211
230
|
return {
|
|
212
|
-
output:
|
|
231
|
+
output: markSafetyUnavailable(ctx, session.sessionId, `Workflow operation could not establish safe state: ${String(error)}`),
|
|
213
232
|
exitCode: 1,
|
|
214
233
|
};
|
|
215
234
|
}
|
|
@@ -224,7 +243,7 @@ export function createPiWorkflowExtension(config) {
|
|
|
224
243
|
}
|
|
225
244
|
sessionStartsById.set(session.sessionId, event);
|
|
226
245
|
try {
|
|
227
|
-
const hasPersistedWorkflow =
|
|
246
|
+
const hasPersistedWorkflow = hasPersistedWorkflowState(session.sessionId);
|
|
228
247
|
const hasTranscriptWorkflow = hasPiWorkflowMarker(ctx.sessionManager.getEntries());
|
|
229
248
|
if (!hasPersistedWorkflow && !hasTranscriptWorkflow) {
|
|
230
249
|
initializationBySession.set(session.sessionId, { type: 'inactive' });
|
|
@@ -270,7 +289,7 @@ export function createPiWorkflowExtension(config) {
|
|
|
270
289
|
catch (error) {
|
|
271
290
|
return {
|
|
272
291
|
block: true,
|
|
273
|
-
reason:
|
|
292
|
+
reason: markSafetyUnavailable(ctx, session.sessionId, `Tool safety could not be established: ${String(error)}`),
|
|
274
293
|
};
|
|
275
294
|
}
|
|
276
295
|
});
|
|
@@ -298,11 +317,11 @@ export function createPiWorkflowExtension(config) {
|
|
|
298
317
|
const result = useEngine(ctx, (engine) => engine.checkStopping(session.sessionId, 'stop'));
|
|
299
318
|
if (result.type === 'blocked' && ctx.isIdle() && !ctx.hasPendingMessages()) {
|
|
300
319
|
recoveredAssistantBySession.set(session.sessionId, settlement.id);
|
|
301
|
-
pi.sendUserMessage(
|
|
320
|
+
pi.sendUserMessage(formatStopPreventionMessage(result.output, config.stopPreventionMessage));
|
|
302
321
|
}
|
|
303
322
|
}
|
|
304
323
|
catch (error) {
|
|
305
|
-
|
|
324
|
+
markSafetyUnavailable(ctx, session.sessionId, `Stopping safety could not be established: ${String(error)}`);
|
|
306
325
|
}
|
|
307
326
|
});
|
|
308
327
|
const blockSessionBranching = (ctx) => {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { ExtensionFactory } from '@earendil-works/pi-coding-agent';
|
|
2
|
-
import type { BaseWorkflowState, RehydratableWorkflow, WorkflowDefinition } from '@nt-ai-lab/deterministic-agent-workflow-engine';
|
|
2
|
+
import type { BaseWorkflowState, RehydratableWorkflow, TransitionContext, WorkflowDefinition } from '@nt-ai-lab/deterministic-agent-workflow-engine';
|
|
3
3
|
import type { PlatformContext, PreToolUseHandlerConfig, RouteMap } from '@nt-ai-lab/deterministic-agent-workflow-cli';
|
|
4
4
|
/** @riviere-role value-object */
|
|
5
5
|
export type PiWorkflowExtension = ExtensionFactory;
|
|
@@ -23,12 +23,13 @@ export type PiSessionIdResult = {
|
|
|
23
23
|
readonly reason: string;
|
|
24
24
|
};
|
|
25
25
|
/** @riviere-role value-object */
|
|
26
|
-
export type PiWorkflowExtensionConfig<TWorkflow extends RehydratableWorkflow<TState>, TState extends BaseWorkflowState<TStateName>, TDeps, TStateName extends string = string, TOperation extends string = string> = Omit<PreToolUseHandlerConfig<TWorkflow, TState, TStateName>, 'questionToolName'> & {
|
|
27
|
-
readonly workflowDefinition: WorkflowDefinition<TWorkflow, TState, TDeps, TStateName, TOperation>;
|
|
26
|
+
export type PiWorkflowExtensionConfig<TWorkflow extends RehydratableWorkflow<TState>, TState extends BaseWorkflowState<TStateName>, TDeps, TStateName extends string = string, TOperation extends string = string, TTransitionContext extends TransitionContext<TState, TStateName> = TransitionContext<TState, TStateName>> = Omit<PreToolUseHandlerConfig<TWorkflow, TState, TStateName>, 'questionToolName'> & {
|
|
27
|
+
readonly workflowDefinition: WorkflowDefinition<TWorkflow, TState, TDeps, TStateName, TOperation, TTransitionContext>;
|
|
28
28
|
readonly routes: RouteMap<TWorkflow, TState>;
|
|
29
29
|
readonly buildWorkflowDeps: (platform: PlatformContext) => TDeps;
|
|
30
30
|
readonly pluginRoot: string;
|
|
31
31
|
readonly databasePath?: string;
|
|
32
32
|
readonly commandName?: string;
|
|
33
33
|
readonly toolName?: string;
|
|
34
|
+
readonly stopPreventionMessage?: string;
|
|
34
35
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nt-ai-lab/deterministic-agent-workflow-pi",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.4",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "module",
|
|
6
6
|
"engines": {
|
|
@@ -23,9 +23,9 @@
|
|
|
23
23
|
},
|
|
24
24
|
"dependencies": {
|
|
25
25
|
"typebox": "^1.3.7",
|
|
26
|
-
"@nt-ai-lab/deterministic-agent-workflow-cli": "0.4.
|
|
27
|
-
"@nt-ai-lab/deterministic-agent-workflow-
|
|
28
|
-
"@nt-ai-lab/deterministic-agent-workflow-
|
|
26
|
+
"@nt-ai-lab/deterministic-agent-workflow-cli": "0.4.7",
|
|
27
|
+
"@nt-ai-lab/deterministic-agent-workflow-engine": "0.4.7",
|
|
28
|
+
"@nt-ai-lab/deterministic-agent-workflow-event-store": "0.4.7"
|
|
29
29
|
},
|
|
30
30
|
"devDependencies": {
|
|
31
31
|
"@earendil-works/pi-coding-agent": "^0.84.4",
|