anbaric 1.63.0 → 1.64.1
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 +10 -5
- package/docs/patterns/testing.md +8 -6
- package/package.json +5 -5
package/README.md
CHANGED
|
@@ -61,8 +61,8 @@ import {Action, Code, PropertyDefinition, State, StateMachine, Transition} from
|
|
|
61
61
|
|
|
62
62
|
const sendWelcome = new Action("Send welcome email", new Code("welcome"));
|
|
63
63
|
sendWelcome.run = async (job) => {
|
|
64
|
-
// Access properties stored against the job
|
|
65
|
-
const email = job.properties.get("email");
|
|
64
|
+
// Access properties stored against the job - reading one is asynchronous
|
|
65
|
+
const email = await job.properties.get("email");
|
|
66
66
|
// Run some code
|
|
67
67
|
console.log(`Sending welcome email to ${email}`);
|
|
68
68
|
// Return new properties to add to the job
|
|
@@ -72,7 +72,7 @@ sendWelcome.run = async (job) => {
|
|
|
72
72
|
};
|
|
73
73
|
|
|
74
74
|
const onboarding = new StateMachine("onboarding", [
|
|
75
|
-
new State("new", [sendWelcome], [new Transition("active", (job) => job.properties.get("emailSent") === true)]),
|
|
75
|
+
new State("new", [sendWelcome], [new Transition("active", async (job) => await job.properties.get("emailSent") === true)]),
|
|
76
76
|
new State("active"),
|
|
77
77
|
]);
|
|
78
78
|
|
|
@@ -81,6 +81,11 @@ const customer = await onboarding.startJob(new Map([["email", "ada@example.com"]
|
|
|
81
81
|
|
|
82
82
|
The job starts in `new`; when it is processed the action runs, sets `emailSent`, and the transition advances it to `active`.
|
|
83
83
|
|
|
84
|
+
`job.properties` is read on demand: `get`, `has` and `getMany` return promises, so
|
|
85
|
+
a job can hold a great deal while a step that needs one property pays for one.
|
|
86
|
+
That is why an action's `predicate` and a transition's guard may be `async`, as
|
|
87
|
+
above. See [Actions and actors](anbaric/docs/features/actions-and-actors.md#reading-properties-is-asynchronous).
|
|
88
|
+
|
|
84
89
|
### Using AI agents to automate states
|
|
85
90
|
|
|
86
91
|
An **agent** is an actor whose properties are produced by a model rather than by
|
|
@@ -104,7 +109,7 @@ const triage = new RemoteLLMAgenticAction(
|
|
|
104
109
|
);
|
|
105
110
|
|
|
106
111
|
const support = new StateMachine("support", [
|
|
107
|
-
new State("open", [triage], [new Transition("prioritised", (job) => job.properties.has("priority"))]),
|
|
112
|
+
new State("open", [triage], [new Transition("prioritised", async (job) => await job.properties.has("priority"))]),
|
|
108
113
|
new State("prioritised"),
|
|
109
114
|
]);
|
|
110
115
|
```
|
|
@@ -136,7 +141,7 @@ approve.fields = ["approved"]; // the input we
|
|
|
136
141
|
approve.resolveUrl = (job) => `/approve?job=${job.id}`; // where the human provides it
|
|
137
142
|
|
|
138
143
|
const fulfilment = new StateMachine("fulfilment", [
|
|
139
|
-
new State("review", [approve], [new Transition("approved", (job) => job.properties.get("approved") === true)]),
|
|
144
|
+
new State("review", [approve], [new Transition("approved", async (job) => await job.properties.get("approved") === true)]),
|
|
140
145
|
new State("approved"),
|
|
141
146
|
]);
|
|
142
147
|
|
package/docs/patterns/testing.md
CHANGED
|
@@ -25,13 +25,15 @@ test("payOut marks the expense paid", async () => {
|
|
|
25
25
|
`new Job(id, properties, state)` is all you need to construct a job for a test
|
|
26
26
|
(later constructor arguments have sensible defaults).
|
|
27
27
|
|
|
28
|
-
Transition predicates and property validations are just as easy
|
|
28
|
+
Transition predicates and property validations are just as easy. A predicate
|
|
29
|
+
that reads properties is asynchronous, because reading properties is, so `await`
|
|
30
|
+
it:
|
|
29
31
|
|
|
30
32
|
```ts
|
|
31
|
-
test("advances once approved", () => {
|
|
33
|
+
test("advances once approved", async () => {
|
|
32
34
|
const job = new Job("job-1", new Map([["approved", true]]), "review");
|
|
33
35
|
const toApproved = machineTransition("approved");
|
|
34
|
-
expect(toApproved.predicate(job)).toBe(true);
|
|
36
|
+
expect(await toApproved.predicate(job)).toBe(true);
|
|
35
37
|
});
|
|
36
38
|
|
|
37
39
|
test("amount must be positive", () => {
|
|
@@ -46,10 +48,10 @@ If several actions share a state and choose themselves by `predicate`, assert th
|
|
|
46
48
|
selection:
|
|
47
49
|
|
|
48
50
|
```ts
|
|
49
|
-
test("low-priority tickets auto-triage", () => {
|
|
51
|
+
test("low-priority tickets auto-triage", async () => {
|
|
50
52
|
const job = new Job("t1", new Map([["priority", "low"]]), "open");
|
|
51
|
-
expect(autoTriage.predicate(job)).toBe(true);
|
|
52
|
-
expect(escalate.predicate(job)).toBe(false);
|
|
53
|
+
expect(await autoTriage.predicate(job)).toBe(true);
|
|
54
|
+
expect(await escalate.predicate(job)).toBe(false);
|
|
53
55
|
});
|
|
54
56
|
```
|
|
55
57
|
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "anbaric",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.64.1",
|
|
4
4
|
"description": "Everything needed to write an Anbaric app: state machines, jobs, document and secret stores, local in-memory implementations and the Anbaric Cloud clients",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
|
@@ -24,9 +24,9 @@
|
|
|
24
24
|
"prepublishOnly": "npm run build"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
|
-
"anbaric-impl-cloud": "^1.
|
|
28
|
-
"anbaric-data-store": "^1.
|
|
29
|
-
"anbaric-state-machine": "^1.
|
|
30
|
-
"anbaric-tsapi": "^1.
|
|
27
|
+
"anbaric-impl-cloud": "^1.64.1",
|
|
28
|
+
"anbaric-data-store": "^1.64.1",
|
|
29
|
+
"anbaric-state-machine": "^1.64.1",
|
|
30
|
+
"anbaric-tsapi": "^1.64.1"
|
|
31
31
|
}
|
|
32
32
|
}
|