@tomflow/proflow-task-orchestration 0.1.10 → 0.1.11
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/CHANGELOG.md +6 -0
- package/dist/deployment/adapter.d.ts +3 -3
- package/dist/deployment/descriptor.d.ts +1 -1
- package/dist/deployment/descriptor.js +1 -1
- package/dist/src/contracts.js +2 -2
- package/dist/src/model.d.ts +2 -0
- package/dist/src/model.js +5 -0
- package/dist/src/services.d.ts +1 -0
- package/dist/src/services.js +30 -5
- package/dist/src/transitions.js +1 -1
- package/package.json +2 -2
- package/proflow.module.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# @tomflow/proflow-task-orchestration
|
|
2
2
|
|
|
3
|
+
## 0.1.11
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- Release the verified Real-3 B1 task recovery, exact execution identity, durable observer resume, bounded gateway error, and matching Agent Action contract fixes.
|
|
8
|
+
|
|
3
9
|
## 0.1.10
|
|
4
10
|
|
|
5
11
|
### Patch Changes
|
|
@@ -4,7 +4,7 @@ declare const success: () => {
|
|
|
4
4
|
readonly ok: true;
|
|
5
5
|
readonly status: "SUCCEEDED";
|
|
6
6
|
readonly moduleRef: "task-orchestration";
|
|
7
|
-
readonly moduleVersion: "0.1.
|
|
7
|
+
readonly moduleVersion: "0.1.11";
|
|
8
8
|
};
|
|
9
9
|
observedEffects: string[];
|
|
10
10
|
};
|
|
@@ -17,7 +17,7 @@ export declare const behaviorAdapter: {
|
|
|
17
17
|
ok: true;
|
|
18
18
|
status: "SUCCEEDED";
|
|
19
19
|
moduleRef: "task-orchestration";
|
|
20
|
-
moduleVersion: "0.1.
|
|
20
|
+
moduleVersion: "0.1.11";
|
|
21
21
|
data: {
|
|
22
22
|
setupStatus: "READY";
|
|
23
23
|
runtimeStatus: "NOT_APPLICABLE";
|
|
@@ -32,7 +32,7 @@ export declare const behaviorAdapter: {
|
|
|
32
32
|
ok: true;
|
|
33
33
|
status: "SUCCEEDED";
|
|
34
34
|
moduleRef: "task-orchestration";
|
|
35
|
-
moduleVersion: "0.1.
|
|
35
|
+
moduleVersion: "0.1.11";
|
|
36
36
|
data: {
|
|
37
37
|
docs: string;
|
|
38
38
|
};
|
|
@@ -3,7 +3,7 @@ export declare const descriptor: {
|
|
|
3
3
|
readonly contractVersion: "1.0.0";
|
|
4
4
|
readonly moduleRef: "task-orchestration";
|
|
5
5
|
readonly packageName: "@tomflow/proflow-task-orchestration";
|
|
6
|
-
readonly moduleVersion: "0.1.
|
|
6
|
+
readonly moduleVersion: "0.1.11";
|
|
7
7
|
readonly kind: "library";
|
|
8
8
|
readonly templateVersion: "1.0.0";
|
|
9
9
|
readonly platformCompatibility: ">=1.0.0 <2.0.0";
|
|
@@ -3,7 +3,7 @@ export const descriptor = {
|
|
|
3
3
|
contractVersion: "1.0.0",
|
|
4
4
|
moduleRef: "task-orchestration",
|
|
5
5
|
packageName: "@tomflow/proflow-task-orchestration",
|
|
6
|
-
moduleVersion: "0.1.
|
|
6
|
+
moduleVersion: "0.1.11",
|
|
7
7
|
kind: "library",
|
|
8
8
|
templateVersion: "1.0.0",
|
|
9
9
|
platformCompatibility: ">=1.0.0 <2.0.0",
|
package/dist/src/contracts.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { z } from "zod";
|
|
2
|
-
import { requiredTaskAgentPackageRefs } from "./model.js";
|
|
2
|
+
import { requiredTaskAgentPackageRefs, taskWaitTypes } from "./model.js";
|
|
3
3
|
export const publicOperationNames = [
|
|
4
4
|
"createTaskGroup",
|
|
5
5
|
"getTaskGroup",
|
|
@@ -136,7 +136,7 @@ const schemas = {
|
|
|
136
136
|
waitNode: z
|
|
137
137
|
.object({
|
|
138
138
|
...nodeVersion,
|
|
139
|
-
waitType:
|
|
139
|
+
waitType: z.enum(taskWaitTypes),
|
|
140
140
|
reasonCode: id,
|
|
141
141
|
message: id,
|
|
142
142
|
relatedRef: id.optional(),
|
package/dist/src/model.d.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
export declare const requiredTaskAgentPackageRefs: readonly ["@tomflow/proflow-agent-product", "@tomflow/proflow-agent-controller-dev", "@tomflow/proflow-agent-test-ops"];
|
|
2
|
+
export declare const taskWaitTypes: readonly ["BUSINESS_CONFIRMATION", "REQUIREMENT_BLOCKED", "EXTERNAL_BUSINESS_DEPENDENCY"];
|
|
3
|
+
export type TaskWaitType = (typeof taskWaitTypes)[number];
|
|
2
4
|
export type TaskGroupStatus = "READY" | "ACTIVE" | "SUCCEEDED";
|
|
3
5
|
export type TaskStatus = "PENDING" | "READY" | "ACTIVE" | "WAITING" | "FAILED" | "PAUSED" | "SUCCEEDED" | "TERMINATED";
|
|
4
6
|
export type NodeStatus = "PENDING" | "READY" | "IN_PROGRESS" | "WAITING" | "FAILED" | "SUCCEEDED" | "TERMINATED";
|
package/dist/src/model.js
CHANGED
package/dist/src/services.d.ts
CHANGED
|
@@ -144,6 +144,7 @@ export declare function createTaskServices(options: {
|
|
|
144
144
|
} | null;
|
|
145
145
|
canDrive: boolean;
|
|
146
146
|
blockedReason: string | null;
|
|
147
|
+
resumeSignalRef: string | null;
|
|
147
148
|
}>;
|
|
148
149
|
getNodeContext: (raw: unknown) => TaskResult<{
|
|
149
150
|
task: Pick<Task, "taskId" | "title" | "objective" | "status" | "version">;
|
package/dist/src/services.js
CHANGED
|
@@ -726,15 +726,24 @@ export function createTaskServices(options) {
|
|
|
726
726
|
const current = task.currentNodeId
|
|
727
727
|
? tx.nodes.get(task.currentNodeId)
|
|
728
728
|
: undefined;
|
|
729
|
+
if (task.status === "WAITING" && current?.status !== "WAITING")
|
|
730
|
+
throw new DomainError("TASK_INVALID_STATE", "A WAITING Task must have a current WAITING Node.");
|
|
729
731
|
if (current?.status === "FAILED")
|
|
730
732
|
throw new DomainError("TASK_INVALID_STATE", "A failed Node must be explicitly reopened before resume.");
|
|
731
|
-
if (current?.status === "WAITING")
|
|
733
|
+
if (current?.status === "WAITING") {
|
|
734
|
+
const unresolved = tx.messages
|
|
735
|
+
.listPending()
|
|
736
|
+
.some((message) => message.taskId === task.taskId &&
|
|
737
|
+
message.nodeId === current.nodeId);
|
|
738
|
+
if (unresolved)
|
|
739
|
+
throw new DomainError("TASK_BLOCKER_UNRESOLVED", "The current Node still has an unresolved business blocker.");
|
|
732
740
|
tx.nodes.update({
|
|
733
741
|
...current,
|
|
734
742
|
status: "IN_PROGRESS",
|
|
735
743
|
version: current.version + 1,
|
|
736
744
|
updatedAt: timestamp,
|
|
737
745
|
});
|
|
746
|
+
}
|
|
738
747
|
const updated = {
|
|
739
748
|
...task,
|
|
740
749
|
status: "ACTIVE",
|
|
@@ -910,6 +919,8 @@ export function createTaskServices(options) {
|
|
|
910
919
|
checkVersion(node.version, input.expectedNodeVersion, "NODE_VERSION_CONFLICT");
|
|
911
920
|
if (task.status !== "ACTIVE")
|
|
912
921
|
throw new DomainError("TASK_INVALID_STATE", "Task must be ACTIVE before a Node can wait.");
|
|
922
|
+
if (task.currentNodeId !== node.nodeId)
|
|
923
|
+
throw new DomainError("NODE_NOT_CURRENT", "Only the current Node can enter WAITING.");
|
|
913
924
|
if (node.status !== "IN_PROGRESS" ||
|
|
914
925
|
!matchesWorker(input.actorRef, node.workerRef))
|
|
915
926
|
throw new DomainError(!matchesWorker(input.actorRef, node.workerRef)
|
|
@@ -950,10 +961,14 @@ export function createTaskServices(options) {
|
|
|
950
961
|
const node = requireNode(tx, input.taskId, input.nodeId);
|
|
951
962
|
checkVersion(task.version, input.expectedTaskVersion, "TASK_VERSION_CONFLICT");
|
|
952
963
|
checkVersion(node.version, input.expectedNodeVersion, "NODE_VERSION_CONFLICT");
|
|
953
|
-
if (
|
|
954
|
-
throw new DomainError("TASK_INVALID_STATE", "Task
|
|
955
|
-
if (
|
|
956
|
-
throw new DomainError("
|
|
964
|
+
if (task.status !== "ACTIVE")
|
|
965
|
+
throw new DomainError("TASK_INVALID_STATE", "Task must be ACTIVE before the current run can fail.");
|
|
966
|
+
if (task.currentNodeId !== node.nodeId)
|
|
967
|
+
throw new DomainError("NODE_NOT_CURRENT", "Only the current Node can record a run failure.");
|
|
968
|
+
if (!matchesWorker(input.actorRef, node.workerRef))
|
|
969
|
+
throw new DomainError("WORKER_MISMATCH", "Only the bound running Worker may fail the current Node.");
|
|
970
|
+
if (node.status !== "IN_PROGRESS")
|
|
971
|
+
throw new DomainError("NODE_INVALID_STATE", "Only the current IN_PROGRESS run can fail.");
|
|
957
972
|
const failedNode = {
|
|
958
973
|
...node,
|
|
959
974
|
status: "FAILED",
|
|
@@ -1116,6 +1131,13 @@ export function createTaskServices(options) {
|
|
|
1116
1131
|
else if (!terminal && !roleBinding?.workerRef)
|
|
1117
1132
|
blockedReason = "TASK_ROLE_BINDING_REQUIRED";
|
|
1118
1133
|
const canDrive = !terminal && blockedReason === null;
|
|
1134
|
+
let durableResumeEventId;
|
|
1135
|
+
if (task.status === "ACTIVE" && currentNode?.status === "IN_PROGRESS")
|
|
1136
|
+
for (const taskEvent of tx.events.listByTask(task.taskId))
|
|
1137
|
+
if (taskEvent.eventType === "TASK_RESUMED" &&
|
|
1138
|
+
taskEvent.taskVersion === task.version &&
|
|
1139
|
+
taskEvent.eventId !== undefined)
|
|
1140
|
+
durableResumeEventId = taskEvent.eventId;
|
|
1119
1141
|
return {
|
|
1120
1142
|
taskId: task.taskId,
|
|
1121
1143
|
taskStatus: task.status,
|
|
@@ -1140,6 +1162,9 @@ export function createTaskServices(options) {
|
|
|
1140
1162
|
: null,
|
|
1141
1163
|
canDrive,
|
|
1142
1164
|
blockedReason,
|
|
1165
|
+
resumeSignalRef: durableResumeEventId === undefined
|
|
1166
|
+
? null
|
|
1167
|
+
: `task-event:${durableResumeEventId}`,
|
|
1143
1168
|
};
|
|
1144
1169
|
}),
|
|
1145
1170
|
getNodeContext: (raw) => queryWithDocumentRecovery("getNodeContext", raw, (tx, input) => {
|
package/dist/src/transitions.js
CHANGED
|
@@ -7,7 +7,7 @@ const taskTransitions = {
|
|
|
7
7
|
READY: ["ACTIVE", "TERMINATED"],
|
|
8
8
|
ACTIVE: ["WAITING", "PAUSED", "FAILED", "SUCCEEDED", "TERMINATED"],
|
|
9
9
|
WAITING: ["ACTIVE", "PAUSED", "TERMINATED"],
|
|
10
|
-
FAILED: ["
|
|
10
|
+
FAILED: ["TERMINATED"],
|
|
11
11
|
PAUSED: ["ACTIVE", "TERMINATED"],
|
|
12
12
|
SUCCEEDED: [],
|
|
13
13
|
TERMINATED: [],
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tomflow/proflow-task-orchestration",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.11",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -23,8 +23,8 @@
|
|
|
23
23
|
"@tomflow/proflow-module-contract": "^0.1.13"
|
|
24
24
|
},
|
|
25
25
|
"devDependencies": {
|
|
26
|
-
"@tomflow/proflow-deployment-conformance": "^0.1.13",
|
|
27
26
|
"@tomflow/proflow-task-migration-runner": "^0.1.11",
|
|
27
|
+
"@tomflow/proflow-deployment-conformance": "^0.1.13",
|
|
28
28
|
"@tomflow/proflow-task-store-sqlite": "^0.1.11"
|
|
29
29
|
},
|
|
30
30
|
"description": "Owns the Task & Orchestration public contract, domain rules and application services.",
|
package/proflow.module.json
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
"contractVersion": "1.0.0",
|
|
4
4
|
"moduleRef": "task-orchestration",
|
|
5
5
|
"packageName": "@tomflow/proflow-task-orchestration",
|
|
6
|
-
"moduleVersion": "0.1.
|
|
6
|
+
"moduleVersion": "0.1.11",
|
|
7
7
|
"kind": "library",
|
|
8
8
|
"templateVersion": "1.0.0",
|
|
9
9
|
"platformCompatibility": ">=1.0.0 <2.0.0",
|