@happyvertical/smrt-agents 0.42.6 → 0.42.7

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 CHANGED
@@ -142,6 +142,27 @@ The **`default` persona reuses the singleton identity** (a `null` key), which is
142
142
 
143
143
  `executeAsPrincipal(options, fn)` runs agent work **AS a persona's bound user**, reusing the existing RBAC cascade with no snapshotting. It publishes `(user_id, tenant_id, permissions[])` onto the DB session (Postgres RLS then bounds every query per-`(table, action)` and per-tenant) and hands `fn` a `PrincipalRun` whose `assertToolAllowed()` / `assertOperation()` enforce the persona tool ceiling and the RLS-off catalog gate. Effective authority = **bound-user RBAC ∩ agent-class ceiling ∩ persona `allowedTools`**. Actions audit as on-behalf-of the originating user via a `PrincipalAuditSink`.
144
144
 
145
+ ## Data Surface Read Tools (issue #2447)
146
+
147
+ `createDataSurfaceTools()` produces the `data.discover`, `data.inspect`, and
148
+ `data.query` `PrincipalTool`s consumed through chat's `extraTools` seam. The
149
+ caller supplies a server-owned surface catalog and executor; the tools copy
150
+ `userId`, `tenantId`, database, and permissions only from the live
151
+ `PrincipalRun`. Discovery and inspection first assert the collection's read
152
+ catalog permission and omit denied surfaces/fields. Query requests and results
153
+ are normalized with the core bounded data-query protocol, including projection,
154
+ cursor/page, row/byte, fingerprint, freshness, total, and truncation rules.
155
+ Sensitive/read-permission fields are removed from descriptors, and
156
+ `DataSurfaceField` policy metadata is stripped before the core schema validator.
157
+ Executor-provided paginated rows retain their order and are validated with a
158
+ stable identity tie-breaker (including type-aware numeric/date comparisons),
159
+ while internal sort keys are stripped when they were not requested in the
160
+ projection. Execution has a bounded deadline; public executor/result failures
161
+ use stable generic errors while optional `onFailure` telemetry receives the
162
+ authenticated/delegated principal and detailed server-side error. Hidden field
163
+ request failures also use a stable public error. Tool arguments never contain
164
+ principal or tenant authority.
165
+
145
166
  ## Agent Orchestration (issue #1892) — invoke-agent + principal delegation
146
167
 
147
168
  A conversational (orchestrator) agent can invoke worker agents with **principal delegation**. This is *not* a new engine — it is a standard `invoke-agent` tool plus a completion-dispatch convention on top of `executeAsPrincipal` + the DispatchBus.
package/README.md CHANGED
@@ -138,6 +138,26 @@ such as `MessagingSettingsService`.
138
138
  | `QueryFn` | Query function type |
139
139
  | `AgentWithInterestsOptions` | Agent options with interests |
140
140
 
141
+ ### Server Export (`@happyvertical/smrt-agents/server`)
142
+
143
+ `createDataSurfaceActionAdapter()` provides server-only preview and confirmed
144
+ apply orchestration for the `smrt-ui` data-surface action contract. Browser
145
+ selections and action payloads are hints, never authority: each action declares
146
+ its input validator, confirmation policy, principal tool/RBAC operation, fresh
147
+ authorization and row-eligibility checks, and foreground or injected-background
148
+ execution.
149
+
150
+ Preview issues a short-lived opaque token bound to the principal, tenant,
151
+ surface/action, selection, query fingerprint, and revision. Apply verifies that
152
+ binding for confirmation-required actions and repeats its principal-bound checks
153
+ before returning accepted, skipped, and failed row outcomes. Actions declared
154
+ with `confirmation: 'none'` may apply directly with an idempotency key; every
155
+ other apply must include its current preview token. Callers must supply a durable shared
156
+ `DataSurfaceActionStateStore` with atomic token and idempotency operations.
157
+ `InMemoryDataSurfaceActionStateStore` is for single-process test harnesses only.
158
+ Background queues must invoke the supplied job `run()` callback so checks are
159
+ repeated at execution time.
160
+
141
161
  ### UI Export (`@happyvertical/smrt-agents/ui`)
142
162
 
143
163
  | Export | Description |
@@ -1,5 +1,7 @@
1
1
  import { ObjectRegistry, SmrtCollection, SmrtObject, field, getClassName, smrt } from "@happyvertical/smrt-core";
2
+ import { createLogger } from "@happyvertical/logger";
2
3
  import { TenantScoped, queryGlobal, queryWithGlobals, tenantId } from "@happyvertical/smrt-tenancy";
4
+ import { assertOperationPermission, withPrincipalPermissionContext } from "@happyvertical/smrt-users";
3
5
  //#region src/identity.ts
4
6
  function getAgentTypeName(name) {
5
7
  const registered = ObjectRegistry.getClass(name);
@@ -167,6 +169,67 @@ var AgentConfigCollection = class extends SmrtCollection {
167
169
  }
168
170
  };
169
171
  //#endregion
170
- export { getAgentTypeName as a, getAgentTypeAliases as i, AgentConfigCollection as n, instanceScopedSubscriber as o, getAgentClassName as r, AgentConfig as t };
172
+ //#region src/execute-as-principal.ts
173
+ var PrincipalToolNotAllowedError = class extends Error {
174
+ tool;
175
+ status = 403;
176
+ constructor(tool) {
177
+ super(`Tool '${tool}' is not permitted for this persona.`);
178
+ this.name = "PrincipalToolNotAllowedError";
179
+ this.tool = tool;
180
+ }
181
+ };
182
+ async function emitAudit(entry, audit, logger) {
183
+ if (audit) {
184
+ await audit(entry);
185
+ return;
186
+ }
187
+ (logger ?? createLogger({ level: "info" })).info("agent action executed on behalf of originating user", { ...entry });
188
+ }
189
+ async function executeAsPrincipal(options, fn) {
190
+ const { principal, onBehalfOfUserId = null, agentClass, action = "agent.run", auditMetadata, permissions, resolver, postgresRls, enterTenantContext, audit, logger, ...smrtOptions } = options;
191
+ const { runAsUserId, tenantId, actsAsProfileId = null } = principal;
192
+ const toolWhitelist = Array.isArray(principal.allowedTools) ? principal.allowedTools : [];
193
+ const isToolAllowed = (tool) => typeof tool === "string" && tool.length > 0 && toolWhitelist.includes(tool);
194
+ await emitAudit({
195
+ action,
196
+ actorUserId: runAsUserId,
197
+ onBehalfOfUserId,
198
+ tenantId,
199
+ agentClass,
200
+ actsAsProfileId,
201
+ metadata: auditMetadata
202
+ }, audit, logger);
203
+ return withPrincipalPermissionContext({
204
+ ...smrtOptions,
205
+ userId: runAsUserId,
206
+ tenantId,
207
+ permissions,
208
+ resolver,
209
+ postgresRls,
210
+ enterTenantContext: enterTenantContext ?? tenantId !== null
211
+ }, async (context) => {
212
+ return fn({
213
+ context,
214
+ permissions: context.permissions,
215
+ allowedTools: toolWhitelist,
216
+ isToolAllowed,
217
+ assertToolAllowed(tool) {
218
+ if (!isToolAllowed(tool)) throw new PrincipalToolNotAllowedError(tool);
219
+ },
220
+ async assertOperation(collection, operationAction, extraOptions) {
221
+ return assertOperationPermission({
222
+ ...smrtOptions,
223
+ ...extraOptions,
224
+ collection,
225
+ action: operationAction,
226
+ permissionSet: context.permissionSet
227
+ });
228
+ }
229
+ });
230
+ });
231
+ }
232
+ //#endregion
233
+ export { getAgentClassName as a, instanceScopedSubscriber as c, AgentConfigCollection as i, executeAsPrincipal as n, getAgentTypeAliases as o, AgentConfig as r, getAgentTypeName as s, PrincipalToolNotAllowedError as t };
171
234
 
172
- //# sourceMappingURL=config-BRQLhsFp.js.map
235
+ //# sourceMappingURL=execute-as-principal-DltxRqN2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"execute-as-principal-DltxRqN2.js","names":["tenantId"],"sources":["../../src/identity.ts","../../src/config.ts","../../src/execute-as-principal.ts"],"sourcesContent":["import { getClassName, ObjectRegistry } from '@happyvertical/smrt-core';\n\n/**\n * Return the canonical agent type identifier for storage and dispatch routing.\n *\n * Uses the registry's qualified name when available and falls back to the input\n * name for dynamically defined or unregistered classes.\n */\nexport function getAgentTypeName(name: string): string {\n const registered = ObjectRegistry.getClass(name);\n return registered?.qualifiedName || registered?.name || name;\n}\n\n/**\n * Return the human-readable class name for UI and logs.\n */\nexport function getAgentClassName(name: string): string {\n const registered = ObjectRegistry.getClass(name);\n return registered?.name || getClassName(name);\n}\n\n/**\n * Return all meaningful aliases for an agent type.\n *\n * The qualified name is first so persistence lookups prefer canonical rows,\n * while the simple class name keeps legacy rows discoverable during migration.\n */\nexport function getAgentTypeAliases(name: string): string[] {\n return Array.from(\n new Set([getAgentTypeName(name), getAgentClassName(name)].filter(Boolean)),\n );\n}\n\n/**\n * Compose a per-instance dispatch subscriber identity from an agent type and an\n * optional instance key (#1890).\n *\n * Multiple durable instances of one agent class each need their own subscriber\n * name so their dispatch subscriptions and pending dispatches never collide —\n * that is what keeps two instances from double-processing each other's work.\n *\n * Returns the bare `agentType` when `instanceKey` is nullish/empty, so a\n * **singleton** agent's subscriber is byte-for-byte unchanged (the N=1 default).\n * When a key is present the identity is `` `${agentType}#${instanceKey}` `` — a\n * stable, reversible composition (the type never contains `#`).\n */\nexport function instanceScopedSubscriber(\n agentType: string,\n instanceKey?: string | null,\n): string {\n return instanceKey ? `${agentType}#${instanceKey}` : agentType;\n}\n","/**\n * AgentConfig - Persistent configuration storage for agents\n *\n * This module provides database-backed configuration for agents,\n * enabling consuming apps to persist agent settings.\n *\n * @module\n */\n\nimport {\n field,\n type SmrtClassOptions,\n SmrtCollection,\n SmrtObject,\n smrt,\n} from '@happyvertical/smrt-core';\nimport {\n queryGlobal,\n queryWithGlobals,\n TenantScoped,\n tenantId,\n} from '@happyvertical/smrt-tenancy';\nimport { getAgentTypeName } from './identity.js';\n\n/**\n * AgentConfig stores agent configuration in the database\n *\n * Each config record maps to a UI slot for an agent configuration owner:\n * - agentId: The durable config owner ID (persona ID for persona-backed\n * instances; Agent STI row ID for legacy/singleton instances)\n * - agentClass: The canonical agent type (qualified name when available)\n * - slotId: The configuration slot (e.g., 'sources', 'settings')\n * - configData: JSON object containing the configuration\n *\n * @example\n * ```typescript\n * // Save config for an agent slot\n * const config = new AgentConfig({\n * agentId: agent.id,\n * agentClass: 'Praeco',\n * slotId: 'sources',\n * configData: { scrapers: ['civicweb', 'govstack'] },\n * db: options.db\n * });\n * await config.initialize();\n * await config.save();\n * ```\n */\n@TenantScoped({ mode: 'optional' })\n@smrt({\n tableName: 'agent_configs',\n api: { include: ['list', 'get', 'create', 'update', 'delete'] },\n mcp: { include: ['list', 'get'] },\n cli: true,\n})\nexport class AgentConfig extends SmrtObject {\n /**\n * Tenant ID for multi-tenant isolation\n * Nullable to support both tenant-scoped and global agent configs\n */\n @tenantId({ nullable: true })\n tenantId: string | null = null;\n\n /**\n * Durable configuration owner ID.\n *\n * The database column retains the historical `agent_id` name for backward\n * compatibility. Persona-backed runtimes store their `AgentPersona.id` here;\n * legacy runtimes store the persisted Agent STI row id.\n */\n @field({ type: 'text' })\n agentId: string = '';\n\n /**\n * Canonical agent type for this config (qualified name when available)\n */\n @field({ type: 'text' })\n agentClass: string = '';\n\n /**\n * UI slot ID (e.g., 'sources', 'settings', 'reports')\n */\n @field({ type: 'text' })\n slotId: string = '';\n\n /**\n * Configuration data stored as JSON\n *\n * Sensitive (#1540) for backward compatibility with legacy blobs, so this is\n * excluded from generated API/MCP responses and rejected as a `where` filter\n * key. New settings schemas must keep credentials in a dedicated secrets\n * service rather than this field.\n */\n @field({ type: 'json', sensitive: true })\n configData: Record<string, unknown> = {};\n\n /**\n * Schema version for future migrations\n */\n @field({ type: 'integer' })\n schemaVersion: number = 1;\n\n /**\n * Load all configs for a specific agent\n *\n * @param agentId - Agent instance ID\n * @param options - Database options\n * @returns Map of slotId → configData\n */\n static async forAgent(\n agentId: string,\n options: SmrtClassOptions,\n ): Promise<Map<string, Record<string, unknown>>> {\n const configsByAgent = await AgentConfig.forAgents([agentId], options);\n return configsByAgent.get(agentId) ?? new Map();\n }\n\n /**\n * Load configs for multiple agents in a single query.\n *\n * @param agentIds - Agent instance IDs\n * @param options - Database options\n * @returns Map of agentId -> (slotId -> configData)\n */\n static async forAgents(\n agentIds: string[],\n options: SmrtClassOptions,\n ): Promise<Map<string, Map<string, Record<string, unknown>>>> {\n const configsByAgent = new Map<\n string,\n Map<string, Record<string, unknown>>\n >();\n if (agentIds.length === 0) {\n return configsByAgent;\n }\n\n const collection = await AgentConfigCollection.create(options);\n const configs = await collection.list({\n where: { 'agentId in': agentIds },\n });\n\n for (const config of configs) {\n if (!configsByAgent.has(config.agentId)) {\n configsByAgent.set(config.agentId, new Map());\n }\n configsByAgent.get(config.agentId)?.set(config.slotId, config.configData);\n }\n\n return configsByAgent;\n }\n\n /**\n * Load config for a specific agent and slot\n *\n * @param agentId - Agent instance ID\n * @param slotId - UI slot ID\n * @param options - Database options\n * @returns Config data or undefined if not found\n */\n static async forSlot(\n agentId: string,\n slotId: string,\n options: SmrtClassOptions,\n ): Promise<Record<string, unknown> | undefined> {\n const collection = await AgentConfigCollection.create(options);\n const configs = await collection.list({\n where: { agentId, slotId },\n limit: 1,\n });\n return configs[0]?.configData;\n }\n\n /**\n * Save or update config for an agent slot\n *\n * @param data - Config data including agentId, agentClass, slotId, configData\n * @param options - Database options\n * @returns Saved AgentConfig instance\n */\n static async saveSlot(\n data: {\n agentId: string;\n agentClass: string;\n slotId: string;\n configData: Record<string, unknown>;\n },\n options: SmrtClassOptions,\n ): Promise<AgentConfig> {\n const normalizedAgentClass = getAgentTypeName(data.agentClass);\n const collection = await AgentConfigCollection.create(options);\n\n // Check for existing config using list with where clause\n const existingConfigs = await collection.list({\n where: { agentId: data.agentId, slotId: data.slotId },\n limit: 1,\n });\n\n if (existingConfigs.length > 0) {\n // Update existing\n const existing = existingConfigs[0];\n existing.configData = data.configData;\n existing.agentClass = normalizedAgentClass;\n await existing.save();\n return existing;\n }\n\n // Create new\n const config = await collection.create({\n agentId: data.agentId,\n agentClass: normalizedAgentClass,\n slotId: data.slotId,\n configData: data.configData,\n slug: `${data.agentId}-${data.slotId}`,\n });\n await config.save();\n return config;\n }\n}\n\n/**\n * Collection for AgentConfig objects\n */\nexport class AgentConfigCollection extends SmrtCollection<AgentConfig> {\n static readonly _itemClass = AgentConfig;\n\n /**\n * Find all configs for a specific tenant\n * @param tenantId - Tenant ID to filter by\n * @returns Array of AgentConfig objects for the tenant\n */\n async findByTenant(tenantId: string): Promise<AgentConfig[]> {\n return this.list({ where: { tenantId } });\n }\n\n /**\n * Find all global configs (not associated with any tenant).\n *\n * Routes through the shared tenant-global helper so it does not throw under\n * an active tenant context (an explicit `tenant_id IS NULL` filter would be\n * flagged as an isolation violation). (#1600)\n *\n * @returns Array of global AgentConfig objects\n */\n async findGlobal(): Promise<AgentConfig[]> {\n return queryGlobal<AgentConfig>(this);\n }\n\n /**\n * Find configs for a tenant including global configs.\n *\n * Fails closed if an active tenant context requests a different tenant's\n * rows; the admin/system path keeps the cross-tenant capability. (#1600)\n *\n * @param tenantId - Tenant ID to include\n * @returns Array of AgentConfig objects for the tenant and global configs\n */\n async findWithGlobals(tenantId: string): Promise<AgentConfig[]> {\n return queryWithGlobals<AgentConfig>(\n this,\n tenantId,\n 'AgentConfig.findWithGlobals',\n );\n }\n}\n","/**\n * ExecuteAsPrincipal — run an agent's work AS its persona's bound user.\n *\n * This is deliberately NOT a new authorization layer. It reuses the framework's\n * existing principal-context machinery:\n *\n * - {@link withPrincipalPermissionContext} resolves the bound user's *live*\n * permission set (the standard {@link PermissionResolver} cascade) and\n * publishes `(smrt.user_id, smrt.tenant_id, smrt.permissions[])` onto the DB\n * session. With Postgres RLS enabled, the manifest-derived policies then bound\n * every query the agent makes per-`(table, action)` and per-tenant — through\n * any door (in-process \"side door\", REST, MCP), with no per-call re-checking.\n *\n * - Because RLS is Postgres-only and opt-in, the exec/tool seam must ALSO assert\n * the catalog permission for the `(collection, action)` when RLS is off\n * (SQLite/dev). {@link PrincipalRun.assertOperation} wraps\n * `assertOperationPermission` for exactly that, so the authority bound holds\n * on every adapter.\n *\n * The effective authority of an agent action is therefore:\n *\n * bound-user RBAC ∩ agent-class capability ceiling ∩ persona allowedTools\n *\n * where the RBAC half is enforced at the data layer (RLS) or the catalog seam\n * (`assertOperation`), and the tool half is enforced by\n * {@link PrincipalRun.assertToolAllowed} against `allowedTools` — which a\n * resolved persona has already intersected with the `TenantAgent` ceiling.\n *\n * Actions audit as on-behalf-of the originating user (see {@link PrincipalAuditEntry}).\n *\n * @packageDocumentation\n */\n\nimport { createLogger, type Logger } from '@happyvertical/logger';\nimport type { SmrtClassOptions } from '@happyvertical/smrt-core';\nimport {\n assertOperationPermission,\n type OperationPermissionCollectionInput,\n type OperationPermissionDecision,\n type PermissionResolver,\n type SessionPermissionRuntimeContext,\n withPrincipalPermissionContext,\n} from '@happyvertical/smrt-users';\n\n/**\n * The bound principal an agent runs as. A resolved persona structurally\n * satisfies this once its optional `runAsUserId` has been narrowed to a\n * concrete id — `allowedTools` on a `ResolvedPersona` is already the persona's\n * tools intersected with the `TenantAgent` capability ceiling.\n */\nexport interface PrincipalBinding {\n /** The user whose live permissions bound this execution. Required. */\n runAsUserId: string;\n /** Tenant the principal acts within. */\n tenantId: string | null;\n /**\n * The persona's tool allow-list (already capped by the agent-class ceiling).\n * This is a **fail-closed** whitelist, mirroring\n * `@happyvertical/smrt-chat`'s `AgentSession.isToolAllowed()` (S5 #1392): an\n * absent (`undefined`) or empty allow-list permits **NO** tools, never all of\n * them, so forgetting to pass it can only tighten authority. Resolved personas\n * always provide a concrete `string[]`.\n */\n allowedTools?: string[];\n /** Optional acting `Bot` profile id, recorded in the audit entry. */\n actsAsProfileId?: string | null;\n}\n\n/**\n * A single audit record describing an agent action performed by the bound\n * principal (`actorUserId`) on behalf of the originating user\n * (`onBehalfOfUserId`).\n */\nexport interface PrincipalAuditEntry {\n /** Action label, e.g. `'agent.run'`. */\n action: string;\n /** The persona's bound user the work ran as. */\n actorUserId: string;\n /** The user who triggered the agent, if known. */\n onBehalfOfUserId: string | null;\n /** Tenant the action ran within. */\n tenantId: string | null;\n /** Canonical agent class, when the caller supplies it. */\n agentClass?: string;\n /** Acting profile id, when the persona sets one. */\n actsAsProfileId?: string | null;\n /** Free-form additional context. */\n metadata?: Record<string, unknown>;\n}\n\n/**\n * Sink that records a {@link PrincipalAuditEntry}. Provide one to persist audit\n * rows (e.g. via `AuditLog.record`); when omitted, the entry is emitted as a\n * structured log line.\n */\nexport type PrincipalAuditSink = (\n entry: PrincipalAuditEntry,\n) => void | Promise<void>;\n\n/**\n * Options for {@link executeAsPrincipal}.\n */\nexport interface ExecuteAsPrincipalOptions extends SmrtClassOptions {\n /** The bound principal to run as. */\n principal: PrincipalBinding;\n /** The originating user the action is performed on behalf of (for audit). */\n onBehalfOfUserId?: string | null;\n /** Canonical agent class, recorded in the audit entry. */\n agentClass?: string;\n /** Audit action label. Defaults to `'agent.run'`. */\n action?: string;\n /** Extra audit metadata merged into the emitted entry. */\n auditMetadata?: Record<string, unknown>;\n /**\n * Pre-resolved permission slugs. When omitted, the principal's permissions\n * are resolved live so role changes reflect on the next execution.\n */\n permissions?: string[];\n /** Reuse an initialized resolver across executions. */\n resolver?: PermissionResolver;\n /** Opt into Postgres RLS transaction wrapping (defaults to package config). */\n postgresRls?: boolean;\n /**\n * Enter tenant context so tenant auto-filtering applies on every adapter.\n * Defaults to `true` whenever the principal has a tenant.\n */\n enterTenantContext?: boolean;\n /** Audit sink. Defaults to a structured log line. */\n audit?: PrincipalAuditSink;\n /** Logger used for the default audit sink. */\n logger?: Logger;\n}\n\n/**\n * Thrown when the persona attempts a tool outside its `allowedTools`.\n */\nexport class PrincipalToolNotAllowedError extends Error {\n readonly tool: string;\n readonly status = 403;\n\n constructor(tool: string) {\n super(`Tool '${tool}' is not permitted for this persona.`);\n this.name = 'PrincipalToolNotAllowedError';\n this.tool = tool;\n }\n}\n\n/**\n * The handle passed to the {@link executeAsPrincipal} body. Its\n * session-permission {@link context} is already published for the principal, so\n * data operations are bounded by RLS on Postgres. The assertions enforce the\n * remaining two authority dimensions.\n */\nexport interface PrincipalRun {\n /** The published session-permission runtime context for the principal. */\n context: SessionPermissionRuntimeContext;\n /** The principal's published (snapshot) permission slugs. */\n permissions: string[];\n /**\n * The effective, fail-closed tool allow-list — always a concrete array (an\n * absent binding allow-list normalizes to `[]`, i.e. no tools).\n */\n allowedTools: string[];\n /**\n * Whether `tool` is within the fail-closed allow-list. An empty allow-list,\n * or an empty/non-string tool name, permits nothing.\n */\n isToolAllowed(tool: string): boolean;\n /** Throw {@link PrincipalToolNotAllowedError} unless `tool` is allowed. */\n assertToolAllowed(tool: string): void;\n /**\n * Assert the principal holds the catalog permission for `(collection,\n * action)`, authorizing against the **published** principal set\n * (`context.permissionSet`) — the same snapshot the RLS session enforces — so\n * the bound is adapter-independent. This is the door-agnostic teeth for the\n * RLS-off adapters; under Postgres RLS it is a redundant (but harmless)\n * second gate. Throws `OperationPermissionError` on denial.\n */\n assertOperation(\n collection: OperationPermissionCollectionInput,\n action: string,\n extraOptions?: SmrtClassOptions,\n ): Promise<OperationPermissionDecision>;\n}\n\nasync function emitAudit(\n entry: PrincipalAuditEntry,\n audit: PrincipalAuditSink | undefined,\n logger: Logger | undefined,\n): Promise<void> {\n if (audit) {\n await audit(entry);\n return;\n }\n const log = logger ?? createLogger({ level: 'info' });\n log.info('agent action executed on behalf of originating user', {\n ...entry,\n });\n}\n\n/**\n * Run `fn` AS the persona's bound principal.\n *\n * Resolves the bound user's live permissions, publishes them onto the DB\n * session (so Postgres RLS bounds every query per-`(table, action)`), emits an\n * on-behalf-of audit entry, and hands `fn` a {@link PrincipalRun} whose\n * assertions enforce the persona tool ceiling and the RLS-off catalog gate.\n *\n * @example\n * ```typescript\n * await executeAsPrincipal(\n * {\n * db,\n * principal: {\n * runAsUserId: persona.runAsUserId,\n * tenantId: persona.tenantId,\n * allowedTools: persona.allowedTools,\n * },\n * onBehalfOfUserId: triggeringUserId,\n * agentClass: persona.agentClass,\n * },\n * async (run) => {\n * run.assertToolAllowed('articles.publish');\n * await run.assertOperation('articles', 'update');\n * await agent.run();\n * },\n * );\n * ```\n */\nexport async function executeAsPrincipal<T>(\n options: ExecuteAsPrincipalOptions,\n fn: (run: PrincipalRun) => Promise<T>,\n): Promise<T> {\n const {\n principal,\n onBehalfOfUserId = null,\n agentClass,\n action = 'agent.run',\n auditMetadata,\n permissions,\n resolver,\n postgresRls,\n enterTenantContext,\n audit,\n logger,\n ...smrtOptions\n } = options;\n\n const { runAsUserId, tenantId, actsAsProfileId = null } = principal;\n\n // Fail-closed tool allow-list (mirrors chat's AgentSession, S5 #1392): an\n // absent or non-array binding allow-list normalizes to `[]` — no tools — so a\n // missing ceiling can only tighten authority, never open it up.\n const toolWhitelist = Array.isArray(principal.allowedTools)\n ? principal.allowedTools\n : [];\n const isToolAllowed = (tool: string): boolean =>\n typeof tool === 'string' && tool.length > 0 && toolWhitelist.includes(tool);\n\n await emitAudit(\n {\n action,\n actorUserId: runAsUserId,\n onBehalfOfUserId,\n tenantId,\n agentClass,\n actsAsProfileId,\n metadata: auditMetadata,\n },\n audit,\n logger,\n );\n\n return withPrincipalPermissionContext(\n {\n ...smrtOptions,\n userId: runAsUserId,\n tenantId,\n permissions,\n resolver,\n postgresRls,\n enterTenantContext: enterTenantContext ?? tenantId !== null,\n },\n async (context) => {\n const run: PrincipalRun = {\n context,\n permissions: context.permissions,\n allowedTools: toolWhitelist,\n isToolAllowed,\n assertToolAllowed(tool: string): void {\n if (!isToolAllowed(tool)) {\n throw new PrincipalToolNotAllowedError(tool);\n }\n },\n async assertOperation(\n collection: OperationPermissionCollectionInput,\n operationAction: string,\n extraOptions?: SmrtClassOptions,\n ): Promise<OperationPermissionDecision> {\n return assertOperationPermission({\n ...smrtOptions,\n ...extraOptions,\n collection,\n action: operationAction,\n // Authorize against the PUBLISHED principal set (the same snapshot\n // Postgres RLS enforces for this context), not a fresh live\n // re-resolve — keeps the RLS-off gate adapter-independent.\n permissionSet: context.permissionSet,\n });\n },\n };\n return fn(run);\n },\n );\n}\n"],"mappings":"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"}
@@ -0,0 +1,126 @@
1
+ import { SmrtClassOptions } from '@happyvertical/smrt-core';
2
+ import { DataQueryFieldDescriptor, DataQueryRequest, DataQueryResult, DataQueryRow, DataQuerySchema } from '@happyvertical/smrt-types';
3
+ import { PrincipalRun } from './execute-as-principal.js';
4
+ import { PrincipalTool } from './invoke-agent.js';
5
+ export declare const DATA_DISCOVER_TOOL_SLUG = "data.discover";
6
+ export declare const DATA_INSPECT_TOOL_SLUG = "data.inspect";
7
+ export declare const DATA_QUERY_TOOL_SLUG = "data.query";
8
+ export declare const DATA_DISCOVER_FUNCTION_NAME = "data-discover";
9
+ export declare const DATA_INSPECT_FUNCTION_NAME = "data-inspect";
10
+ export declare const DATA_QUERY_FUNCTION_NAME = "data-query";
11
+ export declare const DEFAULT_DATA_SURFACE_DEADLINE_MS = 5000;
12
+ export declare const MAX_DATA_SURFACE_DEADLINE_MS = 30000;
13
+ export type DataSurfaceFieldMetadata = Readonly<Record<string, string | number | boolean | null>>;
14
+ /** A data field plus server-owned visibility policy annotations. */
15
+ export interface DataSurfaceField extends DataQueryFieldDescriptor {
16
+ sensitive?: boolean;
17
+ readPermission?: string;
18
+ metadata?: DataSurfaceFieldMetadata;
19
+ }
20
+ /** Server-owned schema; policy annotations never cross the core query boundary. */
21
+ export interface DataSurfaceSchema extends Omit<DataQuerySchema, 'fields'> {
22
+ fields: DataSurfaceField[];
23
+ }
24
+ /** A server-owned data source. Never construct this from model/tool input. */
25
+ export interface DataSurfaceDefinition {
26
+ /** Stable opaque id presented to the model. */
27
+ id: string;
28
+ /** Permission-catalog collection used for the read gate. */
29
+ collection: string;
30
+ /** Optional backing SMRT class, useful to registry-backed executors. */
31
+ className?: string;
32
+ label?: string;
33
+ description?: string;
34
+ schema: DataSurfaceSchema;
35
+ /** Optional surface-specific executor. */
36
+ execute?: DataSurfaceExecutor;
37
+ }
38
+ export interface DataSurfacePrincipal {
39
+ /** The authenticated execution principal, copied from the live run. */
40
+ userId: string;
41
+ /** The authenticated tenant scope, copied from the live run. */
42
+ tenantId: string | null;
43
+ }
44
+ export interface DataSurfaceExecutionContext {
45
+ run: PrincipalRun;
46
+ principal: DataSurfacePrincipal;
47
+ db?: SmrtClassOptions['db'];
48
+ /** Signal for adapters that can cancel database work. */
49
+ signal: AbortSignal;
50
+ }
51
+ export type DataSurfaceExecutorResult = DataQueryResult | DataQueryRow[] | {
52
+ rows?: DataQueryRow[];
53
+ total?: DataQueryResult['total'];
54
+ facets?: DataQueryResult['facets'];
55
+ freshness?: DataQueryResult['freshness'];
56
+ warnings?: string[];
57
+ truncated?: boolean;
58
+ nextCursor?: string;
59
+ hasMore?: boolean;
60
+ };
61
+ export type DataSurfaceExecutor = (surface: DataSurfaceDefinition, request: DataQueryRequest, context: DataSurfaceExecutionContext) => Promise<DataSurfaceExecutorResult>;
62
+ export interface DataSurfaceAuditEntry {
63
+ action: 'discover' | 'inspect' | 'query';
64
+ surfaceId?: string;
65
+ requestId?: string;
66
+ userId: string;
67
+ tenantId: string | null;
68
+ rowCount?: number;
69
+ truncated?: boolean;
70
+ }
71
+ export type DataSurfaceAuditSink = (entry: DataSurfaceAuditEntry) => void | Promise<void>;
72
+ export interface DataSurfaceToolsOptions {
73
+ /** Server-owned catalog. A function is evaluated per authenticated run. */
74
+ surfaces: readonly DataSurfaceDefinition[] | ((run: PrincipalRun) => readonly DataSurfaceDefinition[] | Promise<readonly DataSurfaceDefinition[]>);
75
+ /** Shared executor used when a definition does not provide one. */
76
+ execute?: DataSurfaceExecutor;
77
+ /** Audit sink for individual tool actions. */
78
+ audit?: DataSurfaceAuditSink;
79
+ /** Deadline for an adapter call. Defaults to five seconds. */
80
+ deadlineMs?: number;
81
+ /** Receives detailed server-side failures; never surfaced to the model. */
82
+ onFailure?: DataSurfaceFailureSink;
83
+ }
84
+ export interface DataSurfaceFailureEntry {
85
+ action: 'discover' | 'inspect' | 'query';
86
+ surfaceId?: string;
87
+ requestId?: string;
88
+ userId: string;
89
+ tenantId: string | null;
90
+ error: unknown;
91
+ }
92
+ export type DataSurfaceFailureSink = (entry: DataSurfaceFailureEntry) => void | Promise<void>;
93
+ export declare class DataSurfaceDeniedError extends Error {
94
+ readonly status = 403;
95
+ constructor();
96
+ }
97
+ export declare class DataSurfaceDeadlineError extends Error {
98
+ readonly status = 504;
99
+ constructor();
100
+ }
101
+ /** Adapter output was not in the requested deterministic order. */
102
+ export declare class DataSurfaceResultOrderError extends Error {
103
+ readonly status = 502;
104
+ constructor();
105
+ }
106
+ /** Stable public failure for executor and result-boundary errors. */
107
+ export declare class DataSurfaceQueryError extends Error {
108
+ readonly status = 502;
109
+ readonly code = "DATA_SURFACE_QUERY_FAILED";
110
+ constructor();
111
+ }
112
+ /** Stable public failure for requests that name hidden schema capabilities. */
113
+ export declare class DataSurfaceRequestError extends Error {
114
+ readonly status = 400;
115
+ readonly code = "DATA_SURFACE_REQUEST_INVALID";
116
+ constructor();
117
+ }
118
+ /**
119
+ * Create the fingerprint for the already-normalized request passed to a
120
+ * surface executor. This supports internal projections beyond core's public
121
+ * 50-field projection limit; callers must use the exact request received.
122
+ */
123
+ export declare function createDataSurfaceQueryFingerprint(request: DataQueryRequest): string;
124
+ /** Build the discover/inspect/query tools for a persona conversation. */
125
+ export declare function createDataSurfaceTools(options: DataSurfaceToolsOptions): PrincipalTool[];
126
+ //# sourceMappingURL=data-surface.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"data-surface.d.ts","sourceRoot":"","sources":["../src/data-surface.ts"],"names":[],"mappings":"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"}
package/dist/index.d.ts CHANGED
@@ -3,6 +3,7 @@ export { getClassConfigResolvers, getConfigResolver, isLazyConfigSentinel, listC
3
3
  export { Agent, type AgentOptions } from './agent.js';
4
4
  export { type AgentAIOptions, type AgentAISecretFallback, resolveAgentAIOptions, } from './ai-config.js';
5
5
  export { AgentConfig, AgentConfigCollection } from './config.js';
6
+ export { createDataSurfaceQueryFingerprint, createDataSurfaceTools, DATA_DISCOVER_FUNCTION_NAME, DATA_DISCOVER_TOOL_SLUG, DATA_INSPECT_FUNCTION_NAME, DATA_INSPECT_TOOL_SLUG, DATA_QUERY_FUNCTION_NAME, DATA_QUERY_TOOL_SLUG, type DataSurfaceAuditEntry, type DataSurfaceAuditSink, DataSurfaceDeadlineError, type DataSurfaceDefinition, DataSurfaceDeniedError, type DataSurfaceExecutionContext, type DataSurfaceExecutor, type DataSurfaceExecutorResult, type DataSurfaceFailureEntry, type DataSurfaceFailureSink, type DataSurfaceField, type DataSurfaceFieldMetadata, type DataSurfacePrincipal, DataSurfaceQueryError, DataSurfaceRequestError, DataSurfaceResultOrderError, type DataSurfaceSchema, type DataSurfaceToolsOptions, DEFAULT_DATA_SURFACE_DEADLINE_MS, MAX_DATA_SURFACE_DEADLINE_MS, } from './data-surface.js';
6
7
  export { assertPrincipalNotWidened, assertWithinDelegationDepth, DelegationDepthExceededError, type DelegationEnvelope, type DeriveDelegationEnvelopeOptions, deriveDelegationEnvelope, MAX_DELEGATION_DEPTH, PrincipalWideningError, type RequestedPrincipal, type RootDelegationEnvelopeOptions, rootDelegationEnvelope, } from './delegation.js';
7
8
  export { type ExecuteAsPrincipalOptions, executeAsPrincipal, type PrincipalAuditEntry, type PrincipalAuditSink, type PrincipalBinding, type PrincipalRun, PrincipalToolNotAllowedError, } from './execute-as-principal.js';
8
9
  export { instanceScopedSubscriber } from './identity.js';
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}