@adonis-agora/agent 0.23.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.
Files changed (58) hide show
  1. package/CHANGELOG.md +63 -0
  2. package/dist/configure.d.ts +4 -5
  3. package/dist/configure.d.ts.map +1 -1
  4. package/dist/configure.js +4 -6
  5. package/dist/configure.js.map +1 -1
  6. package/dist/providers/agent_provider.d.ts.map +1 -1
  7. package/dist/providers/agent_provider.js +30 -12
  8. package/dist/providers/agent_provider.js.map +1 -1
  9. package/dist/providers/dashboard_provider.d.ts.map +1 -1
  10. package/dist/providers/dashboard_provider.js +3 -1
  11. package/dist/providers/dashboard_provider.js.map +1 -1
  12. package/dist/src/actor-labels.d.ts +26 -0
  13. package/dist/src/actor-labels.d.ts.map +1 -0
  14. package/dist/src/actor-labels.js +37 -0
  15. package/dist/src/actor-labels.js.map +1 -0
  16. package/dist/src/agent-deps-factory.d.ts +9 -1
  17. package/dist/src/agent-deps-factory.d.ts.map +1 -1
  18. package/dist/src/agent-deps-factory.js +15 -2
  19. package/dist/src/agent-deps-factory.js.map +1 -1
  20. package/dist/src/agent-loop.d.ts.map +1 -1
  21. package/dist/src/agent-loop.js +6 -5
  22. package/dist/src/agent-loop.js.map +1 -1
  23. package/dist/src/ai-tool-ref.js +2 -2
  24. package/dist/src/ai-tool-ref.js.map +1 -1
  25. package/dist/src/base-tool.d.ts +10 -10
  26. package/dist/src/base-tool.d.ts.map +1 -1
  27. package/dist/src/base-tool.js +9 -9
  28. package/dist/src/base-tool.js.map +1 -1
  29. package/dist/src/define_config.d.ts +19 -1
  30. package/dist/src/define_config.d.ts.map +1 -1
  31. package/dist/src/define_config.js.map +1 -1
  32. package/dist/src/index.d.ts +4 -3
  33. package/dist/src/index.d.ts.map +1 -1
  34. package/dist/src/index.js +4 -3
  35. package/dist/src/index.js.map +1 -1
  36. package/dist/src/rag/qdrant-store.d.ts +28 -26
  37. package/dist/src/rag/qdrant-store.d.ts.map +1 -1
  38. package/dist/src/rag/qdrant-store.js +24 -23
  39. package/dist/src/rag/qdrant-store.js.map +1 -1
  40. package/dist/src/spi/governance-queries.d.ts +25 -3
  41. package/dist/src/spi/governance-queries.d.ts.map +1 -1
  42. package/dist/src/spi/tool.d.ts +3 -3
  43. package/dist/src/sse.d.ts +3 -3
  44. package/dist/src/sse.js +3 -3
  45. package/dist/src/stores/factory.d.ts +16 -11
  46. package/dist/src/stores/factory.d.ts.map +1 -1
  47. package/dist/src/stores/factory.js +5 -5
  48. package/dist/src/stores/factory.js.map +1 -1
  49. package/dist/src/stores/lucid-schema.d.ts +22 -3
  50. package/dist/src/stores/lucid-schema.d.ts.map +1 -1
  51. package/dist/src/stores/lucid-schema.js +81 -4
  52. package/dist/src/stores/lucid-schema.js.map +1 -1
  53. package/dist/src/types.d.ts +48 -8
  54. package/dist/src/types.d.ts.map +1 -1
  55. package/dist/stubs/database/migrations/create_agent_rag_chunks.stub +23 -18
  56. package/dist/stubs/database/migrations/create_agent_tables.stub +35 -99
  57. package/package.json +2 -2
  58. package/dist/stubs/database/migrations/create_agent_run_tracking.stub +0 -80
@@ -126,13 +126,88 @@ export function createTableStatements() {
126
126
  `CREATE INDEX IF NOT EXISTS "${t.runs}_status_started_idx" ON "${t.runs}" ("status", "started_at")`,
127
127
  ];
128
128
  }
129
+ /**
130
+ * The `run_id` correlation columns run tracking added to three pre-existing tables. They are inline in
131
+ * {@link createTableStatements}, which is all a fresh database needs — but `CREATE TABLE IF NOT EXISTS`
132
+ * cannot add a column to a table that already exists, so a database provisioned before run tracking
133
+ * shipped needs them ALTERed in. Deliberately not DB foreign keys (SQLite cannot add a column WITH a
134
+ * FK constraint), so a row written before run tracking keeps a `null` run_id.
135
+ */
136
+ const RUN_ID_COLUMNS = [
137
+ AGENT_TABLES.messages,
138
+ AGENT_TABLES.toolCalls,
139
+ AGENT_TABLES.tokenUsage,
140
+ ];
141
+ /**
142
+ * Does `table` already have `column`? Probed with a zero-row `SELECT` rather than `information_schema`
143
+ * (absent on SQLite) or a `PRAGMA` (SQLite-only): every dialect rejects an unknown column at parse
144
+ * time, and `WHERE 1 = 0` means no rows are ever read.
145
+ *
146
+ * Deliberately NOT "attempt the ALTER and swallow the error": that pattern also swallows a permission
147
+ * failure, a lock timeout, and a typo, leaving a schema that is still wrong and a migration that
148
+ * reported success.
149
+ */
150
+ async function hasColumn(db, table, column) {
151
+ try {
152
+ await db.rawQuery(`SELECT "${column}" FROM "${table}" WHERE 1 = 0`);
153
+ return true;
154
+ }
155
+ catch {
156
+ return false;
157
+ }
158
+ }
129
159
  /**
130
160
  * Idempotently provision the six agent tables through Lucid's async raw runner (`CREATE TABLE IF
131
- * NOT EXISTS`). Works on every Lucid dialect. For an AdonisJS app prefer the published migration
132
- * (`node ace configure @adonis-agora/agent`); this helper is for standalone use, tests and quick-starts.
161
+ * NOT EXISTS`), then additively repair a database that predates run tracking by ALTERing in the
162
+ * `run_id` columns its three older tables are missing.
163
+ *
164
+ * Both halves matter, and for different populations. A fresh database gets everything from the
165
+ * `CREATE TABLE` statements and never reaches a repair branch — which is what makes a non-empty
166
+ * `repairs` result mean "this schema was out of date", not "boot happened". A database created before
167
+ * run tracking shipped has all three tables already, so every `CREATE TABLE IF NOT EXISTS` no-ops and
168
+ * only the repair adds the columns the store now writes on every turn.
169
+ *
170
+ * Returns the `<table>.<column>` repairs actually issued, so a caller can report them. Works on every
171
+ * Lucid dialect. For an AdonisJS app prefer the published migration
172
+ * (`node ace configure @adonis-agora/agent`); this helper is what that migration calls, and what the
173
+ * stores call themselves when `autoCreateTables` is on.
133
174
  */
134
175
  export async function createAgentTables(db) {
135
- for (const stmt of createTableStatements()) {
176
+ const statements = createTableStatements();
177
+ // Order matters, in three phases rather than one pass. Tables first, then the `run_id` repair, then
178
+ // indexes — because `createTableStatements` includes `CREATE INDEX ... ON "agent_message" ("run_id")`,
179
+ // and on a legacy database that index would be issued against a table whose `run_id` the repair has
180
+ // not added yet. `CREATE INDEX IF NOT EXISTS` does not save it: the guard is on the INDEX existing,
181
+ // not on the column, so the statement still fails to parse with "no such column: run_id".
182
+ for (const stmt of statements) {
183
+ if (stmt.startsWith('CREATE TABLE'))
184
+ await db.rawQuery(stmt);
185
+ }
186
+ const repairs = [];
187
+ for (const table of RUN_ID_COLUMNS) {
188
+ if (await hasColumn(db, table, 'run_id'))
189
+ continue;
190
+ await db.rawQuery(`ALTER TABLE "${table}" ADD COLUMN "run_id" VARCHAR(255) NULL`);
191
+ repairs.push(`${table}.run_id`);
192
+ }
193
+ for (const stmt of statements) {
194
+ if (stmt.startsWith('CREATE INDEX'))
195
+ await db.rawQuery(stmt);
196
+ }
197
+ return repairs;
198
+ }
199
+ /**
200
+ * `DROP TABLE IF EXISTS` for the six agent tables, in reverse dependency order so a dialect that
201
+ * enforces the `REFERENCES` clauses never refuses a drop for a child that still exists. The mirror of
202
+ * {@link createAgentTables}, and what the published migration's `down()` calls.
203
+ */
204
+ export function dropTableStatements() {
205
+ const t = AGENT_TABLES;
206
+ return [t.runs, t.tokenUsage, t.toolCalls, t.messages, t.modelPricing, t.threads].map((table) => `DROP TABLE IF EXISTS "${table}"`);
207
+ }
208
+ /** Drop the six agent tables. Destructive and irreversible — this erases every thread and every ledger row. */
209
+ export async function dropAgentTables(db) {
210
+ for (const stmt of dropTableStatements()) {
136
211
  await db.rawQuery(stmt);
137
212
  }
138
213
  }
@@ -154,7 +229,9 @@ export function ensureAgentTables(db) {
154
229
  const key = db;
155
230
  let ready = provisioned.get(key);
156
231
  if (ready === undefined) {
157
- ready = createAgentTables(db).catch((error) => {
232
+ ready = createAgentTables(db)
233
+ .then(() => undefined)
234
+ .catch((error) => {
158
235
  provisioned.delete(key);
159
236
  throw error;
160
237
  });
@@ -1 +1 @@
1
- {"version":3,"file":"lucid-schema.js","sourceRoot":"","sources":["../../../src/stores/lucid-schema.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,CAAC,MAAM,YAAY,GAAG;IAC1B,OAAO,EAAE,cAAc;IACvB,QAAQ,EAAE,eAAe;IACzB,SAAS,EAAE,iBAAiB;IAC5B,UAAU,EAAE,mBAAmB;IAC/B,YAAY,EAAE,qBAAqB;IACnC,IAAI,EAAE,WAAW;CACT,CAAC;AAEX;;;;;;;;;;;;;;;GAeG;AACH,MAAM,UAAU,qBAAqB;IACnC,MAAM,CAAC,GAAG,YAAY,CAAC;IACvB,OAAO;QACL,+BAA+B,CAAC,CAAC,OAAO;;;;;;;;;;;;;;MActC;QACF,+BAA+B,CAAC,CAAC,OAAO,2BAA2B,CAAC,CAAC,OAAO,+BAA+B;QAC3G,+BAA+B,CAAC,CAAC,QAAQ;;sDAES,CAAC,CAAC,OAAO;;;;;;;;;;;MAWzD;QACF,+BAA+B,CAAC,CAAC,QAAQ,4BAA4B,CAAC,CAAC,QAAQ,+BAA+B;QAC9G,+BAA+B,CAAC,CAAC,QAAQ,iBAAiB,CAAC,CAAC,QAAQ,cAAc;QAClF,+BAA+B,CAAC,CAAC,SAAS;;uDAES,CAAC,CAAC,QAAQ;;;;;;;;;;;;MAY3D;QACF,+BAA+B,CAAC,CAAC,SAAS,iBAAiB,CAAC,CAAC,SAAS,cAAc;QACpF,+BAA+B,CAAC,CAAC,SAAS,4BAA4B,CAAC,CAAC,SAAS,4BAA4B;QAC7G,+BAA+B,CAAC,CAAC,UAAU;;sDAEO,CAAC,CAAC,OAAO;;;;;;;;;;;;MAYzD;QACF,+BAA+B,CAAC,CAAC,UAAU,2BAA2B,CAAC,CAAC,UAAU,+BAA+B;QACjH,+BAA+B,CAAC,CAAC,UAAU,iBAAiB,CAAC,CAAC,UAAU,cAAc;QACtF,+BAA+B,CAAC,CAAC,YAAY;;;;;;;;;MAS3C;QACF,+BAA+B,CAAC,CAAC,IAAI;;sDAEa,CAAC,CAAC,OAAO;;;;;;;;;;;;;MAazD;QACF,+BAA+B,CAAC,CAAC,IAAI,qBAAqB,CAAC,CAAC,IAAI,kBAAkB;QAClF,+BAA+B,CAAC,CAAC,IAAI,2BAA2B,CAAC,CAAC,IAAI,+BAA+B;QACrG,+BAA+B,CAAC,CAAC,IAAI,4BAA4B,CAAC,CAAC,IAAI,4BAA4B;KACpG,CAAC;AACJ,CAAC;AAED;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,iBAAiB,CAAC,EAAqB;IAC3D,KAAK,MAAM,IAAI,IAAI,qBAAqB,EAAE,EAAE,CAAC;QAC3C,MAAM,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC;IAC1B,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,WAAW,GAAG,IAAI,OAAO,EAAyB,CAAC;AAEzD;;;;;GAKG;AACH,MAAM,UAAU,iBAAiB,CAAC,EAAqB;IACrD,MAAM,GAAG,GAAG,EAAuB,CAAC;IACpC,IAAI,KAAK,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;IACjC,IAAI,KAAK,KAAK,SAAS,EAAE,CAAC;QACxB,KAAK,GAAG,iBAAiB,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YAC5C,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;YACxB,MAAM,KAAK,CAAC;QACd,CAAC,CAAC,CAAC;QACH,WAAW,CAAC,GAAG,CAAC,GAAG,EAAE,KAAK,CAAC,CAAC;IAC9B,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC"}
1
+ {"version":3,"file":"lucid-schema.js","sourceRoot":"","sources":["../../../src/stores/lucid-schema.ts"],"names":[],"mappings":"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"}
@@ -31,8 +31,9 @@ export interface ToolSpec {
31
31
  roles?: string[];
32
32
  /**
33
33
  * An authorization ability name (e.g. 'cache.purge'). Consumed by an ability-aware RolesPolicy
34
- * such as the `@dudousxd/nestjs-agent-authz` Gate adapter. Apps that don't use authz ignore it
35
- * and rely on `roles` instead — both live on the same SPI, so neither is required.
34
+ * such as the `@adonis-agora/agent/authz` Bouncer adapter (`authzToolAuthorizer`), which denies
35
+ * every tool that declares none. Apps that don't use authz ignore it and rely on `roles` instead —
36
+ * both live on the same SPI, so neither is required.
36
37
  */
37
38
  ability?: string;
38
39
  }
@@ -175,10 +176,39 @@ export interface AgentRunInput {
175
176
  agentName?: string;
176
177
  }
177
178
  /**
178
- * A named agent: its prompt, the tools it may use, and its personas. Multiple definitions are
179
- * registered via `AgentModule.forFeature([...])`; an orchestrator delegates to others through
180
- * `ctx.runAgent(name, task)`. Model/store/sink/governance are shared from the module unless
181
- * overridden here.
179
+ * One `agent → agent` delegation edge, with the authorization the synthesized `ask_<target>` tool
180
+ * carries. The object form exists because delegation goes through the same {@link ToolSpec} gate as
181
+ * every other tool: a spec with neither `roles` nor `ability` is denied by both shipped authorizers,
182
+ * so an orchestrator that must actually delegate has to say who may.
183
+ *
184
+ * ```ts
185
+ * // Role-based (the default `DefaultToolAuthorizer`):
186
+ * { name: 'orchestrator', delegatesTo: [{ agent: 'researcher', roles: ['ANALYST', 'ADMIN'] }] }
187
+ *
188
+ * // Ability-based (the `@adonis-agora/agent/authz` Bouncer adapter):
189
+ * { name: 'orchestrator', delegatesTo: [{ agent: 'researcher', ability: 'agent.delegate' }] }
190
+ * ```
191
+ */
192
+ export interface DelegateEdge {
193
+ /** Name of the agent to delegate to — the `target` in `ask_<target>`. */
194
+ agent: string;
195
+ /**
196
+ * Roles allowed to invoke the synthesized delegate tool. Omitted → the `RolesPolicy` default,
197
+ * which is ADMIN-only under {@link import('./authorizer.js').DefaultToolAuthorizer}.
198
+ */
199
+ roles?: string[];
200
+ /**
201
+ * Ability the synthesized delegate tool declares. REQUIRED under an ability-aware authorizer such
202
+ * as `authzToolAuthorizer`, which denies every tool that declares none — omit it there and the
203
+ * delegation is denied on every call.
204
+ */
205
+ ability?: string;
206
+ }
207
+ /**
208
+ * A named agent: its prompt, the tools it may use, and its personas. Definitions are registered in
209
+ * `config/agent.ts` under `agents: [...]`; an orchestrator delegates to the others it names in
210
+ * {@link AgentDefinition.delegatesTo}, which the factory turns into `ask_<target>` tools. Model,
211
+ * store, sink and governance are shared from the module config unless overridden here.
182
212
  */
183
213
  export interface AgentDefinition {
184
214
  name: string;
@@ -186,8 +216,18 @@ export interface AgentDefinition {
186
216
  systemPrompt?: string | PromptBuilder;
187
217
  /** Allow-list of tool names this agent may use (subset of all registered tools). */
188
218
  tools?: string[];
189
- /** Names of other agents this agent may delegate to (auto-registered as `agent`-kind tools). */
190
- delegatesTo?: string[];
219
+ /**
220
+ * Other agents this agent may delegate to. Each edge is auto-registered as an `agent`-kind tool
221
+ * named `ask_<target>`, which the loop authorizes exactly like any other tool.
222
+ *
223
+ * A bare string declares the edge with no authorization annotation, which is fail-closed on
224
+ * purpose: under the default {@link import('./authorizer.js').DefaultToolAuthorizer} a tool with
225
+ * no `roles` is ADMIN-only, and under the `@adonis-agora/agent/authz` adapter a tool with no
226
+ * `ability` is denied outright — so under authz a bare edge can never be called. Use the
227
+ * {@link DelegateEdge} object form to declare the `roles` and/or `ability` the delegate tool
228
+ * carries.
229
+ */
230
+ delegatesTo?: (string | DelegateEdge)[];
191
231
  personas?: Persona[];
192
232
  defaultPersona?: string;
193
233
  modelId?: string;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"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"}
@@ -2,37 +2,42 @@
2
2
  exports({ to: app.migrationsPath(`${new Date().getTime()}_create_agent_rag_chunks.ts`) })
3
3
  }}}
4
4
  import { BaseSchema } from '@adonisjs/lucid/schema'
5
+ import db from '@adonisjs/lucid/services/db'
6
+ import { PgVectorStore } from '@adonis-agora/agent'
5
7
 
6
8
  /**
7
9
  * The pgvector chunk table for the @adonis-agora/agent `retrievers.pgvector({...})` store: one row per
8
10
  * embedded chunk (id `${documentId}#<n>`), the chunk text, an optional citation source, a `jsonb`
9
11
  * metadata column filtered with `@>`, and the `vector(N)` embedding ranked with the `<=>`/`<->`/`<#>`
10
- * operators. Requires the pgvector extension (`CREATE EXTENSION vector`) — Postgres only.
12
+ * operators. Requires the pgvector extension — Postgres only. Delete this file if you do not use
13
+ * pgvector RAG.
11
14
  *
12
- * Set `DIMENSION` to your embedding model's width (e.g. 1536 for text-embedding-3-small) and `OPCLASS`
13
- * to the index operator class matching the store's metric: `vector_cosine_ops` (default),
14
- * `vector_l2_ops`, or `vector_ip_ops`.
15
+ * Like the agent tables migration, this DELEGATES rather than copying DDL: `PgVectorStore` owns the
16
+ * column names and the index operator class its own queries depend on, and it exposes the same
17
+ * provisioning the store runs for itself under `ensureSchema: true`. Every statement is
18
+ * `IF NOT EXISTS`, so this is safe against a database that already has the table.
19
+ *
20
+ * SET THESE to match your retriever config in `config/agent.ts` — they must agree, or the store will
21
+ * query a table shaped differently from the one this created:
22
+ * - `DIMENSION` — your embedding model's width (1536 for text-embedding-3-small).
23
+ * - `METRIC` — 'cosine' (default), 'l2', or 'inner'. Picks the index operator class.
24
+ * - `TABLE` — only if you overrode `table` on the retriever.
15
25
  */
16
26
  const TABLE = 'agent_rag_chunks'
17
27
  const DIMENSION = 1536
18
- const OPCLASS = 'vector_cosine_ops'
28
+ const METRIC = 'cosine'
19
29
 
20
30
  export default class extends BaseSchema {
21
- async up() {
22
- this.schema.raw('CREATE EXTENSION IF NOT EXISTS vector')
31
+ /** Same reason as the agent tables migration: the DDL runs on the manager's own pooled connection. */
32
+ static disableTransactions = true
23
33
 
24
- this.schema.createTable(TABLE, (table) => {
25
- table.text('id').primary()
26
- table.text('text').notNullable()
27
- table.text('source')
28
- table.jsonb('metadata')
29
- table.specificType('embedding', `vector(${DIMENSION})`).notNullable()
34
+ async up() {
35
+ const store = new PgVectorStore(db.connection(this.db.connectionName), {
36
+ table: TABLE,
37
+ dimension: DIMENSION,
38
+ metric: METRIC,
30
39
  })
31
-
32
- // Approximate-nearest-neighbour index for the configured metric. Drop it to fall back to an exact scan.
33
- this.schema.raw(
34
- `CREATE INDEX IF NOT EXISTS ${TABLE}_embedding_idx ON ${TABLE} USING hnsw (embedding ${OPCLASS})`
35
- )
40
+ await store.ensureSchema()
36
41
  }
37
42
 
38
43
  async down() {
@@ -2,112 +2,48 @@
2
2
  exports({ to: app.migrationsPath(`${new Date().getTime()}_create_agent_tables.ts`) })
3
3
  }}}
4
4
  import { BaseSchema } from '@adonisjs/lucid/schema'
5
+ import db from '@adonisjs/lucid/services/db'
6
+ import { createAgentTables, dropAgentTables } from '@adonis-agora/agent'
5
7
 
6
8
  /**
7
- * The five tables for the @adonis-agora/agent `lucid` store: threads, messages, tool calls, token
8
- * usage and model pricing. JSON payloads (tool calls/results, follow-ups, usage, tool input/output)
9
- * are stored as TEXT — the store (de)serializes them — booleans as INTEGER (0/1), and timestamps as
10
- * epoch-ms integers, so the schema is portable across SQLite / Postgres / MySQL. The `agent_tool_call`
11
- * primary key is the model-supplied `toolCallId`, not a generated id.
9
+ * The six tables for the @adonis-agora/agent `lucid` store: threads, messages, tool calls, token
10
+ * usage, model pricing, and the run lifecycle — plus their indexes.
11
+ *
12
+ * This migration DELEGATES to the library instead of reproducing its DDL. The schema belongs to the
13
+ * library: `LucidAgentStore`, the pricing store and the governance read-model all decide together what
14
+ * columns they read and write, so a hand-copied snapshot here can only ever be right until the next
15
+ * release. It was already wrong in two ways. It reproduced `createTable(...)` with no existence guard,
16
+ * which THROWS on a database where the tables are already there — and they usually are, because
17
+ * `autoCreateTables` defaults to `true` and any of those three stores provisions the shared schema on
18
+ * its first use. And it took two files to say what the library says in one: a second additive migration
19
+ * existed purely to ALTER in the `run_id` columns this one had been written before.
20
+ *
21
+ * `createAgentTables` is idempotent (`CREATE TABLE IF NOT EXISTS`) and additive-only: it creates what
22
+ * is missing and ALTERs the `run_id` columns into a database that predates run tracking. So it is safe
23
+ * against an empty database, against one the library already auto-created, and against one left over
24
+ * from an older version — which is exactly the set of states a real app is in.
25
+ *
26
+ * `db` (the `Database` manager from `@adonisjs/lucid/services/db`) rather than `this.db`: the manager
27
+ * checks out its own connection from the pool, which is what keeps the DDL out of the migrator's
28
+ * transaction (see `disableTransactions` below). `this.db` still supplies the connection NAME, so
29
+ * `node ace migration:run --connection=x` provisions the tables on connection `x` and not on the default.
12
30
  */
13
31
  export default class extends BaseSchema {
14
- async up() {
15
- this.schema.createTable('agent_thread', (table) => {
16
- table.string('id').primary()
17
- table.string('actor_ref').notNullable()
18
- table.string('tenant_ref')
19
- table.text('title').notNullable()
20
- table.string('persona').notNullable().defaultTo('default')
21
- table.integer('transient').notNullable().defaultTo(0)
22
- table.bigInteger('pinned_at')
23
- table.text('summary')
24
- table.integer('summary_message_count').notNullable().defaultTo(0)
25
- table.string('active_stream_id')
26
- table.bigInteger('created_at').notNullable()
27
- table.bigInteger('updated_at').notNullable()
28
- table.bigInteger('deleted_at')
29
- table.index(['actor_ref', 'updated_at'], 'agent_thread_actor_updated_idx')
30
- })
31
-
32
- this.schema.createTable('agent_message', (table) => {
33
- table.string('id').primary()
34
- table
35
- .string('thread_id')
36
- .notNullable()
37
- .references('id')
38
- .inTable('agent_thread')
39
- .onDelete('CASCADE')
40
- table.string('role').notNullable()
41
- table.text('content').notNullable()
42
- table.text('tool_calls')
43
- table.text('tool_results')
44
- table.text('attachments')
45
- table.text('follow_ups')
46
- table.text('usage')
47
- table.string('persona')
48
- table.bigInteger('created_at').notNullable()
49
- table.index(['thread_id', 'created_at'], 'agent_message_thread_created_idx')
50
- })
51
-
52
- this.schema.createTable('agent_tool_call', (table) => {
53
- // PK = the model-supplied toolCallId, not a generated id.
54
- table.string('id').primary()
55
- table
56
- .string('message_id')
57
- .notNullable()
58
- .references('id')
59
- .inTable('agent_message')
60
- .onDelete('CASCADE')
61
- table.string('tool_name').notNullable()
62
- table.string('tool_type').notNullable()
63
- table.text('input')
64
- table.text('output')
65
- table.string('status').notNullable()
66
- table.string('executed_by_ref')
67
- table.integer('execution_ms')
68
- table.text('error')
69
- table.bigInteger('created_at').notNullable()
70
- table.bigInteger('executed_at')
71
- })
32
+ /**
33
+ * REQUIRED, not a preference. The DDL below runs on a connection the `Database` manager checks out
34
+ * itself — it is not part of the transaction the migrator would otherwise open for this migration.
35
+ * With `pool: { max: 1 }` (Adonis's own SQLite guidance) that transaction would hold the only
36
+ * connection while `createAgentTables` waited for a free one, and the migration would hang until the
37
+ * acquire timeout. Nothing is lost by opting out: the statements were never inside that transaction
38
+ * anyway, and re-running an interrupted `createAgentTables` is a no-op.
39
+ */
40
+ static disableTransactions = true
72
41
 
73
- this.schema.createTable('agent_token_usage', (table) => {
74
- table.string('id').primary()
75
- table
76
- .string('thread_id')
77
- .notNullable()
78
- .references('id')
79
- .inTable('agent_thread')
80
- .onDelete('CASCADE')
81
- table.string('actor_ref').notNullable()
82
- table.string('message_id')
83
- table.string('model_id').notNullable()
84
- table.string('purpose').notNullable()
85
- table.integer('input_tokens').notNullable()
86
- table.integer('output_tokens').notNullable()
87
- table.integer('cache_write_tokens')
88
- table.integer('cache_read_tokens')
89
- table.double('cost_usd')
90
- table.bigInteger('created_at').notNullable()
91
- table.index(['actor_ref', 'created_at'], 'agent_token_usage_actor_created_idx')
92
- })
93
-
94
- this.schema.createTable('agent_model_pricing', (table) => {
95
- table.string('id').primary()
96
- table.string('model_id').notNullable()
97
- table.double('input_price_per_1m').notNullable()
98
- table.double('output_price_per_1m').notNullable()
99
- table.double('cache_write_price_per_1m')
100
- table.double('cache_read_price_per_1m')
101
- table.bigInteger('effective_from').notNullable()
102
- table.integer('is_current').notNullable()
103
- })
42
+ async up() {
43
+ await createAgentTables(db.connection(this.db.connectionName))
104
44
  }
105
45
 
106
46
  async down() {
107
- this.schema.dropTableIfExists('agent_model_pricing')
108
- this.schema.dropTableIfExists('agent_token_usage')
109
- this.schema.dropTableIfExists('agent_tool_call')
110
- this.schema.dropTableIfExists('agent_message')
111
- this.schema.dropTableIfExists('agent_thread')
47
+ await dropAgentTables(db.connection(this.db.connectionName))
112
48
  }
113
49
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@adonis-agora/agent",
3
- "version": "0.23.0",
3
+ "version": "0.25.0",
4
4
  "description": "Governed, durable-backed AI agent (chat + tool-calling + governance) for AdonisJS — part of the Agora ecosystem.",
5
5
  "license": "MIT",
6
6
  "repository": {
@@ -196,7 +196,7 @@
196
196
  "zod": "3.25.76"
197
197
  },
198
198
  "engines": {
199
- "node": "v22.23.2"
199
+ "node": ">=20.6.0"
200
200
  },
201
201
  "keywords": [
202
202
  "adonisjs",
@@ -1,80 +0,0 @@
1
- {{{
2
- exports({ to: app.migrationsPath(`${new Date().getTime()}_create_agent_run_tracking.ts`) })
3
- }}}
4
- import { BaseSchema } from '@adonisjs/lucid/schema'
5
-
6
- /**
7
- * Additive migration for @adonis-agora/agent RUN tracking. Adds the `agent_run` table (one row per
8
- * run/turn lifecycle) plus a nullable `run_id` correlation column on `agent_message`,
9
- * `agent_tool_call` and `agent_token_usage`. `run_id` is deliberately NOT a DB foreign key (like the
10
- * reference): it can be `ALTER TABLE ADD COLUMN`-ed portably (SQLite can't add a column WITH a FK
11
- * constraint) and a row written before this shipped keeps a `null` run_id.
12
- *
13
- * Timestamps are epoch-ms integers, booleans INTEGER (0/1) and cost a DOUBLE, matching
14
- * `create_agent_tables` so the schema stays portable across SQLite / Postgres / MySQL. Safe to run on
15
- * an existing deployment: it only creates a new table and adds nullable columns.
16
- */
17
- export default class extends BaseSchema {
18
- async up() {
19
- this.schema.createTable('agent_run', (table) => {
20
- table.string('id').primary()
21
- table
22
- .string('thread_id')
23
- .notNullable()
24
- .references('id')
25
- .inTable('agent_thread')
26
- .onDelete('CASCADE')
27
- table.string('agent_name')
28
- table.string('actor_ref').notNullable()
29
- table.string('tenant_ref')
30
- table.string('status').notNullable()
31
- table.bigInteger('started_at').notNullable()
32
- table.bigInteger('finished_at')
33
- table.integer('step_count').notNullable().defaultTo(0)
34
- table.integer('input_tokens').notNullable().defaultTo(0)
35
- table.integer('output_tokens').notNullable().defaultTo(0)
36
- table.double('cost_usd')
37
- table.text('error')
38
- table.integer('durable').notNullable().defaultTo(0)
39
- table.index(['started_at'], 'agent_run_started_idx')
40
- table.index(['actor_ref', 'started_at'], 'agent_run_actor_started_idx')
41
- table.index(['status', 'started_at'], 'agent_run_status_started_idx')
42
- })
43
-
44
- this.schema.alterTable('agent_message', (table) => {
45
- table.string('run_id')
46
- table.index(['run_id'], 'agent_message_run_idx')
47
- })
48
-
49
- this.schema.alterTable('agent_tool_call', (table) => {
50
- table.string('run_id')
51
- table.index(['run_id'], 'agent_tool_call_run_idx')
52
- table.index(['status', 'created_at'], 'agent_tool_call_status_created_idx')
53
- })
54
-
55
- this.schema.alterTable('agent_token_usage', (table) => {
56
- table.string('run_id')
57
- table.index(['run_id'], 'agent_token_usage_run_idx')
58
- })
59
- }
60
-
61
- async down() {
62
- this.schema.alterTable('agent_token_usage', (table) => {
63
- table.dropIndex(['run_id'], 'agent_token_usage_run_idx')
64
- table.dropColumn('run_id')
65
- })
66
-
67
- this.schema.alterTable('agent_tool_call', (table) => {
68
- table.dropIndex(['status', 'created_at'], 'agent_tool_call_status_created_idx')
69
- table.dropIndex(['run_id'], 'agent_tool_call_run_idx')
70
- table.dropColumn('run_id')
71
- })
72
-
73
- this.schema.alterTable('agent_message', (table) => {
74
- table.dropIndex(['run_id'], 'agent_message_run_idx')
75
- table.dropColumn('run_id')
76
- })
77
-
78
- this.schema.dropTableIfExists('agent_run')
79
- }
80
- }