@adonis-agora/agent
Version:
Governed, durable-backed AI agent (chat + tool-calling + governance) for AdonisJS — part of the Agora ecosystem.
64 lines • 3.25 kB
TypeScript
import type { BrandedFunctionalTool } from '../ai-tool-ref.js';
import type { LucidRawRunner } from '../stores/lucid.js';
import { type GroupTableAccessConfig, type TableAccessPolicy } from './table-access.js';
import { type TenantScopeConfig } from './tenant-scope.js';
/** App-supplied runner over a read-only connection. The package never opens a DB itself. */
export interface QueryRunner {
run(sql: string): Promise<Record<string, unknown>[]>;
}
/**
* Configuration for {@link dataTool} — the governed read-only SQL agent tool. Mirrors the reference
* `ExecuteSqlDeps`, adapted to the AdonisJS `defineConfig`/factory idiom. Supply the DB handle as a
* structural {@link LucidRawRunner} (so `@adonisjs/lucid` stays an optional peer) or a custom
* {@link QueryRunner}.
*/
export interface DataToolConfig {
/**
* Read-only Lucid DB handle (structural). Queries run through `db.rawQuery(sql)`. Point it at a
* read-only connection/replica. Provide this OR {@link DataToolConfig.runner}.
*/
db?: LucidRawRunner;
/** Custom query runner. Overrides {@link DataToolConfig.db} when both are given. */
runner?: QueryRunner;
/**
* Coarse table-level allowlist checked for every referenced table. Pass a {@link TableAccessPolicy}
* instance, or a {@link GroupTableAccessConfig} to build the default {@link GroupTableAccessPolicy}.
* **Required** — there is no implicit allow-all (fail-closed).
*/
tableAccess: TableAccessPolicy | GroupTableAccessConfig;
/** Optional per-row tenant constraint injected before the query runs. */
tenant?: TenantScopeConfig;
/** Row cap injected when the query has no LIMIT. Default 100. */
maxRows?: number;
/**
* Reject the query if the runner has not resolved within this many ms — a soft statement-timeout
* guard (the query may keep running server-side; the model gets a timeout error to re-plan). Off by
* default; pair with a DB-level statement timeout for a hard cap.
*/
statementTimeoutMs?: number;
/** Tool name the model sees. Default `executeSql`. */
name?: string;
/** Roles allowed to invoke the tool (spec-level gate). Omit → config defaults (ADMIN-only). */
roles?: string[];
/** Authz ability checked by an ability-aware `RolesPolicy`. */
ability?: string;
}
export interface DataToolResult {
rows: Record<string, unknown>[];
rowCount: number;
sql: string;
truncated?: true;
}
/**
* Builds the governed `executeSql` read tool as a branded functional tool ({@link defineTool}) the agent
* registry auto-discovers. Register it in `config/agent.ts` (`defineConfig({ tools: [dataTool({ ... })] })`)
* or export it from an `app/agent_tools/` module.
*
* The pipeline per call (identical to the reference satellite) is:
* validate (single SELECT) → assert table access for every referenced table →
* tenant-scope rewrite (if configured) → inject LIMIT → run → return rows,
* truncating the payload if it would exceed ~256KB. `node-sql-parser` is imported lazily on the first
* call, so it stays an optional peer.
*/
export declare function dataTool(config: DataToolConfig): BrandedFunctionalTool;
//# sourceMappingURL=data-tool.d.ts.map