@abloatai/ablo 0.46.0 → 0.48.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/AGENTS.md +1 -1
- package/CHANGELOG.md +160 -0
- package/LICENSE +1 -1
- package/NOTICE +3 -3
- package/README.md +20 -2
- package/docs/agent-messaging.md +0 -1
- package/docs/agents.md +1 -1
- package/docs/api.md +6 -5
- package/docs/cli.md +13 -5
- package/docs/client-behavior.md +8 -7
- package/docs/coordination.md +2 -2
- package/docs/data-sources.md +158 -15
- package/docs/debugging.md +4 -5
- package/docs/examples/agent-human.md +0 -2
- package/docs/examples/existing-python-backend.md +0 -2
- package/docs/examples/nextjs.md +1 -2
- package/docs/examples/server-agent.md +2 -3
- package/docs/groups.md +1 -1
- package/docs/guarantees.md +4 -7
- package/docs/how-it-works.md +6 -6
- package/docs/idempotency.md +0 -1
- package/docs/identity.md +1 -1
- package/docs/index.md +1 -2
- package/docs/integration-guide.md +7 -10
- package/docs/integrations/inngest.md +1 -4
- package/docs/integrations/temporal.md +1 -3
- package/docs/internal/serializable-schema.md +1 -1
- package/docs/internal/structure.md +4 -0
- package/docs/migration.md +3 -3
- package/docs/operating-on-your-database.md +2 -2
- package/docs/react.md +1 -3
- package/docs/schema-contract.md +2 -2
- package/examples/README.md +1 -1
- package/llms.txt +2 -3
- package/package.json +3 -3
- package/docs/internal/agent-orchestration.md +0 -58
|
@@ -46,7 +46,7 @@ Sort any action you're about to take into one of these, and the right move
|
|
|
46
46
|
follows.
|
|
47
47
|
|
|
48
48
|
**Run freely — read-only or reversible.**
|
|
49
|
-
Reads (`
|
|
49
|
+
Reads (`get`, `list`), `ablo check`, and `ablo pull` observe and
|
|
50
50
|
never change anything. Previews — `--show-sql`, `--dry-run` — print the exact
|
|
51
51
|
SQL a command would run without executing it. Model writes through
|
|
52
52
|
`ablo.<model>.create` / `update` are claim-checked, optimistic, rolled back if
|
|
@@ -95,7 +95,7 @@ read-only checks:
|
|
|
95
95
|
Read-only, like `prisma db pull`.
|
|
96
96
|
- `--show-sql` / `--dry-run` on `connect` and `migrate` — the exact statements,
|
|
97
97
|
printed and unexecuted, so you approve the SQL before it runs.
|
|
98
|
-
- Read the row and its claim state before you write — `
|
|
98
|
+
- Read the row and its claim state before you write — `get` / `list`, and
|
|
99
99
|
`ablo.<model>.claim.state({ id })` for who is already working on it.
|
|
100
100
|
|
|
101
101
|
The pattern underneath all of it is steady: reads and model writes flow freely
|
package/docs/react.md
CHANGED
|
@@ -143,7 +143,7 @@ const reports = useAblo((ablo) =>
|
|
|
143
143
|
const report = await ablo.weatherReports.get({ id });
|
|
144
144
|
```
|
|
145
145
|
|
|
146
|
-
Use `
|
|
146
|
+
Use `get` in Server Components when the row may not be in the local pool
|
|
147
147
|
yet — it hydrates from the local store and the server, and returns a Promise, so
|
|
148
148
|
`await` it. (Server reads come in two shapes: `get({ id })` for one row and
|
|
149
149
|
`list({ where })` for many; both are async. The synchronous local reads are
|
|
@@ -162,7 +162,6 @@ await ablo.weatherReports.update({
|
|
|
162
162
|
data: patch,
|
|
163
163
|
readAt: snap.stamp,
|
|
164
164
|
onStale: 'reject',
|
|
165
|
-
wait: 'confirmed',
|
|
166
165
|
});
|
|
167
166
|
```
|
|
168
167
|
|
|
@@ -180,7 +179,6 @@ async function markReady() {
|
|
|
180
179
|
data: { status: 'ready' },
|
|
181
180
|
readAt: snap.stamp,
|
|
182
181
|
onStale: 'reject',
|
|
183
|
-
wait: 'confirmed',
|
|
184
182
|
});
|
|
185
183
|
}
|
|
186
184
|
```
|
package/docs/schema-contract.md
CHANGED
|
@@ -6,7 +6,7 @@ Ablo's schema is the integration contract. Define it once, pass it to `Ablo(...)
|
|
|
6
6
|
and every actor gets the same typed model surface:
|
|
7
7
|
|
|
8
8
|
```txt
|
|
9
|
-
defineSchema(...) -> ablo.<model>.create/
|
|
9
|
+
defineSchema(...) -> ablo.<model>.create/get/update/claim(...)
|
|
10
10
|
```
|
|
11
11
|
|
|
12
12
|
That one object drives:
|
|
@@ -84,7 +84,7 @@ const pending = ablo.weatherReports.local.list({ where: { status: 'pending' } })
|
|
|
84
84
|
Use model writes for every actor:
|
|
85
85
|
|
|
86
86
|
```ts
|
|
87
|
-
await ablo.weatherReports.update({ id: reportId, data: { status: 'ready' }
|
|
87
|
+
await ablo.weatherReports.update({ id: reportId, data: { status: 'ready' } });
|
|
88
88
|
```
|
|
89
89
|
|
|
90
90
|
## Coordination
|
package/examples/README.md
CHANGED
|
@@ -21,7 +21,7 @@ const ablo = Ablo({ schema, apiKey: process.env.ABLO_API_KEY });
|
|
|
21
21
|
Then:
|
|
22
22
|
|
|
23
23
|
- create with `ablo.weatherReports.create`
|
|
24
|
-
- read with `ablo.weatherReports.
|
|
24
|
+
- read with `ablo.weatherReports.get` or `ablo.weatherReports.list`
|
|
25
25
|
- coordinate long-running work with `ablo.weatherReports.claim`
|
|
26
26
|
- write with `ablo.weatherReports.update`
|
|
27
27
|
- dispose the client when the worker finishes
|
package/llms.txt
CHANGED
|
@@ -61,11 +61,10 @@ await using claim = await ablo.weatherReports.claim({ id: 'report_stockholm' });
|
|
|
61
61
|
const updated = await ablo.weatherReports.update({
|
|
62
62
|
id: claim.data.id,
|
|
63
63
|
data: { status: 'ready', forecast: await getForecast(claim.data) },
|
|
64
|
-
wait: 'confirmed',
|
|
65
64
|
});
|
|
66
65
|
```
|
|
67
66
|
|
|
68
|
-
That is the normal app path: declare models in a schema, then use `ablo.<model>.
|
|
67
|
+
That is the normal app path: declare models in a schema, then use `ablo.<model>.get({ id })`, `ablo.<model>.create(...)`, `ablo.<model>.update(...)`, and `ablo.<model>.delete(...)`. Every verb takes a single options object.
|
|
69
68
|
|
|
70
69
|
Treat the schema as the integration contract. It drives typed model clients,
|
|
71
70
|
React selectors, server and agent writes, Data Source request/response shape,
|
|
@@ -137,7 +136,7 @@ frees. Use `ifClaimed: 'fail'` when you'd rather refuse to read a claimed row.
|
|
|
137
136
|
|
|
138
137
|
## Guarantees
|
|
139
138
|
|
|
140
|
-
|
|
139
|
+
Schema model writes update local state optimistically, while their returned promise always waits for authoritative confirmation. Server rejection rolls back local state. To prevent lost updates, read with `snapshot(...)` to capture a `readAt`, then write with `onStale: 'reject'` — the server rejects your update if someone else changed the row after that `readAt`.
|
|
141
140
|
|
|
142
141
|
Claims coordinate writers; they do not block readers. Most users should stay on
|
|
143
142
|
schema-backed reads/writes and `claim(...)`; manual protocol bookkeeping is not
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abloatai/ablo",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.48.0",
|
|
4
4
|
"description": "The public Ablo SDK for coordinated reads, commits, claims, observation, and reactive applications.",
|
|
5
5
|
"license": "Apache-2.0",
|
|
6
6
|
"type": "module",
|
|
@@ -124,8 +124,8 @@
|
|
|
124
124
|
"directory": "packages/ablo"
|
|
125
125
|
},
|
|
126
126
|
"dependencies": {
|
|
127
|
-
"@abloatai/humans": "^0.
|
|
128
|
-
"@abloatai/transaction": "^0.
|
|
127
|
+
"@abloatai/humans": "^0.48.0",
|
|
128
|
+
"@abloatai/transaction": "^0.48.0"
|
|
129
129
|
},
|
|
130
130
|
"peerDependencies": {
|
|
131
131
|
"ai": "^6.0.0 || ^7.0.0",
|
|
@@ -1,58 +0,0 @@
|
|
|
1
|
-
# Agent Orchestration
|
|
2
|
-
|
|
3
|
-
Do not model parent and child agents as directly talking to each other over WebSocket.
|
|
4
|
-
|
|
5
|
-
Model them as actors coordinating through models:
|
|
6
|
-
|
|
7
|
-
```txt
|
|
8
|
-
parent creates job -> child claims job -> child commits result -> parent reads result
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
The WebSocket is delivery infrastructure. The product model is shared state.
|
|
12
|
-
|
|
13
|
-
## Model Shape
|
|
14
|
-
|
|
15
|
-
A parent creates a job through its typed model client:
|
|
16
|
-
|
|
17
|
-
```ts
|
|
18
|
-
const jobId = `forecast:${runId}`;
|
|
19
|
-
await ablo.agentJobs.create({
|
|
20
|
-
id: jobId,
|
|
21
|
-
idempotencyKey: `job:${runId}`,
|
|
22
|
-
data: {
|
|
23
|
-
status: 'open',
|
|
24
|
-
kind: 'forecast_report',
|
|
25
|
-
target: { model: 'weatherReports', id: 'report_stockholm', field: 'forecast' },
|
|
26
|
-
},
|
|
27
|
-
wait: 'confirmed',
|
|
28
|
-
});
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
The child claims the job. If another worker holds it, the claim waits fairly,
|
|
32
|
-
then returns the fresh row:
|
|
33
|
-
|
|
34
|
-
```ts
|
|
35
|
-
await using claim = await ablo.agentJobs.claim({
|
|
36
|
-
id: jobId,
|
|
37
|
-
description: 'complete',
|
|
38
|
-
ttl: '5m',
|
|
39
|
-
});
|
|
40
|
-
const job = claim.data;
|
|
41
|
-
|
|
42
|
-
await ablo.agentJobs.update({
|
|
43
|
-
id: job.id,
|
|
44
|
-
data: {
|
|
45
|
-
status: 'completed',
|
|
46
|
-
result: { text },
|
|
47
|
-
},
|
|
48
|
-
});
|
|
49
|
-
```
|
|
50
|
-
|
|
51
|
-
The child commits completion through the normal `update`, which is stale-guarded
|
|
52
|
-
under the held claim. The claim releases when its scope exits.
|
|
53
|
-
|
|
54
|
-
The parent retrieves the job result by model ID. Later, `ablo.events` can make that reactive, but the state model does not change.
|
|
55
|
-
|
|
56
|
-
## Rule
|
|
57
|
-
|
|
58
|
-
Nested agents should create or complete models. They should not require a separate agent-to-agent protocol for normal work.
|