@exaudeus/workrail 1.0.0 → 1.2.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/application/services/output-normalizer.d.ts +9 -0
- package/dist/application/services/output-normalizer.js +38 -0
- package/dist/application/services/validation-engine.d.ts +15 -1
- package/dist/application/services/validation-engine.js +81 -51
- package/dist/application/services/workflow-compiler.d.ts +3 -0
- package/dist/application/services/workflow-compiler.js +26 -0
- package/dist/application/services/workflow-interpreter.d.ts +4 -1
- package/dist/application/services/workflow-interpreter.js +85 -24
- package/dist/application/services/workflow-service.js +19 -2
- package/dist/manifest.json +379 -75
- package/dist/mcp/handler-factory.d.ts +7 -0
- package/dist/mcp/handler-factory.js +70 -0
- package/dist/mcp/handlers/shared/with-timeout.d.ts +1 -0
- package/dist/mcp/handlers/shared/with-timeout.js +9 -0
- package/dist/mcp/handlers/v2-advance-core.d.ts +45 -0
- package/dist/mcp/handlers/v2-advance-core.js +433 -0
- package/dist/mcp/handlers/v2-context-budget.d.ts +17 -0
- package/dist/mcp/handlers/v2-context-budget.js +169 -0
- package/dist/mcp/handlers/v2-error-mapping.d.ts +34 -0
- package/dist/mcp/handlers/v2-error-mapping.js +125 -0
- package/dist/mcp/handlers/v2-execution-helpers.js +4 -1
- package/dist/mcp/handlers/v2-execution.d.ts +19 -0
- package/dist/mcp/handlers/v2-execution.js +366 -589
- package/dist/mcp/handlers/v2-state-conversion.d.ts +40 -0
- package/dist/mcp/handlers/v2-state-conversion.js +132 -0
- package/dist/mcp/handlers/v2-token-ops.d.ts +33 -0
- package/dist/mcp/handlers/v2-token-ops.js +62 -0
- package/dist/mcp/handlers/v2-workflow.js +3 -8
- package/dist/mcp/handlers/workflow.js +4 -11
- package/dist/mcp/output-schemas.d.ts +514 -38
- package/dist/mcp/output-schemas.js +102 -7
- package/dist/mcp/server.js +23 -127
- package/dist/mcp/tool-descriptions.js +142 -18
- package/dist/mcp/types/workflow-tool-edition.d.ts +28 -0
- package/dist/mcp/types/workflow-tool-edition.js +10 -0
- package/dist/mcp/types.d.ts +2 -0
- package/dist/mcp/v1/tool-registry.d.ts +8 -0
- package/dist/mcp/v1/tool-registry.js +49 -0
- package/dist/mcp/v2/tool-registry.d.ts +2 -5
- package/dist/mcp/v2/tool-registry.js +33 -32
- package/dist/mcp/v2/tools.d.ts +23 -2
- package/dist/mcp/v2/tools.js +38 -7
- package/dist/mcp/workflow-tool-edition-selector.d.ts +4 -0
- package/dist/mcp/workflow-tool-edition-selector.js +13 -0
- package/dist/types/workflow-definition.d.ts +19 -0
- package/dist/v2/durable-core/constants.d.ts +3 -0
- package/dist/v2/durable-core/constants.js +4 -1
- package/dist/v2/durable-core/domain/ack-advance-append-plan.d.ts +15 -7
- package/dist/v2/durable-core/domain/ack-advance-append-plan.js +89 -24
- package/dist/v2/durable-core/domain/artifact-contract-validator.d.ts +31 -0
- package/dist/v2/durable-core/domain/artifact-contract-validator.js +98 -0
- package/dist/v2/durable-core/domain/blocked-node-builder.d.ts +20 -0
- package/dist/v2/durable-core/domain/blocked-node-builder.js +94 -0
- package/dist/v2/durable-core/domain/blocking-decision.d.ts +32 -0
- package/dist/v2/durable-core/domain/blocking-decision.js +41 -0
- package/dist/v2/durable-core/domain/context-merge.d.ts +8 -0
- package/dist/v2/durable-core/domain/context-merge.js +40 -0
- package/dist/v2/durable-core/domain/decision-trace-builder.d.ts +33 -0
- package/dist/v2/durable-core/domain/decision-trace-builder.js +92 -0
- package/dist/v2/durable-core/domain/function-definition-expander.d.ts +14 -0
- package/dist/v2/durable-core/domain/function-definition-expander.js +66 -0
- package/dist/v2/durable-core/domain/gap-builder.d.ts +19 -0
- package/dist/v2/durable-core/domain/gap-builder.js +24 -0
- package/dist/v2/durable-core/domain/loop-control-evaluator.d.ts +13 -0
- package/dist/v2/durable-core/domain/loop-control-evaluator.js +24 -0
- package/dist/v2/durable-core/domain/observation-builder.d.ts +16 -0
- package/dist/v2/durable-core/domain/observation-builder.js +42 -0
- package/dist/v2/durable-core/domain/outputs.js +2 -2
- package/dist/v2/durable-core/domain/prompt-renderer.d.ts +24 -0
- package/dist/v2/durable-core/domain/prompt-renderer.js +200 -0
- package/dist/v2/durable-core/domain/reason-model.d.ts +96 -0
- package/dist/v2/durable-core/domain/reason-model.js +241 -0
- package/dist/v2/durable-core/domain/recap-recovery.d.ts +24 -0
- package/dist/v2/durable-core/domain/recap-recovery.js +71 -0
- package/dist/v2/durable-core/domain/recommendation-warnings.d.ts +20 -0
- package/dist/v2/durable-core/domain/recommendation-warnings.js +35 -0
- package/dist/v2/durable-core/domain/risk-policy-guardrails.d.ts +15 -0
- package/dist/v2/durable-core/domain/risk-policy-guardrails.js +78 -0
- package/dist/v2/durable-core/domain/validation-criteria-validator.d.ts +16 -0
- package/dist/v2/durable-core/domain/validation-criteria-validator.js +46 -0
- package/dist/v2/durable-core/domain/validation-event-builder.d.ts +26 -0
- package/dist/v2/durable-core/domain/validation-event-builder.js +100 -0
- package/dist/v2/durable-core/domain/validation-loader.d.ts +11 -0
- package/dist/v2/durable-core/domain/validation-loader.js +21 -0
- package/dist/v2/durable-core/domain/validation-requirements-extractor.d.ts +2 -0
- package/dist/v2/durable-core/domain/validation-requirements-extractor.js +58 -0
- package/dist/v2/durable-core/projections/snapshot-state.js +1 -1
- package/dist/v2/durable-core/schemas/artifacts/index.d.ts +4 -0
- package/dist/v2/durable-core/schemas/artifacts/index.js +18 -0
- package/dist/v2/durable-core/schemas/artifacts/loop-control.d.ts +66 -0
- package/dist/v2/durable-core/schemas/artifacts/loop-control.js +47 -0
- package/dist/v2/durable-core/schemas/execution-snapshot/blocked-snapshot.d.ts +598 -0
- package/dist/v2/durable-core/schemas/execution-snapshot/blocked-snapshot.js +89 -0
- package/dist/v2/durable-core/schemas/execution-snapshot/execution-snapshot.v1.d.ts +3801 -57
- package/dist/v2/durable-core/schemas/execution-snapshot/execution-snapshot.v1.js +12 -2
- package/dist/v2/durable-core/schemas/execution-snapshot/index.d.ts +2 -0
- package/dist/v2/durable-core/schemas/execution-snapshot/index.js +3 -1
- package/dist/v2/durable-core/schemas/export-bundle/index.d.ts +6201 -2071
- package/dist/v2/durable-core/schemas/session/events.d.ts +216 -45
- package/dist/v2/durable-core/schemas/session/events.js +17 -1
- package/dist/v2/durable-core/schemas/session/validation-event.d.ts +68 -0
- package/dist/v2/durable-core/schemas/session/validation-event.js +52 -0
- package/dist/v2/durable-core/tokens/payloads.d.ts +16 -16
- package/dist/v2/infra/local/workspace-anchor/index.d.ts +9 -0
- package/dist/v2/infra/local/workspace-anchor/index.js +44 -0
- package/dist/v2/ports/workspace-anchor.port.d.ts +18 -0
- package/dist/v2/ports/workspace-anchor.port.js +2 -0
- package/dist/v2/projections/artifacts.d.ts +22 -0
- package/dist/v2/projections/artifacts.js +53 -0
- package/dist/v2/projections/projection-timing.d.ts +13 -0
- package/dist/v2/projections/projection-timing.js +23 -0
- package/dist/v2/projections/run-context.d.ts +22 -0
- package/dist/v2/projections/run-context.js +33 -0
- package/dist/v2/projections/run-dag.d.ts +1 -1
- package/dist/v2/projections/run-status-signals.js +3 -8
- package/package.json +1 -1
- package/spec/workflow.schema.json +60 -0
- package/spec/workflow.schema.v0.0.1.json +38 -0
- package/workflows/coding-task-workflow-agentic.json +11 -18
- package/workflows/test-artifact-loop-control.json +59 -0
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.ValidationPerformedDataV1Schema = exports.ValidationPerformedResultV1Schema = void 0;
|
|
4
|
+
const zod_1 = require("zod");
|
|
5
|
+
const constants_js_1 = require("../../constants.js");
|
|
6
|
+
const utf8_bounded_string_js_1 = require("../lib/utf8-bounded-string.js");
|
|
7
|
+
function utf8ByteLength(s) {
|
|
8
|
+
return new TextEncoder().encode(s).length;
|
|
9
|
+
}
|
|
10
|
+
const ValidationIssueV1Schema = (0, utf8_bounded_string_js_1.utf8BoundedString)({
|
|
11
|
+
label: 'validation issue',
|
|
12
|
+
minLength: 1,
|
|
13
|
+
maxBytes: 512,
|
|
14
|
+
});
|
|
15
|
+
const ValidationSuggestionV1Schema = (0, utf8_bounded_string_js_1.utf8BoundedString)({
|
|
16
|
+
label: 'validation suggestion',
|
|
17
|
+
minLength: 1,
|
|
18
|
+
maxBytes: 1024,
|
|
19
|
+
});
|
|
20
|
+
exports.ValidationPerformedResultV1Schema = zod_1.z
|
|
21
|
+
.object({
|
|
22
|
+
valid: zod_1.z.boolean(),
|
|
23
|
+
issues: zod_1.z.array(ValidationIssueV1Schema).readonly(),
|
|
24
|
+
suggestions: zod_1.z.array(ValidationSuggestionV1Schema).readonly(),
|
|
25
|
+
})
|
|
26
|
+
.strict()
|
|
27
|
+
.superRefine((v, ctx) => {
|
|
28
|
+
const issuesBytes = v.issues.reduce((sum, s) => sum + utf8ByteLength(s), 0);
|
|
29
|
+
if (issuesBytes > constants_js_1.MAX_VALIDATION_ISSUES_BYTES) {
|
|
30
|
+
ctx.addIssue({
|
|
31
|
+
code: zod_1.z.ZodIssueCode.custom,
|
|
32
|
+
message: `validation issues exceed ${constants_js_1.MAX_VALIDATION_ISSUES_BYTES} bytes (UTF-8)`,
|
|
33
|
+
path: ['issues'],
|
|
34
|
+
});
|
|
35
|
+
}
|
|
36
|
+
const suggestionsBytes = v.suggestions.reduce((sum, s) => sum + utf8ByteLength(s), 0);
|
|
37
|
+
if (suggestionsBytes > constants_js_1.MAX_VALIDATION_SUGGESTIONS_BYTES) {
|
|
38
|
+
ctx.addIssue({
|
|
39
|
+
code: zod_1.z.ZodIssueCode.custom,
|
|
40
|
+
message: `validation suggestions exceed ${constants_js_1.MAX_VALIDATION_SUGGESTIONS_BYTES} bytes (UTF-8)`,
|
|
41
|
+
path: ['suggestions'],
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
exports.ValidationPerformedDataV1Schema = zod_1.z
|
|
46
|
+
.object({
|
|
47
|
+
validationId: zod_1.z.string().min(1),
|
|
48
|
+
attemptId: zod_1.z.string().min(1),
|
|
49
|
+
contractRef: zod_1.z.string().min(1),
|
|
50
|
+
result: exports.ValidationPerformedResultV1Schema,
|
|
51
|
+
})
|
|
52
|
+
.strict();
|
|
@@ -55,22 +55,22 @@ export declare const AckTokenPayloadV1Schema: z.ZodObject<{
|
|
|
55
55
|
sessionId: string & {
|
|
56
56
|
readonly __brand: "v2.SessionId";
|
|
57
57
|
};
|
|
58
|
+
attemptId: string & {
|
|
59
|
+
readonly __brand: "v2.AttemptId";
|
|
60
|
+
};
|
|
58
61
|
runId: string & {
|
|
59
62
|
readonly __brand: "v2.RunId";
|
|
60
63
|
};
|
|
61
64
|
nodeId: string & {
|
|
62
65
|
readonly __brand: "v2.NodeId";
|
|
63
66
|
};
|
|
64
|
-
attemptId: string & {
|
|
65
|
-
readonly __brand: "v2.AttemptId";
|
|
66
|
-
};
|
|
67
67
|
tokenVersion: 1;
|
|
68
68
|
tokenKind: "ack";
|
|
69
69
|
}, {
|
|
70
70
|
sessionId: string;
|
|
71
|
+
attemptId: string;
|
|
71
72
|
runId: string;
|
|
72
73
|
nodeId: string;
|
|
73
|
-
attemptId: string;
|
|
74
74
|
tokenVersion: 1;
|
|
75
75
|
tokenKind: "ack";
|
|
76
76
|
}>;
|
|
@@ -93,22 +93,22 @@ export declare const CheckpointTokenPayloadV1Schema: z.ZodObject<{
|
|
|
93
93
|
sessionId: string & {
|
|
94
94
|
readonly __brand: "v2.SessionId";
|
|
95
95
|
};
|
|
96
|
+
attemptId: string & {
|
|
97
|
+
readonly __brand: "v2.AttemptId";
|
|
98
|
+
};
|
|
96
99
|
runId: string & {
|
|
97
100
|
readonly __brand: "v2.RunId";
|
|
98
101
|
};
|
|
99
102
|
nodeId: string & {
|
|
100
103
|
readonly __brand: "v2.NodeId";
|
|
101
104
|
};
|
|
102
|
-
attemptId: string & {
|
|
103
|
-
readonly __brand: "v2.AttemptId";
|
|
104
|
-
};
|
|
105
105
|
tokenVersion: 1;
|
|
106
106
|
tokenKind: "checkpoint";
|
|
107
107
|
}, {
|
|
108
108
|
sessionId: string;
|
|
109
|
+
attemptId: string;
|
|
109
110
|
runId: string;
|
|
110
111
|
nodeId: string;
|
|
111
|
-
attemptId: string;
|
|
112
112
|
tokenVersion: 1;
|
|
113
113
|
tokenKind: "checkpoint";
|
|
114
114
|
}>;
|
|
@@ -160,22 +160,22 @@ export declare const TokenPayloadV1Schema: z.ZodDiscriminatedUnion<"tokenKind",
|
|
|
160
160
|
sessionId: string & {
|
|
161
161
|
readonly __brand: "v2.SessionId";
|
|
162
162
|
};
|
|
163
|
+
attemptId: string & {
|
|
164
|
+
readonly __brand: "v2.AttemptId";
|
|
165
|
+
};
|
|
163
166
|
runId: string & {
|
|
164
167
|
readonly __brand: "v2.RunId";
|
|
165
168
|
};
|
|
166
169
|
nodeId: string & {
|
|
167
170
|
readonly __brand: "v2.NodeId";
|
|
168
171
|
};
|
|
169
|
-
attemptId: string & {
|
|
170
|
-
readonly __brand: "v2.AttemptId";
|
|
171
|
-
};
|
|
172
172
|
tokenVersion: 1;
|
|
173
173
|
tokenKind: "ack";
|
|
174
174
|
}, {
|
|
175
175
|
sessionId: string;
|
|
176
|
+
attemptId: string;
|
|
176
177
|
runId: string;
|
|
177
178
|
nodeId: string;
|
|
178
|
-
attemptId: string;
|
|
179
179
|
tokenVersion: 1;
|
|
180
180
|
tokenKind: "ack";
|
|
181
181
|
}>, z.ZodObject<{
|
|
@@ -189,22 +189,22 @@ export declare const TokenPayloadV1Schema: z.ZodDiscriminatedUnion<"tokenKind",
|
|
|
189
189
|
sessionId: string & {
|
|
190
190
|
readonly __brand: "v2.SessionId";
|
|
191
191
|
};
|
|
192
|
+
attemptId: string & {
|
|
193
|
+
readonly __brand: "v2.AttemptId";
|
|
194
|
+
};
|
|
192
195
|
runId: string & {
|
|
193
196
|
readonly __brand: "v2.RunId";
|
|
194
197
|
};
|
|
195
198
|
nodeId: string & {
|
|
196
199
|
readonly __brand: "v2.NodeId";
|
|
197
200
|
};
|
|
198
|
-
attemptId: string & {
|
|
199
|
-
readonly __brand: "v2.AttemptId";
|
|
200
|
-
};
|
|
201
201
|
tokenVersion: 1;
|
|
202
202
|
tokenKind: "checkpoint";
|
|
203
203
|
}, {
|
|
204
204
|
sessionId: string;
|
|
205
|
+
attemptId: string;
|
|
205
206
|
runId: string;
|
|
206
207
|
nodeId: string;
|
|
207
|
-
attemptId: string;
|
|
208
208
|
tokenVersion: 1;
|
|
209
209
|
tokenKind: "checkpoint";
|
|
210
210
|
}>]>;
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import { ResultAsync as RA } from 'neverthrow';
|
|
2
|
+
import type { WorkspaceAnchorPortV2, WorkspaceAnchor, WorkspaceAnchorError } from '../../../ports/workspace-anchor.port.js';
|
|
3
|
+
export declare class LocalWorkspaceAnchorV2 implements WorkspaceAnchorPortV2 {
|
|
4
|
+
private readonly cwd;
|
|
5
|
+
constructor(cwd: string);
|
|
6
|
+
resolveAnchors(): RA<readonly WorkspaceAnchor[], WorkspaceAnchorError>;
|
|
7
|
+
private resolve;
|
|
8
|
+
private gitCommand;
|
|
9
|
+
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.LocalWorkspaceAnchorV2 = void 0;
|
|
4
|
+
const neverthrow_1 = require("neverthrow");
|
|
5
|
+
const child_process_1 = require("child_process");
|
|
6
|
+
const util_1 = require("util");
|
|
7
|
+
const execAsync = (0, util_1.promisify)(child_process_1.exec);
|
|
8
|
+
class LocalWorkspaceAnchorV2 {
|
|
9
|
+
constructor(cwd) {
|
|
10
|
+
this.cwd = cwd;
|
|
11
|
+
}
|
|
12
|
+
resolveAnchors() {
|
|
13
|
+
return neverthrow_1.ResultAsync.fromPromise(this.resolve(), (cause) => ({
|
|
14
|
+
code: 'ANCHOR_RESOLVE_FAILED',
|
|
15
|
+
message: `Failed to resolve workspace anchors: ${String(cause)}`,
|
|
16
|
+
}));
|
|
17
|
+
}
|
|
18
|
+
async resolve() {
|
|
19
|
+
const anchors = [];
|
|
20
|
+
const branch = await this.gitCommand('git rev-parse --abbrev-ref HEAD');
|
|
21
|
+
if (branch && branch !== 'HEAD') {
|
|
22
|
+
anchors.push({ key: 'git_branch', value: branch });
|
|
23
|
+
}
|
|
24
|
+
const sha = await this.gitCommand('git rev-parse HEAD');
|
|
25
|
+
if (sha && /^[0-9a-f]{40}$/.test(sha)) {
|
|
26
|
+
anchors.push({ key: 'git_head_sha', value: sha });
|
|
27
|
+
}
|
|
28
|
+
return anchors;
|
|
29
|
+
}
|
|
30
|
+
async gitCommand(cmd) {
|
|
31
|
+
try {
|
|
32
|
+
const { stdout } = await execAsync(cmd, {
|
|
33
|
+
cwd: this.cwd,
|
|
34
|
+
timeout: 5000,
|
|
35
|
+
encoding: 'utf8',
|
|
36
|
+
});
|
|
37
|
+
return stdout.trim() || null;
|
|
38
|
+
}
|
|
39
|
+
catch {
|
|
40
|
+
return null;
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
exports.LocalWorkspaceAnchorV2 = LocalWorkspaceAnchorV2;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { ResultAsync } from 'neverthrow';
|
|
2
|
+
export type WorkspaceAnchor = {
|
|
3
|
+
readonly key: 'git_branch';
|
|
4
|
+
readonly value: string;
|
|
5
|
+
} | {
|
|
6
|
+
readonly key: 'git_head_sha';
|
|
7
|
+
readonly value: string;
|
|
8
|
+
} | {
|
|
9
|
+
readonly key: 'repo_root_hash';
|
|
10
|
+
readonly value: string;
|
|
11
|
+
};
|
|
12
|
+
export type WorkspaceAnchorError = {
|
|
13
|
+
readonly code: 'ANCHOR_RESOLVE_FAILED';
|
|
14
|
+
readonly message: string;
|
|
15
|
+
};
|
|
16
|
+
export interface WorkspaceAnchorPortV2 {
|
|
17
|
+
resolveAnchors(): ResultAsync<readonly WorkspaceAnchor[], WorkspaceAnchorError>;
|
|
18
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Result } from 'neverthrow';
|
|
2
|
+
import type { DomainEventV1 } from '../durable-core/schemas/session/index.js';
|
|
3
|
+
export type ArtifactProjectionError = {
|
|
4
|
+
readonly code: 'PROJECTION_INVARIANT_VIOLATION';
|
|
5
|
+
readonly message: string;
|
|
6
|
+
};
|
|
7
|
+
export interface ProjectedArtifactV2 {
|
|
8
|
+
readonly content: unknown;
|
|
9
|
+
readonly outputId: string;
|
|
10
|
+
readonly sha256: string;
|
|
11
|
+
readonly contentType: string;
|
|
12
|
+
readonly byteLength: number;
|
|
13
|
+
readonly createdAtEventIndex: number;
|
|
14
|
+
}
|
|
15
|
+
export interface NodeArtifactsViewV2 {
|
|
16
|
+
readonly artifacts: readonly ProjectedArtifactV2[];
|
|
17
|
+
}
|
|
18
|
+
export interface ArtifactsProjectionV2 {
|
|
19
|
+
readonly byNodeId: Readonly<Record<string, NodeArtifactsViewV2>>;
|
|
20
|
+
}
|
|
21
|
+
export declare function projectArtifactsV2(events: readonly DomainEventV1[]): Result<ArtifactsProjectionV2, ArtifactProjectionError>;
|
|
22
|
+
export declare function getArtifactContentsForNode(projection: ArtifactsProjectionV2, nodeId: string): readonly unknown[];
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.projectArtifactsV2 = projectArtifactsV2;
|
|
4
|
+
exports.getArtifactContentsForNode = getArtifactContentsForNode;
|
|
5
|
+
const neverthrow_1 = require("neverthrow");
|
|
6
|
+
function projectArtifactsV2(events) {
|
|
7
|
+
const byNodeId = {};
|
|
8
|
+
for (let i = 1; i < events.length; i++) {
|
|
9
|
+
if (events[i].eventIndex < events[i - 1].eventIndex) {
|
|
10
|
+
return (0, neverthrow_1.err)({
|
|
11
|
+
code: 'PROJECTION_INVARIANT_VIOLATION',
|
|
12
|
+
message: 'Events must be sorted by eventIndex ascending',
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
}
|
|
16
|
+
for (const e of events) {
|
|
17
|
+
if (e.kind !== 'node_output_appended')
|
|
18
|
+
continue;
|
|
19
|
+
if (e.data.outputChannel !== 'artifact')
|
|
20
|
+
continue;
|
|
21
|
+
const payload = e.data.payload;
|
|
22
|
+
if (payload.payloadKind !== 'artifact_ref')
|
|
23
|
+
continue;
|
|
24
|
+
const contentPayload = payload;
|
|
25
|
+
if (contentPayload.content === undefined)
|
|
26
|
+
continue;
|
|
27
|
+
const nodeId = e.scope?.nodeId;
|
|
28
|
+
if (!nodeId)
|
|
29
|
+
continue;
|
|
30
|
+
if (!byNodeId[nodeId]) {
|
|
31
|
+
byNodeId[nodeId] = { artifacts: [] };
|
|
32
|
+
}
|
|
33
|
+
byNodeId[nodeId].artifacts.push({
|
|
34
|
+
content: contentPayload.content,
|
|
35
|
+
outputId: e.data.outputId,
|
|
36
|
+
sha256: payload.sha256,
|
|
37
|
+
contentType: payload.contentType,
|
|
38
|
+
byteLength: payload.byteLength,
|
|
39
|
+
createdAtEventIndex: e.eventIndex,
|
|
40
|
+
});
|
|
41
|
+
}
|
|
42
|
+
const result = {};
|
|
43
|
+
for (const [nodeId, view] of Object.entries(byNodeId)) {
|
|
44
|
+
result[nodeId] = { artifacts: view.artifacts };
|
|
45
|
+
}
|
|
46
|
+
return (0, neverthrow_1.ok)({ byNodeId: result });
|
|
47
|
+
}
|
|
48
|
+
function getArtifactContentsForNode(projection, nodeId) {
|
|
49
|
+
const view = projection.byNodeId[nodeId];
|
|
50
|
+
if (!view)
|
|
51
|
+
return [];
|
|
52
|
+
return view.artifacts.map(a => a.content);
|
|
53
|
+
}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import type { Result } from 'neverthrow';
|
|
2
|
+
export interface ProjectionTimingV2 {
|
|
3
|
+
readonly projectionName: string;
|
|
4
|
+
readonly eventCount: number;
|
|
5
|
+
readonly durationMs: number;
|
|
6
|
+
}
|
|
7
|
+
export type ProjectionTimingSink = (timing: ProjectionTimingV2) => void;
|
|
8
|
+
export declare const noopTimingSink: ProjectionTimingSink;
|
|
9
|
+
export declare function withProjectionTiming<E, T>(projectionName: string, fn: (events: readonly {
|
|
10
|
+
readonly eventIndex: number;
|
|
11
|
+
}[]) => Result<T, E>, sink?: ProjectionTimingSink): (events: readonly {
|
|
12
|
+
readonly eventIndex: number;
|
|
13
|
+
}[]) => Result<T, E>;
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.noopTimingSink = void 0;
|
|
4
|
+
exports.withProjectionTiming = withProjectionTiming;
|
|
5
|
+
const noopTimingSink = () => { };
|
|
6
|
+
exports.noopTimingSink = noopTimingSink;
|
|
7
|
+
function withProjectionTiming(projectionName, fn, sink = exports.noopTimingSink) {
|
|
8
|
+
return (events) => {
|
|
9
|
+
const start = performance.now();
|
|
10
|
+
const result = fn(events);
|
|
11
|
+
const durationMs = performance.now() - start;
|
|
12
|
+
try {
|
|
13
|
+
sink({
|
|
14
|
+
projectionName,
|
|
15
|
+
eventCount: events.length,
|
|
16
|
+
durationMs: Math.round(durationMs * 100) / 100,
|
|
17
|
+
});
|
|
18
|
+
}
|
|
19
|
+
catch {
|
|
20
|
+
}
|
|
21
|
+
return result;
|
|
22
|
+
};
|
|
23
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Result } from 'neverthrow';
|
|
2
|
+
import type { DomainEventV1 } from '../durable-core/schemas/session/index.js';
|
|
3
|
+
import type { JsonObject } from '../durable-core/canonical/json-types.js';
|
|
4
|
+
import type { RunId } from '../durable-core/ids/index.js';
|
|
5
|
+
export type ProjectionError = {
|
|
6
|
+
readonly code: 'PROJECTION_INVARIANT_VIOLATION';
|
|
7
|
+
readonly message: string;
|
|
8
|
+
} | {
|
|
9
|
+
readonly code: 'PROJECTION_CORRUPTION_DETECTED';
|
|
10
|
+
readonly message: string;
|
|
11
|
+
};
|
|
12
|
+
export interface RunContextV2 {
|
|
13
|
+
readonly runId: RunId;
|
|
14
|
+
readonly context: JsonObject;
|
|
15
|
+
readonly contextId: string;
|
|
16
|
+
readonly source: 'initial' | 'agent_delta';
|
|
17
|
+
readonly setAtEventIndex: number;
|
|
18
|
+
}
|
|
19
|
+
export interface RunContextProjectionV2 {
|
|
20
|
+
readonly byRunId: Readonly<Record<string, RunContextV2>>;
|
|
21
|
+
}
|
|
22
|
+
export declare function projectRunContextV2(events: readonly DomainEventV1[]): Result<RunContextProjectionV2, ProjectionError>;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.projectRunContextV2 = projectRunContextV2;
|
|
4
|
+
const neverthrow_1 = require("neverthrow");
|
|
5
|
+
const index_js_1 = require("../durable-core/ids/index.js");
|
|
6
|
+
function projectRunContextV2(events) {
|
|
7
|
+
for (let i = 1; i < events.length; i++) {
|
|
8
|
+
if (events[i].eventIndex < events[i - 1].eventIndex) {
|
|
9
|
+
return (0, neverthrow_1.err)({ code: 'PROJECTION_INVARIANT_VIOLATION', message: 'Events must be sorted by eventIndex ascending' });
|
|
10
|
+
}
|
|
11
|
+
}
|
|
12
|
+
const byRunId = {};
|
|
13
|
+
for (const e of events) {
|
|
14
|
+
if (e.kind !== 'context_set')
|
|
15
|
+
continue;
|
|
16
|
+
const runId = e.scope.runId;
|
|
17
|
+
const context = e.data.context;
|
|
18
|
+
if (!context || typeof context !== 'object' || Array.isArray(context)) {
|
|
19
|
+
return (0, neverthrow_1.err)({
|
|
20
|
+
code: 'PROJECTION_CORRUPTION_DETECTED',
|
|
21
|
+
message: `context_set event has invalid context type (runId=${runId}, eventId=${e.eventId})`,
|
|
22
|
+
});
|
|
23
|
+
}
|
|
24
|
+
byRunId[runId] = {
|
|
25
|
+
runId: (0, index_js_1.asRunId)(runId),
|
|
26
|
+
context: context,
|
|
27
|
+
contextId: e.data.contextId,
|
|
28
|
+
source: e.data.source,
|
|
29
|
+
setAtEventIndex: e.eventIndex,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
return (0, neverthrow_1.ok)({ byRunId });
|
|
33
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Result } from 'neverthrow';
|
|
2
2
|
import type { DomainEventV1 } from '../durable-core/schemas/session/index.js';
|
|
3
|
-
export type NodeKindV2 = 'step' | 'checkpoint';
|
|
3
|
+
export type NodeKindV2 = 'step' | 'checkpoint' | 'blocked_attempt';
|
|
4
4
|
export type EdgeKindV2 = 'acked_step' | 'checkpoint';
|
|
5
5
|
export type ProjectionError = {
|
|
6
6
|
readonly code: 'PROJECTION_INVARIANT_VIOLATION';
|
|
@@ -4,7 +4,6 @@ exports.projectRunStatusSignalsV2 = projectRunStatusSignalsV2;
|
|
|
4
4
|
const neverthrow_1 = require("neverthrow");
|
|
5
5
|
const run_dag_js_1 = require("./run-dag.js");
|
|
6
6
|
const gaps_js_1 = require("./gaps.js");
|
|
7
|
-
const advance_outcomes_js_1 = require("./advance-outcomes.js");
|
|
8
7
|
function projectRunStatusSignalsV2(events) {
|
|
9
8
|
const dagRes = (0, run_dag_js_1.projectRunDagV2)(events);
|
|
10
9
|
if (dagRes.isErr())
|
|
@@ -14,10 +13,6 @@ function projectRunStatusSignalsV2(events) {
|
|
|
14
13
|
if (gapsRes.isErr())
|
|
15
14
|
return (0, neverthrow_1.err)(gapsRes.error);
|
|
16
15
|
const gaps = gapsRes.value;
|
|
17
|
-
const advanceRes = (0, advance_outcomes_js_1.projectAdvanceOutcomesV2)(events);
|
|
18
|
-
if (advanceRes.isErr())
|
|
19
|
-
return (0, neverthrow_1.err)(advanceRes.error);
|
|
20
|
-
const advances = advanceRes.value;
|
|
21
16
|
const prefsByNodeId = {};
|
|
22
17
|
for (const e of events) {
|
|
23
18
|
if (e.kind !== 'preferences_changed')
|
|
@@ -34,9 +29,9 @@ function projectRunStatusSignalsV2(events) {
|
|
|
34
29
|
const hasBlockingCategoryGap = (gaps.unresolvedCriticalByRunId[runId] ?? []).some((g) => g.reason.category === 'user_only_dependency' ||
|
|
35
30
|
g.reason.category === 'contract_violation' ||
|
|
36
31
|
g.reason.category === 'capability_missing');
|
|
37
|
-
const
|
|
38
|
-
const
|
|
39
|
-
const isBlocked = prefs.autonomy !== 'full_auto_never_stop' && (
|
|
32
|
+
const tipNodeKind = tip ? run.nodesById[tip]?.nodeKind : undefined;
|
|
33
|
+
const blockedByTopology = tipNodeKind === 'blocked_attempt';
|
|
34
|
+
const isBlocked = prefs.autonomy !== 'full_auto_never_stop' && (blockedByTopology || hasBlockingCategoryGap);
|
|
40
35
|
byRunId[runId] = {
|
|
41
36
|
runId,
|
|
42
37
|
preferredTipNodeId: tip,
|
package/package.json
CHANGED
|
@@ -107,6 +107,23 @@
|
|
|
107
107
|
"additionalProperties": false
|
|
108
108
|
},
|
|
109
109
|
"uniqueItems": true
|
|
110
|
+
},
|
|
111
|
+
"recommendedPreferences": {
|
|
112
|
+
"type": "object",
|
|
113
|
+
"description": "Workflow-level preference recommendations. When effective preferences exceed these, structured warnings are emitted. Never hard-blocks user choice.",
|
|
114
|
+
"properties": {
|
|
115
|
+
"recommendedAutonomy": {
|
|
116
|
+
"type": "string",
|
|
117
|
+
"enum": ["guided", "full_auto_stop_on_user_deps", "full_auto_never_stop"],
|
|
118
|
+
"description": "Recommended autonomy level for this workflow"
|
|
119
|
+
},
|
|
120
|
+
"recommendedRiskPolicy": {
|
|
121
|
+
"type": "string",
|
|
122
|
+
"enum": ["conservative", "balanced", "aggressive"],
|
|
123
|
+
"description": "Recommended risk policy for this workflow"
|
|
124
|
+
}
|
|
125
|
+
},
|
|
126
|
+
"additionalProperties": false
|
|
110
127
|
}
|
|
111
128
|
},
|
|
112
129
|
"required": [
|
|
@@ -169,6 +186,7 @@
|
|
|
169
186
|
"requireConfirmation": { "$ref": "#/$defs/confirmationRule" },
|
|
170
187
|
"runCondition": { "$ref": "#/$defs/condition" },
|
|
171
188
|
"validationCriteria": { "oneOf": [ { "type": "array", "items": { "$ref": "#/$defs/validationRule" } }, { "$ref": "#/$defs/validationComposition" } ] },
|
|
189
|
+
"outputContract": { "$ref": "#/$defs/outputContract" },
|
|
172
190
|
"functionDefinitions": { "type": "array", "items": { "$ref": "#/$defs/functionDefinition" } },
|
|
173
191
|
"functionCalls": { "type": "array", "items": { "$ref": "#/$defs/functionCall" } },
|
|
174
192
|
"functionReferences": { "type": "array", "items": { "type": "string", "pattern": "^[a-zA-Z_][a-zA-Z0-9_]*\\(\\)$" } }
|
|
@@ -286,6 +304,30 @@
|
|
|
286
304
|
"type": "string",
|
|
287
305
|
"pattern": "^[a-zA-Z_][a-zA-Z0-9_]*$",
|
|
288
306
|
"description": "Custom variable name for current index (forEach loops)"
|
|
307
|
+
},
|
|
308
|
+
"conditionSource": {
|
|
309
|
+
"description": "Explicit condition source for while/until loops. Auto-derived by compiler when absent.",
|
|
310
|
+
"oneOf": [
|
|
311
|
+
{
|
|
312
|
+
"type": "object",
|
|
313
|
+
"properties": {
|
|
314
|
+
"kind": { "const": "artifact_contract" },
|
|
315
|
+
"contractRef": { "type": "string", "minLength": 1 },
|
|
316
|
+
"loopId": { "type": "string", "minLength": 1 }
|
|
317
|
+
},
|
|
318
|
+
"required": ["kind", "contractRef", "loopId"],
|
|
319
|
+
"additionalProperties": false
|
|
320
|
+
},
|
|
321
|
+
{
|
|
322
|
+
"type": "object",
|
|
323
|
+
"properties": {
|
|
324
|
+
"kind": { "const": "context_variable" },
|
|
325
|
+
"condition": { "$ref": "#/$defs/condition" }
|
|
326
|
+
},
|
|
327
|
+
"required": ["kind", "condition"],
|
|
328
|
+
"additionalProperties": false
|
|
329
|
+
}
|
|
330
|
+
]
|
|
289
331
|
}
|
|
290
332
|
},
|
|
291
333
|
"required": ["type", "maxIterations"],
|
|
@@ -516,6 +558,24 @@
|
|
|
516
558
|
}
|
|
517
559
|
]
|
|
518
560
|
},
|
|
561
|
+
"outputContract": {
|
|
562
|
+
"type": "object",
|
|
563
|
+
"description": "Typed output contract declaring required artifact schema",
|
|
564
|
+
"properties": {
|
|
565
|
+
"contractRef": {
|
|
566
|
+
"type": "string",
|
|
567
|
+
"description": "Artifact contract reference (e.g. wr.contracts.loop_control)",
|
|
568
|
+
"minLength": 1
|
|
569
|
+
},
|
|
570
|
+
"required": {
|
|
571
|
+
"type": "boolean",
|
|
572
|
+
"description": "Whether the artifact is required (default true)",
|
|
573
|
+
"default": true
|
|
574
|
+
}
|
|
575
|
+
},
|
|
576
|
+
"required": ["contractRef"],
|
|
577
|
+
"additionalProperties": false
|
|
578
|
+
},
|
|
519
579
|
"functionCall": {
|
|
520
580
|
"type": "object",
|
|
521
581
|
"properties": {
|
|
@@ -223,6 +223,9 @@
|
|
|
223
223
|
"$ref": "#/$defs/validationComposition"
|
|
224
224
|
}
|
|
225
225
|
]
|
|
226
|
+
},
|
|
227
|
+
"outputContract": {
|
|
228
|
+
"$ref": "#/$defs/outputContract"
|
|
226
229
|
}
|
|
227
230
|
},
|
|
228
231
|
"required": [
|
|
@@ -243,6 +246,23 @@
|
|
|
243
246
|
"maxLength": 256
|
|
244
247
|
},
|
|
245
248
|
"uniqueItems": true
|
|
249
|
+
},
|
|
250
|
+
"recommendedPreferences": {
|
|
251
|
+
"type": "object",
|
|
252
|
+
"description": "Workflow-level preference recommendations. When effective preferences exceed these, structured warnings are emitted. Never hard-blocks user choice.",
|
|
253
|
+
"properties": {
|
|
254
|
+
"recommendedAutonomy": {
|
|
255
|
+
"type": "string",
|
|
256
|
+
"enum": ["guided", "full_auto_stop_on_user_deps", "full_auto_never_stop"],
|
|
257
|
+
"description": "Recommended autonomy level for this workflow"
|
|
258
|
+
},
|
|
259
|
+
"recommendedRiskPolicy": {
|
|
260
|
+
"type": "string",
|
|
261
|
+
"enum": ["conservative", "balanced", "aggressive"],
|
|
262
|
+
"description": "Recommended risk policy for this workflow"
|
|
263
|
+
}
|
|
264
|
+
},
|
|
265
|
+
"additionalProperties": false
|
|
246
266
|
}
|
|
247
267
|
},
|
|
248
268
|
"required": [
|
|
@@ -388,6 +408,24 @@
|
|
|
388
408
|
"$ref": "#/$defs/validationComposition"
|
|
389
409
|
}
|
|
390
410
|
]
|
|
411
|
+
},
|
|
412
|
+
"outputContract": {
|
|
413
|
+
"type": "object",
|
|
414
|
+
"description": "Typed output contract declaring required artifact schema",
|
|
415
|
+
"properties": {
|
|
416
|
+
"contractRef": {
|
|
417
|
+
"type": "string",
|
|
418
|
+
"description": "Artifact contract reference (e.g. wr.contracts.loop_control)",
|
|
419
|
+
"minLength": 1
|
|
420
|
+
},
|
|
421
|
+
"required": {
|
|
422
|
+
"type": "boolean",
|
|
423
|
+
"description": "Whether the artifact is required (default true)",
|
|
424
|
+
"default": true
|
|
425
|
+
}
|
|
426
|
+
},
|
|
427
|
+
"required": ["contractRef"],
|
|
428
|
+
"additionalProperties": false
|
|
391
429
|
}
|
|
392
430
|
}
|
|
393
431
|
}
|
|
@@ -1,8 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"id": "coding-task-workflow-agentic",
|
|
3
3
|
"name": "Agentic Task Dev Workflow (Invariants • Architecture • Vertical Slices • PR Sizing • Audits • Resumable)",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.5.0",
|
|
5
5
|
"description": "Coding workflow that explores multiple approaches before committing—avoids anchoring on the first idea. Flow: constraints → approaches → compare → decide → slices → verify. Use when getting it right matters.",
|
|
6
|
+
"recommendedPreferences": {
|
|
7
|
+
"recommendedAutonomy": "guided",
|
|
8
|
+
"recommendedRiskPolicy": "conservative"
|
|
9
|
+
},
|
|
6
10
|
"preconditions": [
|
|
7
11
|
"User provides a task description (ticket text or equivalent) and success criteria (even if partial).",
|
|
8
12
|
"Agent has read access to the codebase and can use tools (search/read/edit/terminal).",
|
|
@@ -283,17 +287,8 @@
|
|
|
283
287
|
"var": "taskComplexity",
|
|
284
288
|
"not_equals": "Small"
|
|
285
289
|
},
|
|
286
|
-
"prompt": "Initialize a bounded plan-iteration loop.\n\
|
|
287
|
-
"requireConfirmation": false
|
|
288
|
-
"validationCriteria": {
|
|
289
|
-
"and": [
|
|
290
|
-
{
|
|
291
|
-
"type": "contains",
|
|
292
|
-
"value": "continuePlanning = true",
|
|
293
|
-
"message": "Must explicitly set: continuePlanning = true (otherwise the planning loop may not run)"
|
|
294
|
-
}
|
|
295
|
-
]
|
|
296
|
-
}
|
|
290
|
+
"prompt": "Initialize a bounded plan-iteration loop.\n\nRule: max 5 iterations. Continue while issues are found; stop when a pass is clean (no findings).\n\nThe loop will enter automatically. The exit decision step inside the loop will use a typed artifact to control continuation.",
|
|
291
|
+
"requireConfirmation": false
|
|
297
292
|
},
|
|
298
293
|
{
|
|
299
294
|
"id": "phase-5-plan-iterations",
|
|
@@ -344,15 +339,13 @@
|
|
|
344
339
|
{
|
|
345
340
|
"id": "phase-5d-loop-exit-decision",
|
|
346
341
|
"title": "Loop Exit Decision (Fail-Safe)",
|
|
347
|
-
"prompt": "**Non-optional:**
|
|
342
|
+
"prompt": "**Non-optional:** Provide a loop control decision artifact.\n\n**Output (exact format):**\n- Loop control artifact with decision: continue or stop\n- `reason`: one sentence\n- `whatChangedSinceLastIteration`: 1–3 bullets\n\n**Loop continuation logic (continue while issues found):**\n\n- If `planFindings` is **NON-EMPTY** (issues found this pass):\n → decision: continue\n → Rationale: Amendments need verification; may have introduced new issues\n\n- If `planFindings` is **EMPTY** (clean pass):\n → decision: stop\n → Rationale: Plan is stable, no more issues to find\n\n**Max iterations (5) still applies** — if you've hit 5 iterations and still finding issues, exit anyway and note remaining concerns.\n\n**Override to exit early:**\n- User explicitly requests to proceed\n- All findings are Minor AND `planConfidence >= 8`\n\nIf continuing, name what was found + what changes next iteration.\n\n**CONTEXT LOGGING:** Update CONTEXT.md Decision Log (follow format from metaGuidance) and update Machine State Checkpoint (keep last 3).",
|
|
348
343
|
"requireConfirmation": true,
|
|
344
|
+
"outputContract": {
|
|
345
|
+
"contractRef": "wr.contracts.loop_control"
|
|
346
|
+
},
|
|
349
347
|
"validationCriteria": {
|
|
350
348
|
"and": [
|
|
351
|
-
{
|
|
352
|
-
"type": "contains",
|
|
353
|
-
"value": "continuePlanning",
|
|
354
|
-
"message": "Must explicitly set: continuePlanning = true or false"
|
|
355
|
-
},
|
|
356
349
|
{
|
|
357
350
|
"type": "contains",
|
|
358
351
|
"value": "reason:",
|