@dudousxd/nestjs-agent-store-drizzle 0.24.0 → 0.25.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/README.md +97 -0
- package/dist/index.cjs +887 -171
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2045 -488
- package/dist/index.d.ts +2045 -488
- package/dist/index.js +830 -116
- package/dist/index.js.map +1 -1
- package/package.json +4 -4
package/README.md
CHANGED
|
@@ -237,3 +237,100 @@ for the full model.
|
|
|
237
237
|
## License
|
|
238
238
|
|
|
239
239
|
MIT © Davide Carvalho
|
|
240
|
+
|
|
241
|
+
|
|
242
|
+
Action preflight confirmations persist in the nullable `agent_tool_call.confirmation` JSON column.
|
|
243
|
+
The schema helper adds this column to existing databases. Hosts managing their own migrations must
|
|
244
|
+
add it before upgrading (`JSONB` on PostgreSQL, `JSON` on MySQL, JSON text on SQLite). The stored
|
|
245
|
+
confirmation is returned in `StoredMessage.approvals` so a reload uses the same wording.
|
|
246
|
+
|
|
247
|
+
### Durable action proposals
|
|
248
|
+
|
|
249
|
+
`DrizzleAgentStore` also implements the optional core `ActionProposalStore` capability.
|
|
250
|
+
Its `createActionProposal`, scoped get/list, immutable decision, lease claim/renewal,
|
|
251
|
+
and settlement methods persist to the independent `agent_action_proposal` table;
|
|
252
|
+
no persisted thread, message, or run is required. The standalone
|
|
253
|
+
`DrizzleActionProposalStore` exposes the same methods when only this capability is needed.
|
|
254
|
+
Both accept an optional second constructor argument `{ clock: () => number }` for a
|
|
255
|
+
trusted server clock (default `Date.now`); never pass a request timestamp as that clock.
|
|
256
|
+
|
|
257
|
+
Creation is replay-safe against the original canonical JSON snapshot. A proposal ID
|
|
258
|
+
is globally unique, and every read or mutation checks tenant, actor, and thread scope.
|
|
259
|
+
Approval and queued execution commit together in one version-fenced SQL update.
|
|
260
|
+
Claims/recovery increment a generation and issue a new token; renewal and settlement
|
|
261
|
+
require both and an unexpired lease. Expiry is inclusive (`now >= expiresAt`).
|
|
262
|
+
A contended caller transaction can return `conflict` after bounded CAS retries;
|
|
263
|
+
retry from a fresh transaction when its repeatable-read snapshot is stale.
|
|
264
|
+
The stable `idempotencyKey` survives recovery: delivery is at least once, so the tool
|
|
265
|
+
must enforce idempotency for its external effect. This storage capability does not
|
|
266
|
+
start a worker or change the agent loop.
|
|
267
|
+
|
|
268
|
+
For existing databases, run `ensureAgentSchema(db)` to add the new table and its
|
|
269
|
+
scope/creation-order index without altering existing data. Lists filter and limit in
|
|
270
|
+
SQL (default 100, maximum 1000), with UTF16 lexical ID ordering for equal creation
|
|
271
|
+
times. Logical proposal IDs are limited to 255 UTF16 code units by the core contract.
|
|
272
|
+
If you own migrations,
|
|
273
|
+
include `agent_action_proposal` from `agentSchema`, `pgAgentSchema`, or
|
|
274
|
+
`mysqlAgentSchema` (or the corresponding `agentSchemaDdl(dialect)` statements).
|
|
275
|
+
The physical primary key and scope key are SHA-256 digests; original identifiers
|
|
276
|
+
remain in the canonical JSON text snapshot and are matched exactly, including
|
|
277
|
+
trailing spaces,
|
|
278
|
+
independently of MySQL collation padding. Text storage preserves valid JSON strings
|
|
279
|
+
containing NUL or lone surrogates on every dialect. Decision audit and execution
|
|
280
|
+
work share
|
|
281
|
+
the snapshot column, fenced by the numeric `version` column. Existing table schemas
|
|
282
|
+
and fixture callers remain compatible.
|
|
283
|
+
|
|
284
|
+
Worker discovery is available on `DrizzleAgentStore` and `DrizzleActionProposalStore`
|
|
285
|
+
through the privileged `claimNextActionProposal({ workerId, leaseMs })` and
|
|
286
|
+
`expireActionProposals({ limit })` methods. Do not expose these unscoped methods on
|
|
287
|
+
public routes. Discovery selects at most 32 queued or expired-lease candidates;
|
|
288
|
+
expiry selects at most `limit` (1–1000) pending proposals due at the trusted store
|
|
289
|
+
clock. Existing scoped, version-fenced mutations decide which worker wins.
|
|
290
|
+
|
|
291
|
+
Upgrading an existing proposal table requires the additive nullable
|
|
292
|
+
`execution_status`, `lease_expires_at`, and `proposal_expires_at` columns, the
|
|
293
|
+
`discovery_index_version` column with default 0, and the execution/expiry indexes
|
|
294
|
+
from the exported schema. `ensureAgentSchema` adds these definitions; hosts using
|
|
295
|
+
Drizzle migrations must include them in their forward migration. Stop old writers,
|
|
296
|
+
apply the DDL, then repeat the bounded backfill before starting new workers:
|
|
297
|
+
|
|
298
|
+
```ts
|
|
299
|
+
while (await store.backfillActionProposalDiscoveryIndex({ limit: 1000 })) {
|
|
300
|
+
// Each batch derives metadata from the canonical payload under its row version.
|
|
301
|
+
}
|
|
302
|
+
```
|
|
303
|
+
|
|
304
|
+
New writes maintain index version 1 and all discovery metadata atomically with the
|
|
305
|
+
proposal snapshot. Backfill increments the row version without changing the
|
|
306
|
+
proposal payload, timestamps, or audit. It does not invoke transitions or execute
|
|
307
|
+
tools. This upgrade does not support mixed old and new writers: old writers cannot
|
|
308
|
+
maintain the new indexes. Discovery deliberately excludes rows awaiting backfill;
|
|
309
|
+
it never performs an implicit, unbounded migration.
|
|
310
|
+
|
|
311
|
+
### Independent approval runtime
|
|
312
|
+
|
|
313
|
+
`actionApprovalMode: 'independent'` requires proposal discovery, atomic replacement,
|
|
314
|
+
terminal outcome admission and the thread queue on the same database. This adapter
|
|
315
|
+
advertises admission support for better-sqlite3, node-postgres, mysql2 and libSQL;
|
|
316
|
+
other Drizzle drivers retain blocking behavior and fail independent configuration.
|
|
317
|
+
Synchronous SQLite transaction callbacks complete synchronously, including both
|
|
318
|
+
assistant insertion and the delivery compare-and-set. PostgreSQL/MySQL admission
|
|
319
|
+
locks the proposal and conversation before checking the delivery lease again.
|
|
320
|
+
|
|
321
|
+
The updated schemas add nullable `delivery_status`, `delivery_lease_expires_at`,
|
|
322
|
+
`replacement_group_key`, `outcome_id_key` and their indexes to proposals,
|
|
323
|
+
`action_proposal_outcome` to messages, `proposal_id` to tool calls and
|
|
324
|
+
`ui_capabilities` to queued messages. `ensureAgentSchema` adds missing columns and
|
|
325
|
+
indexes; applications owning drizzle-kit migrations must include the same additions.
|
|
326
|
+
Outcomes use escaped TEXT/LONGTEXT metadata to preserve JSON strings exactly.
|
|
327
|
+
|
|
328
|
+
Delivery writes one assistant fact and its UI together with its admitted marker,
|
|
329
|
+
waits while a user turn owns the conversation and deduplicates retries. Replacement
|
|
330
|
+
only closes pending proposals in the same exact scope, tool and replacement group.
|
|
331
|
+
An existing transaction passed as the database handle remains the transaction
|
|
332
|
+
owner: a caller rollback also rolls back replacement or admission. External side
|
|
333
|
+
effects remain at least once; use the stable tool-context idempotency key.
|
|
334
|
+
|
|
335
|
+
See [the shared setup and rollout guide](../../docs/independent-approvals.md) for
|
|
336
|
+
policies, text/channel decisions, remembered approvals and component capabilities.
|