@abloatai/ablo 0.37.0 → 0.38.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 +3 -3
- package/CHANGELOG.md +162 -92
- package/README.md +86 -21
- package/dist/ai-sdk.d.ts +2 -0
- package/dist/ai-sdk.d.ts.map +1 -0
- package/dist/ai-sdk.js +2 -0
- package/dist/ai-sdk.js.map +1 -0
- package/docs/agents.md +59 -9
- package/docs/api-keys.md +51 -27
- package/docs/branch-development.md +392 -0
- package/docs/cli.md +50 -42
- package/docs/data-sources.md +11 -0
- package/docs/deployment.md +20 -19
- package/docs/examples/ai-sdk-tool.md +25 -52
- package/docs/how-it-works.md +3 -2
- package/docs/index.md +7 -3
- package/docs/integration-guide.md +6 -13
- package/docs/integrations/inngest.md +258 -0
- package/docs/integrations/temporal.md +187 -0
- package/docs/integrations.md +54 -0
- package/docs/migration.md +4 -4
- package/docs/projects.md +1 -1
- package/docs/quickstart.md +30 -22
- package/docs/webhooks.md +4 -4
- package/llms.txt +20 -18
- package/package.json +15 -3
package/AGENTS.md
CHANGED
|
@@ -13,10 +13,10 @@ Don't hand-write the integration. Run the CLI; it generates the current-API sche
|
|
|
13
13
|
- **Auth:** set `ABLO_API_KEY` in the environment. Do **NOT** run `ablo login` — it opens a browser device flow and blocks an agent.
|
|
14
14
|
- **Connect your database — logical replication (the primary path):** `npx ablo connect` prints the setup SQL (`wal_level=logical`, a publication, a `REPLICATION` role); `npx ablo connect register` registers the source with Ablo in one step. Ablo **consumes your Postgres' logical-replication stream** — it never runs DDL on, writes to, owns, or migrates your database, and your application keeps the write path. Registration **is** the enable; there is no tier or flag to pick. (Ablo hosts only the transaction log + coordination, never your rows.)
|
|
15
15
|
- **Fallback — signed Data Source endpoint** (DB can't grant a `REPLICATION` role): the generated `ablo/data-source.ts` exposes one route; Ablo sends signed requests and your app touches its own DB. **Only in this mode** does `npx ablo migrate` provision the adapter's bookkeeping tables (`ablo_outbox`, `ablo_idempotency`) plus your Ablo models — it does **not** touch your other tables. Keep your own migrations (drizzle-kit / prisma migrate) for auth and anything outside the Ablo schema.
|
|
16
|
-
- **No database yet?**
|
|
16
|
+
- **No database yet?** Run `npx ablo dev --no-watch --branch <name>` to create an isolated non-root branch and obtain its expiring `sk_test_` credential. The branch uses a throwaway hosted data plane; Production remains the protected root. There is no shared Sandbox mode.
|
|
17
17
|
- **Adopt an existing DB schema:** `npx ablo pull prisma [path]` / `pull drizzle <module>` (lossless) or `pull` (live DB, lossy). Writes `ablo/schema.ts`.
|
|
18
|
-
- **
|
|
19
|
-
- **Other long-running:** `npx ablo logs --no-follow` (default tails forever). `
|
|
18
|
+
- **Prepare a branch and push your schema — REQUIRED before any write works.** The server keeps its OWN copy of the schema. After you create or edit `ablo/schema.ts`, run `npx ablo dev --no-watch --branch <git-or-ci-ref>`: it ensures an isolated branch, mints a temporary branch credential, writes it to gitignored `.env.local`, pushes once, and exits. **Skip this and every write to a new or changed model fails with `server_execute_unknown_model`.** Plain `ablo dev` watches forever — never run it bare in an agent. `ablo push` is the lower-level one-shot command for an already selected key, including reviewed production deploys.
|
|
19
|
+
- **Other long-running:** `npx ablo logs --no-follow` (default tails forever). `status`, `branch check`, `push`, `pull`, `check`, `generate`, `docs`, and `dev --no-watch` are one-shot.
|
|
20
20
|
|
|
21
21
|
When you use the signed-endpoint fallback, the generated `ablo/data-source.ts` is the whole endpoint and needs no hand-editing: `dataSourceNext({ schema, apiKey, adapter: prismaDataSource(prisma, schema) })` (or `drizzleDataSource(db, schema)`). The adapter owns commit / idempotency / outbox.
|
|
22
22
|
|
package/CHANGELOG.md
CHANGED
|
@@ -1,96 +1,166 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.38.0
|
|
4
|
+
|
|
5
|
+
### Branch-isolated development
|
|
6
|
+
|
|
7
|
+
Ablo branches replace the former shared Sandbox mode. Every project has a
|
|
8
|
+
protected Production root and can have multiple isolated development, preview,
|
|
9
|
+
test, or long-lived branches. Credentials are bound to immutable branch
|
|
10
|
+
identities, so changing a slug or request parameter cannot redirect a write.
|
|
11
|
+
|
|
12
|
+
`npx ablo dev` now discovers the current Git or CI branch, ensures the matching
|
|
13
|
+
Ablo branch, mints an expiring branch credential, writes it to the gitignored
|
|
14
|
+
local environment, pushes the schema, and watches for changes. Use
|
|
15
|
+
`npx ablo dev --no-watch --branch <name>` for a one-shot agent or CI setup.
|
|
16
|
+
|
|
17
|
+
The CLI also provides `ablo branch list`, `create`, `ensure`, `status`, `check`,
|
|
18
|
+
`credential`, and `delete`. The public HTTP and OpenAPI contracts expose the
|
|
19
|
+
same lifecycle for other languages and deployment systems.
|
|
20
|
+
|
|
21
|
+
This release removes the CLI mode switch and the dashboard Sandbox surface.
|
|
22
|
+
Production remains the protected root; a development credential cannot select
|
|
23
|
+
another branch or gain production authority.
|
|
24
|
+
|
|
25
|
+
Source adapters and PostgreSQL footprint helpers now select immutable branches.
|
|
26
|
+
If you construct `FootprintPlane` or `SourceRequestContext`, replace
|
|
27
|
+
`environment`, `mode`, and `sandboxId` with `branchId`.
|
|
28
|
+
|
|
29
|
+
### Temporal and Inngest integration guides
|
|
30
|
+
|
|
31
|
+
New runnable examples and documentation show how Temporal and Inngest
|
|
32
|
+
workflows use Ablo without introducing another authority path. Temporal
|
|
33
|
+
activities and Inngest steps create the Ablo client, perform authoritative
|
|
34
|
+
reads, acquire claims for long-running work, and submit idempotent writes
|
|
35
|
+
through the same transaction API as every other caller.
|
|
36
|
+
|
|
37
|
+
The integrations keep each product in its proper role: Temporal and Inngest
|
|
38
|
+
own durable execution, scheduling, retries, and workflow history; Ablo owns
|
|
39
|
+
shared-data authority, claims, conflicts, idempotency, settlement, and ordered
|
|
40
|
+
observation. Workflow code does not open WebSockets or hold live client state.
|
|
41
|
+
|
|
42
|
+
### Database adapter foundation, starting with PostgreSQL
|
|
43
|
+
|
|
44
|
+
Customer-database adapters now declare their database, ORM binding, and
|
|
45
|
+
observation strategy as separate axes. The existing Prisma, Drizzle, and Kysely
|
|
46
|
+
integrations are accurately identified as PostgreSQL bindings using either a
|
|
47
|
+
transactional outbox or PostgreSQL WAL.
|
|
48
|
+
|
|
49
|
+
All built-in adapters are constructed through one validating factory and the
|
|
50
|
+
shared conformance suite checks that the three axes are present. Impossible
|
|
51
|
+
capability combinations fail during adapter construction instead of silently
|
|
52
|
+
advertising guarantees the database path cannot provide.
|
|
53
|
+
|
|
54
|
+
PostgreSQL is the first database profile on this axis. The contract leaves room
|
|
55
|
+
for additional databases without pretending their transaction, observation,
|
|
56
|
+
and change-capture guarantees are interchangeable with PostgreSQL.
|
|
57
|
+
|
|
58
|
+
### Generated language SDK foundation
|
|
59
|
+
|
|
60
|
+
The HTTP API is now explicitly treated as Ablo's language-neutral product
|
|
61
|
+
boundary. Its OpenAPI artifact follows the current Ablo version and every
|
|
62
|
+
operation has a stable, unique name suitable for deterministic Python and Go
|
|
63
|
+
generation.
|
|
64
|
+
|
|
65
|
+
The OpenAPI generator and drift check are restored as repository and CI gates.
|
|
66
|
+
Future language clients will generate their transport, wire models, and error
|
|
67
|
+
decoding from this contract, retaining handwritten code only for thin
|
|
68
|
+
language-idiomatic resource and claim façades.
|
|
69
|
+
|
|
70
|
+
The artifact now names shared claim, receipt, cursor, page, and error schemas;
|
|
71
|
+
references the canonical error envelope from every operation; publishes typed
|
|
72
|
+
pagination parameters and explicit union discriminators; and normalizes Zod's
|
|
73
|
+
JSON Schema output to the portable subset accepted by the Python and Go
|
|
74
|
+
generator candidates. CI also validates the rendered OpenAPI 3.1 document with
|
|
75
|
+
an independent, pinned Redocly CLI.
|
|
76
|
+
|
|
77
|
+
### AI SDK tools over the transaction API
|
|
78
|
+
|
|
79
|
+
`@abloatai/ablo/ai-sdk` now exposes small tool adapters for authoritative
|
|
80
|
+
reads, idempotent creates, concurrency-safe updates, and claimed deletes. These
|
|
81
|
+
helpers use the caller's existing typed Ablo model resource; they do not add an
|
|
82
|
+
agent runtime or a second transport.
|
|
83
|
+
|
|
84
|
+
The public surface follows the model verbs directly: `readTool`, `createTool`,
|
|
85
|
+
`updateTool`, and `deleteTool`. AI SDK metadata and approval policy pass through
|
|
86
|
+
to each tool, destructive tools require approval by default, and cancellation
|
|
87
|
+
stops queued claim acquisition.
|
|
88
|
+
|
|
89
|
+
This deliberately replaces the previously published `coordinatedTool` naming:
|
|
90
|
+
use `updateTool`, `UpdateToolModel`, `UpdateToolOptions`, `UpdateToolResult`,
|
|
91
|
+
`UpdateStrategy`, and the `status` result field. The former
|
|
92
|
+
`coordinatedTool`, `CoordinatedModel`, `CoordinatedToolOptions`,
|
|
93
|
+
`CoordinatedWriteResult`, and `CoordinationStrategy` exports are removed rather
|
|
94
|
+
than retained as legacy aliases.
|
|
95
|
+
|
|
96
|
+
Queued tool writes now use Ablo's server-owned FIFO claim queue rather than
|
|
97
|
+
recreating coordination with client-side polling.
|
|
98
|
+
|
|
99
|
+
Internal job dispatch, concrete worker tools, prompts, sandboxes, and model
|
|
100
|
+
selection remain application concerns and are not part of the public Ablo
|
|
101
|
+
agent surface.
|
|
102
|
+
|
|
103
|
+
## 0.37.1
|
|
104
|
+
|
|
105
|
+
### A clearer introduction to Ablo
|
|
106
|
+
|
|
107
|
+
The package README now explains Ablo from the problem outward: humans already
|
|
108
|
+
coordinate shared work by seeing who is active, agreeing on ownership, waiting,
|
|
109
|
+
and looking again before continuing; Ablo gives agents those same practical
|
|
110
|
+
capabilities in software.
|
|
111
|
+
|
|
112
|
+
It also makes the headless product explicit. The TypeScript SDK is backed by a
|
|
113
|
+
pure HTTP transaction API, so agents, services, jobs, command-line tools, and
|
|
114
|
+
interactive applications can use the same coordination model without requiring
|
|
115
|
+
a browser or reactive client.
|
|
116
|
+
|
|
117
|
+
### Lower overhead on busy write paths
|
|
118
|
+
|
|
119
|
+
Large create batches now return only the inserted identifiers needed for
|
|
120
|
+
idempotency handling instead of sending every inserted column back to the
|
|
121
|
+
server. Live clients also bypass reconciliation work when a publication frame
|
|
122
|
+
contains one change per entity.
|
|
123
|
+
|
|
124
|
+
These changes reduce server response volume and client materialization work.
|
|
125
|
+
There are no public API changes in 0.37.1.
|
|
126
|
+
|
|
3
127
|
## 0.37.0
|
|
4
128
|
|
|
5
|
-
###
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
serve WebSocket-backed reactive applications.
|
|
44
|
-
|
|
45
|
-
The public surface now provides:
|
|
46
|
-
|
|
47
|
-
- `@abloatai/ablo` for agents, services, workers, jobs, and backend code;
|
|
48
|
-
- `@abloatai/ablo/client` for live local state;
|
|
49
|
-
- `@abloatai/ablo/react` for React bindings;
|
|
50
|
-
- branded schema, source-adapter, server, authorization, coordination, and wire
|
|
51
|
-
subpaths; and
|
|
52
|
-
- `/source/next`, `/source/drizzle`, `/source/kysely`, and
|
|
53
|
-
`/source/conformance` for Data Source integrations.
|
|
54
|
-
|
|
55
|
-
Authoritative reads use `model.get({ id })`; reactive snapshots use
|
|
56
|
-
`model.local.get(id)`.
|
|
57
|
-
|
|
58
|
-
Ablo is now presented as the transaction and coordination API for state
|
|
59
|
-
operated by humans, services, tools, and AI agents. Realtime synchronization
|
|
60
|
-
remains available as a client capability rather than defining the product.
|
|
61
|
-
Live applications no longer accept HTTP transport configuration, and the old
|
|
62
|
-
sync-engine package and compatibility paths are removed.
|
|
63
|
-
|
|
64
|
-
The public repository preserves the workspace structure used for development
|
|
65
|
-
instead of flattening sources into a generated package. The branded banner,
|
|
66
|
-
documentation, examples, license, notices, and release automation remain part
|
|
67
|
-
of the repository.
|
|
68
|
-
|
|
69
|
-
The new package pages direct application developers to the branded Ablo
|
|
70
|
-
entrypoints while still documenting where integration authors can find the
|
|
71
|
-
lower-level transaction and interactive-client contracts.
|
|
72
|
-
|
|
73
|
-
- f60ed16: Improve confirmed commit throughput and live-client materialization without
|
|
74
|
-
weakening atomic writes, ordered observation, audit delivery, or replay.
|
|
75
|
-
|
|
76
|
-
The certified AWS benchmark sustained more than 10,000 committed operations per
|
|
77
|
-
second for homogeneous creates, mixed creates, updates, and deletes with zero
|
|
78
|
-
write errors and sub-second publication drain. The result covers the documented
|
|
79
|
-
single-plane, 12-client, 500-operation benchmark topology rather than claiming
|
|
80
|
-
universal production capacity.
|
|
81
|
-
|
|
82
|
-
Live clients now defer reactive model activation until state reaches a
|
|
83
|
-
consumer-visible boundary and keep cache eviction work bounded under sustained
|
|
84
|
-
ingestion. Optimistic state and actively observed models remain immediately
|
|
85
|
-
reactive.
|
|
86
|
-
|
|
87
|
-
### Patch Changes
|
|
88
|
-
|
|
89
|
-
- Updated dependencies [f60ed16]
|
|
90
|
-
- Updated dependencies [16cc7d1]
|
|
91
|
-
- Updated dependencies [08a3cad]
|
|
92
|
-
- Updated dependencies [f60ed16]
|
|
93
|
-
- @abloatai/transaction@0.37.0
|
|
94
|
-
- @abloatai/humans@0.37.0
|
|
95
|
-
|
|
96
|
-
Release notes are generated from the repository changesets.
|
|
129
|
+
### One Ablo SDK for humans, agents, and backend systems
|
|
130
|
+
|
|
131
|
+
Ablo is now presented and shipped as the transaction and coordination layer for
|
|
132
|
+
shared application state—not only as a realtime synchronization library.
|
|
133
|
+
|
|
134
|
+
Install `@abloatai/ablo` as the single public SDK:
|
|
135
|
+
|
|
136
|
+
- `@abloatai/ablo` provides the pure HTTP path for agents, services, workers,
|
|
137
|
+
jobs, server actions, and other headless runtimes.
|
|
138
|
+
- `@abloatai/ablo/client` adds live local state, optimistic interaction,
|
|
139
|
+
persistence, and presence for human-facing applications.
|
|
140
|
+
- `@abloatai/ablo/react` provides the React bindings.
|
|
141
|
+
|
|
142
|
+
Every entrypoint uses the same schema, capabilities, commits, claims,
|
|
143
|
+
idempotency, settlement, and ordered changes. Authoritative reads use
|
|
144
|
+
`model.get({ id })`; local reactive snapshots use `model.local.get(id)`.
|
|
145
|
+
|
|
146
|
+
### Coordination now matches the unit applications can safely write
|
|
147
|
+
|
|
148
|
+
Claims can coordinate an entire row or a typed set of fields. Two actors
|
|
149
|
+
working on different fields of the same row can proceed concurrently, while
|
|
150
|
+
overlapping work takes turns.
|
|
151
|
+
|
|
152
|
+
Sub-field `path` and `range` claims have been removed because the write path
|
|
153
|
+
cannot yet guarantee independent updates within one field. Applications using
|
|
154
|
+
those options should claim the containing field instead and keep any
|
|
155
|
+
cursor/range information in claim metadata for display.
|
|
156
|
+
|
|
157
|
+
### Safer authority for browser applications
|
|
158
|
+
|
|
159
|
+
Browser sessions now use one typed, short-lived credential flow and require a
|
|
160
|
+
non-empty schema-typed `can` grant. Applications specify the exact model
|
|
161
|
+
operations a session may perform instead of issuing ambient all-data access.
|
|
162
|
+
|
|
163
|
+
Use `authEndpoint` for the browser credential endpoint. The supported routes
|
|
164
|
+
are `/v1/ephemeral_keys` and `/v1/capabilities`; the former `apiKey` endpoint
|
|
165
|
+
option and legacy route aliases are removed. Credential callbacks now use the
|
|
166
|
+
`CredentialProvider` type.
|
package/README.md
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
</p>
|
|
4
4
|
|
|
5
5
|
<p align="center">
|
|
6
|
-
<strong>
|
|
6
|
+
<strong>The transaction layer for AI agents.</strong>
|
|
7
7
|
</p>
|
|
8
8
|
|
|
9
9
|
<p align="center">
|
|
@@ -22,45 +22,110 @@
|
|
|
22
22
|
|
|
23
23
|
---
|
|
24
24
|
|
|
25
|
-
|
|
25
|
+
Safely coordinate AI agents, humans, workflows, and services writing to the
|
|
26
|
+
same database.
|
|
27
|
+
|
|
28
|
+
Ablo is an authoritative transaction layer for shared application state. Every
|
|
29
|
+
write goes through one typed API where authority, idempotency, conflicts,
|
|
30
|
+
ordering, and confirmation can be enforced. Your Postgres remains the source
|
|
31
|
+
of truth.
|
|
32
|
+
|
|
33
|
+
## Why Ablo
|
|
34
|
+
|
|
35
|
+
Software used to have one writer: a human clicking through an application. AI
|
|
36
|
+
applications now have humans, agents, workflows, and services acting
|
|
37
|
+
concurrently. Databases keep transactions consistent. They do not coordinate
|
|
38
|
+
autonomous work that reads now, reasons for thirty seconds, and writes later.
|
|
39
|
+
|
|
40
|
+
Humans handle this naturally. We see that somebody is editing, agree on who
|
|
41
|
+
takes which part, wait our turn, and look again before continuing. Ablo gives
|
|
42
|
+
software actors those same capabilities: bounded authority, shared ownership,
|
|
43
|
+
fresh context, safe handoffs, and an attributed record of what happened.
|
|
44
|
+
|
|
45
|
+
## Start
|
|
26
46
|
|
|
27
47
|
```sh
|
|
28
48
|
npm install @abloatai/ablo
|
|
49
|
+
npx ablo init
|
|
50
|
+
npx ablo dev
|
|
29
51
|
```
|
|
30
52
|
|
|
31
|
-
|
|
53
|
+
`ablo dev` prepares an isolated Ablo branch for your Git branch, writes its
|
|
54
|
+
temporary credential to gitignored `.env.local`, pushes the schema, and watches
|
|
55
|
+
for changes.
|
|
56
|
+
|
|
57
|
+
Read and write through the transaction layer:
|
|
32
58
|
|
|
33
59
|
```ts
|
|
34
|
-
|
|
60
|
+
const order = await ablo.orders.get({ id: orderId });
|
|
35
61
|
|
|
36
|
-
|
|
62
|
+
if (!order) throw new Error('Order not found');
|
|
37
63
|
await ablo.orders.update({
|
|
38
|
-
id:
|
|
64
|
+
id: order.id,
|
|
39
65
|
data: { status: 'approved' },
|
|
66
|
+
wait: 'confirmed',
|
|
40
67
|
});
|
|
41
68
|
```
|
|
42
69
|
|
|
43
|
-
|
|
70
|
+
`confirmed` means the authoritative database reported the change back. The
|
|
71
|
+
same commit can be retried safely if the caller loses its connection.
|
|
72
|
+
|
|
73
|
+
When work takes thirty seconds instead of one request, coordinate before the
|
|
74
|
+
agent starts reasoning:
|
|
44
75
|
|
|
45
76
|
```ts
|
|
46
|
-
|
|
77
|
+
await using claim = await ablo.orders.claim({ id: orderId });
|
|
78
|
+
|
|
79
|
+
const priced = await pricingAgent(claim.data);
|
|
47
80
|
|
|
48
|
-
|
|
49
|
-
|
|
81
|
+
await ablo.orders.update({
|
|
82
|
+
id: claim.data.id,
|
|
83
|
+
data: { total: priced.total, status: 'repriced' },
|
|
84
|
+
claim,
|
|
85
|
+
wait: 'confirmed',
|
|
86
|
+
});
|
|
50
87
|
```
|
|
51
88
|
|
|
52
|
-
|
|
89
|
+
Another actor touching the same work waits fairly and receives fresh state when
|
|
90
|
+
its turn begins. If the agent fails, the claim releases automatically. If its
|
|
91
|
+
context became stale, the write is rejected instead of silently overwriting
|
|
92
|
+
work it never saw.
|
|
53
93
|
|
|
54
|
-
|
|
94
|
+
If you use AI SDK, expose the same operation as a typed model tool:
|
|
55
95
|
|
|
56
|
-
```
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
96
|
+
```ts
|
|
97
|
+
import { updateTool } from '@abloatai/ablo/ai-sdk';
|
|
98
|
+
|
|
99
|
+
const approveOrder = updateTool(ablo.orders, {
|
|
100
|
+
description: 'Approve an order after reviewing it.',
|
|
101
|
+
inputSchema: z.object({ orderId: z.string() }),
|
|
102
|
+
id: ({ orderId }) => orderId,
|
|
103
|
+
apply: () => ({ status: 'approved' }),
|
|
104
|
+
});
|
|
62
105
|
```
|
|
63
106
|
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
107
|
+
Ablo supplies `readTool`, `createTool`, `updateTool`, and `deleteTool` over the
|
|
108
|
+
same authoritative resources. AI SDK keeps ownership of the model loop and tool
|
|
109
|
+
execution.
|
|
110
|
+
|
|
111
|
+
Use `@abloatai/ablo` for agents and backend code,
|
|
112
|
+
`@abloatai/ablo/client` for live applications, and
|
|
113
|
+
`@abloatai/ablo/react` for React. All entrypoints share the same schema,
|
|
114
|
+
authority, commits, claims, and ordered changes.
|
|
115
|
+
|
|
116
|
+
Read the [Quickstart](https://docs.abloatai.com/quickstart), browse
|
|
117
|
+
[docs.abloatai.com](https://docs.abloatai.com), or run `npx ablo docs`.
|
|
118
|
+
|
|
119
|
+
## Contributing
|
|
120
|
+
|
|
121
|
+
Ablo is free and open source. You can help by
|
|
122
|
+
[opening an issue](https://github.com/Abloatai/ablo/issues),
|
|
123
|
+
[suggesting a feature](https://github.com/Abloatai/ablo/issues/new), or
|
|
124
|
+
[contributing code](https://github.com/Abloatai/ablo/pulls).
|
|
125
|
+
|
|
126
|
+
Please report vulnerabilities privately through
|
|
127
|
+
[GitHub Security Advisories](https://github.com/Abloatai/ablo/security/advisories/new).
|
|
128
|
+
|
|
129
|
+
## License
|
|
130
|
+
|
|
131
|
+
Apache License 2.0. See [LICENSE](./LICENSE) and [NOTICE](./NOTICE).
|
package/dist/ai-sdk.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-sdk.d.ts","sourceRoot":"","sources":["../src/ai-sdk.ts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAC"}
|
package/dist/ai-sdk.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ai-sdk.js","sourceRoot":"","sources":["../src/ai-sdk.ts"],"names":[],"mappings":"AAAA,cAAc,8BAA8B,CAAC"}
|
package/docs/agents.md
CHANGED
|
@@ -6,7 +6,7 @@ An agent is a **reactive** participant: it wakes on something happening, reads
|
|
|
6
6
|
what it needs, writes a result, and goes idle. That's a request/response
|
|
7
7
|
workload — so agents talk to Ablo over **plain HTTP**, holding no WebSocket. The
|
|
8
8
|
credential *is* the identity; the server resolves the org, scope, and actor from
|
|
9
|
-
the key on every request
|
|
9
|
+
the key on every request.
|
|
10
10
|
|
|
11
11
|
Agents get the stateless plane (HTTP). People — when you add the `humans()`
|
|
12
12
|
plugin — get the live plane (WebSocket: presence, optimistic, sub-100ms).
|
|
@@ -31,7 +31,7 @@ import { schema } from "./schema";
|
|
|
31
31
|
const ablo = Ablo({ schema, apiKey: process.env.ABLO_API_KEY, transport: "http" });
|
|
32
32
|
|
|
33
33
|
// Reads + writes, fully typed off your schema.
|
|
34
|
-
// `
|
|
34
|
+
// `get` resolves to the row, or `undefined` when none matches.
|
|
35
35
|
const open = await ablo.tasks.list({ where: { status: "todo" } });
|
|
36
36
|
|
|
37
37
|
const task = await ablo.tasks.get({ id: open[0].id });
|
|
@@ -41,11 +41,57 @@ console.log(task.title);
|
|
|
41
41
|
await ablo.tasks.update({ id: task.id, data: { status: "done" } });
|
|
42
42
|
```
|
|
43
43
|
|
|
44
|
-
It exposes `
|
|
45
|
-
and `claim`. It does **not** expose
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
44
|
+
It exposes `get` / `list` / `create` / `update` / `delete`, plus `commits`
|
|
45
|
+
and `claim`. It does **not** expose stateful-only `local` reads or `onChange`
|
|
46
|
+
subscriptions. Those need a live connection, so with `transport: 'http'` they
|
|
47
|
+
are compile errors rather than runtime surprises.
|
|
48
|
+
|
|
49
|
+
## AI SDK tools
|
|
50
|
+
|
|
51
|
+
Keep AI SDK in charge of the model loop and expose only the Ablo operations the
|
|
52
|
+
model needs:
|
|
53
|
+
|
|
54
|
+
```ts
|
|
55
|
+
import { generateText } from 'ai';
|
|
56
|
+
import {
|
|
57
|
+
createTool,
|
|
58
|
+
deleteTool,
|
|
59
|
+
readTool,
|
|
60
|
+
updateTool,
|
|
61
|
+
} from '@abloatai/ablo/ai-sdk';
|
|
62
|
+
|
|
63
|
+
const tools = {
|
|
64
|
+
getTask: readTool(ablo.tasks, {
|
|
65
|
+
description: 'Read the current task.',
|
|
66
|
+
inputSchema: z.object({ taskId: z.string() }),
|
|
67
|
+
id: ({ taskId }) => taskId,
|
|
68
|
+
}),
|
|
69
|
+
createTask: createTool(ablo.tasks, {
|
|
70
|
+
description: 'Create a task.',
|
|
71
|
+
inputSchema: z.object({ requestId: z.string(), title: z.string() }),
|
|
72
|
+
id: ({ requestId }) => requestId,
|
|
73
|
+
data: ({ title }) => ({ title, status: 'todo' }),
|
|
74
|
+
}),
|
|
75
|
+
updateTask: updateTool(ablo.tasks, {
|
|
76
|
+
description: 'Update a task without overwriting concurrent work.',
|
|
77
|
+
inputSchema: z.object({ taskId: z.string(), status: z.string() }),
|
|
78
|
+
id: ({ taskId }) => taskId,
|
|
79
|
+
apply: (_current, { status }) => ({ status }),
|
|
80
|
+
}),
|
|
81
|
+
deleteTask: deleteTool(ablo.tasks, {
|
|
82
|
+
description: 'Delete a task after taking its claim.',
|
|
83
|
+
inputSchema: z.object({ taskId: z.string() }),
|
|
84
|
+
id: ({ taskId }) => taskId,
|
|
85
|
+
// Destructive tools require AI SDK approval by default.
|
|
86
|
+
}),
|
|
87
|
+
};
|
|
88
|
+
|
|
89
|
+
await generateText({ model, messages, tools });
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
These are adapters over the same typed resources used by ordinary backend
|
|
93
|
+
code. Ablo does not own the planner, prompt system, memory, provider, worker,
|
|
94
|
+
or workflow runtime.
|
|
49
95
|
|
|
50
96
|
## Coordination: claim, queue, reorder
|
|
51
97
|
|
|
@@ -59,7 +105,11 @@ clobber the same record.
|
|
|
59
105
|
await using claim = await ablo.tasks.claim({ id: taskId });
|
|
60
106
|
const task = claim.data;
|
|
61
107
|
// …no one else can hold this row while you work…
|
|
62
|
-
await ablo.tasks.update({
|
|
108
|
+
await ablo.tasks.update({
|
|
109
|
+
id: task.id,
|
|
110
|
+
data: { status: "in_review" },
|
|
111
|
+
claim,
|
|
112
|
+
});
|
|
63
113
|
|
|
64
114
|
await ablo.tasks.claim.state({ id: taskId }); // who holds it now (or null)
|
|
65
115
|
await ablo.tasks.claim.queue({ id: taskId }); // the FIFO wait-line behind the holder
|
|
@@ -111,5 +161,5 @@ agents costs nothing on the live plane — that capacity stays for humans.
|
|
|
111
161
|
`onChange` (live subscriptions) and the `local` reads (local synced-pool
|
|
112
162
|
reads) require a WebSocket and a local store — they're for interactive UIs, not
|
|
113
163
|
stateless agents. An agent reacts to an external trigger (a job/queue/webhook),
|
|
114
|
-
then reads with `list`/`
|
|
164
|
+
then reads with `list`/`get`. See [client behavior](/client-behavior) for
|
|
115
165
|
the full surface and [guarantees](/guarantees) for the coordination semantics.
|