{
  "schemaVersion": 1,
  "sensitiveFieldsExcluded": true,
  "generatedAt": "1970-01-01T00:00:00.000Z",
  "packageName": "@happyvertical/smrt-agents",
  "packageVersion": "0.43.3",
  "sourceManifestPath": "dist/manifest.json",
  "agentDocPath": "AGENTS.md",
  "sourceHashes": {
    "manifest": "915aa2f920998fb74749b386e39795531b92febc6d5ce2f82e456e46f3099f4c",
    "packageJson": "9cbaccdc884484fb5ad5a6ec4bee93b2af83428c6cea0dda239002ea0c0b9a72",
    "agents": "6ce7da109ba71d3e767ee0091d7ac28528c422310f5031f46f65e93814ee0a86"
  },
  "exports": [
    ".",
    "./manifest",
    "./manifest.json",
    "./playground",
    "./server",
    "./svelte",
    "./svelte/admin",
    "./ui",
    "./vite"
  ],
  "dependencies": {
    "@happyvertical/ai": "catalog:",
    "@happyvertical/files": "catalog:",
    "@happyvertical/smrt-config": "workspace:*",
    "@happyvertical/smrt-core": "workspace:*",
    "@happyvertical/smrt-reports": "workspace:*",
    "@happyvertical/smrt-secrets": "workspace:*",
    "@happyvertical/smrt-tenancy": "workspace:*",
    "@happyvertical/smrt-types": "workspace:*",
    "@happyvertical/smrt-ui": "workspace:*",
    "@happyvertical/smrt-users": "workspace:*",
    "@happyvertical/utils": "catalog:",
    "@happyvertical/logger": "catalog:",
    "@happyvertical/smrt-vitest": "workspace:*",
    "@happyvertical/sql": "catalog:",
    "@sentry/node": "catalog:",
    "@sveltejs/package": "^2.5.8",
    "@sveltejs/vite-plugin-svelte": "^7.1.2",
    "@testing-library/svelte": "^5.4.2",
    "@testing-library/user-event": "^14.6.1",
    "@types/node": "24.13.2",
    "fast-glob": "3.3.3",
    "svelte-check": "^4.7.1",
    "svelte": "^5.56.4",
    "typescript": "5.9.3",
    "vite": "8.1.4",
    "vitest": "4.1.10"
  },
  "smrtDependencies": [
    "@happyvertical/smrt-config",
    "@happyvertical/smrt-core",
    "@happyvertical/smrt-reports",
    "@happyvertical/smrt-secrets",
    "@happyvertical/smrt-tenancy",
    "@happyvertical/smrt-types",
    "@happyvertical/smrt-ui",
    "@happyvertical/smrt-users",
    "@happyvertical/smrt-vitest"
  ],
  "sdkDependencies": [
    "@happyvertical/ai",
    "@happyvertical/files",
    "@happyvertical/logger",
    "@happyvertical/sql",
    "@happyvertical/utils"
  ],
  "tags": [],
  "risks": [],
  "objects": [
    {
      "name": "Agent",
      "qualifiedName": "@happyvertical/smrt-agents:Agent",
      "collection": "agents",
      "tableName": "agents",
      "packageName": "@happyvertical/smrt-agents",
      "extends": "SmrtObject",
      "fields": [
        {
          "name": "created_at",
          "type": "datetime",
          "required": false,
          "columnType": "TIMESTAMP"
        },
        {
          "name": "updated_at",
          "type": "datetime",
          "required": false,
          "columnType": "TIMESTAMP"
        },
        {
          "name": "tenantId",
          "type": "text",
          "required": false,
          "columnType": "UUID"
        },
        {
          "name": "status",
          "type": "text",
          "required": false,
          "columnType": "TEXT",
          "default": "idle"
        }
      ],
      "relationships": [],
      "methods": [
        "_setLoadedRelationship",
        "classifyConstraintError",
        "clearEmbeddings",
        "delete",
        "describe",
        "destroy",
        "do",
        "execute",
        "executeToolCall",
        "exportConfig",
        "forget",
        "forgetScope",
        "generateEmbeddings",
        "getAiUsageSnapshot",
        "getAvailableTools",
        "getConfigOwnerId",
        "getDispatch",
        "getDispatchSubscriber",
        "getEmbedding",
        "getFields",
        "getId",
        "getInstanceKey",
        "getLearningMemory",
        "getMergedConfig",
        "getRelated",
        "getSavedId",
        "getSlug",
        "getUISlots",
        "handleDispatch",
        "hasStaleEmbeddings",
        "initialize",
        "interesting",
        "is",
        "isRelatedLoaded",
        "isSaved",
        "listAiUsage",
        "loadConfigs",
        "loadDataFromDb",
        "loadFromId",
        "loadFromSlug",
        "loadRelated",
        "loadRelatedMany",
        "markAsPersisted",
        "processDispatches",
        "recall",
        "recallAll",
        "remember",
        "requireInsertOnSave",
        "resetAiUsage",
        "save",
        "saveSlotConfig",
        "shutdown",
        "summarizeAiUsage",
        "toJSON",
        "toPlainObject",
        "toPublicJSON",
        "validate",
        "withDatabase"
      ],
      "methodSignatures": [
        {
          "name": "_setLoadedRelationship",
          "params": [
            "fieldName: string",
            "value: any"
          ],
          "returns": "void"
        },
        {
          "name": "classifyConstraintError",
          "static": true,
          "params": [
            "message: string"
          ],
          "returns": "'unique' | 'not_null' | null"
        },
        {
          "name": "clearEmbeddings",
          "async": true,
          "returns": "Promise<void>"
        },
        {
          "name": "delete",
          "async": true,
          "returns": "Promise<void>"
        },
        {
          "name": "describe",
          "async": true,
          "params": [
            "options?: AiOperationOptions"
          ],
          "returns": "any"
        },
        {
          "name": "destroy",
          "returns": "void"
        },
        {
          "name": "do",
          "async": true,
          "params": [
            "instructions: string",
            "options?: AiOperationOptions"
          ],
          "returns": "any"
        },
        {
          "name": "execute",
          "async": true,
          "returns": "Promise<void>"
        },
        {
          "name": "executeToolCall",
          "async": true,
          "params": [
            "toolCall: ToolCall"
          ],
          "returns": "Promise<ToolCallResult>"
        },
        {
          "name": "exportConfig",
          "async": true,
          "params": [
            "options?: object"
          ],
          "returns": "Promise<Record<string>>"
        },
        {
          "name": "forget",
          "async": true,
          "params": [
            "options: object"
          ],
          "returns": "Promise<void>"
        },
        {
          "name": "forgetScope",
          "async": true,
          "params": [
            "options: object"
          ],
          "returns": "Promise<number>"
        },
        {
          "name": "generateEmbeddings",
          "async": true,
          "params": [
            "options?: GenerateEmbeddingsOptions"
          ],
          "returns": "Promise<void>"
        },
        {
          "name": "getAiUsageSnapshot",
          "returns": "AiUsageSnapshot | undefined"
        },
        {
          "name": "getAvailableTools",
          "returns": "AITool[]"
        },
        {
          "name": "getConfigOwnerId",
          "params": [
            "slotId?: string"
          ],
          "returns": "string | null"
        },
        {
          "name": "getDispatch",
          "async": true,
          "returns": "Promise<DispatchBus>"
        },
        {
          "name": "getDispatchSubscriber",
          "returns": "string"
        },
        {
          "name": "getEmbedding",
          "async": true,
          "params": [
            "fieldName: string",
            "model?: string"
          ],
          "returns": "Promise<number[] | null>"
        },
        {
          "name": "getFields",
          "async": true,
          "returns": "Promise<any>"
        },
        {
          "name": "getId",
          "async": true,
          "returns": "any"
        },
        {
          "name": "getInstanceKey",
          "returns": "string | null"
        },
        {
          "name": "getLearningMemory",
          "returns": "LearningMemory | null"
        },
        {
          "name": "getMergedConfig",
          "async": true,
          "params": [
            "slotId: string"
          ],
          "returns": "Promise<Record<string>>"
        },
        {
          "name": "getRelated",
          "async": true,
          "params": [
            "fieldName: string",
            "opts?: LoadRelatedOptions"
          ],
          "returns": "Promise<any>"
        },
        {
          "name": "getSavedId",
          "async": true,
          "returns": "any"
        },
        {
          "name": "getSlug",
          "async": true,
          "returns": "any"
        },
        {
          "name": "getUISlots",
          "returns": "AgentUISlots"
        },
        {
          "name": "handleDispatch",
          "async": true,
          "params": [
            "_payload: any",
            "_metadata: DispatchMetadata"
          ],
          "returns": "Promise<void>"
        },
        {
          "name": "hasStaleEmbeddings",
          "async": true,
          "returns": "Promise<boolean>"
        },
        {
          "name": "initialize",
          "async": true,
          "returns": "Promise"
        },
        {
          "name": "interesting",
          "async": true,
          "returns": "Promise<InterestResult[]>"
        },
        {
          "name": "is",
          "async": true,
          "params": [
            "criteria: string",
            "options?: AiOperationOptions"
          ],
          "returns": "any"
        },
        {
          "name": "isRelatedLoaded",
          "params": [
            "fieldName: string"
          ],
          "returns": "boolean"
        },
        {
          "name": "isSaved",
          "async": true,
          "returns": "any"
        },
        {
          "name": "listAiUsage",
          "async": true,
          "params": [
            "options?: AiUsageListOptions"
          ],
          "returns": "Promise<SmrtAiUsageRecord[]>"
        },
        {
          "name": "loadConfigs",
          "async": true,
          "returns": "Promise<Map<string, Record<string>>>"
        },
        {
          "name": "loadDataFromDb",
          "async": true,
          "params": [
            "data: Record<string>"
          ],
          "returns": "any"
        },
        {
          "name": "loadFromId",
          "async": true,
          "returns": "any"
        },
        {
          "name": "loadFromSlug",
          "async": true,
          "returns": "any"
        },
        {
          "name": "loadRelated",
          "async": true,
          "params": [
            "fieldName: string",
            "opts?: LoadRelatedOptions"
          ],
          "returns": "Promise<any>"
        },
        {
          "name": "loadRelatedMany",
          "async": true,
          "params": [
            "fieldName: string",
            "opts?: LoadRelatedOptions"
          ],
          "returns": "Promise<any[]>"
        },
        {
          "name": "markAsPersisted",
          "returns": "void"
        },
        {
          "name": "processDispatches",
          "async": true,
          "returns": "Promise<number>"
        },
        {
          "name": "recall",
          "async": true,
          "params": [
            "options: object"
          ],
          "returns": "Promise"
        },
        {
          "name": "recallAll",
          "async": true,
          "params": [
            "options?: object"
          ],
          "returns": "Promise<Map<string>>"
        },
        {
          "name": "remember",
          "async": true,
          "params": [
            "options: object"
          ],
          "returns": "Promise<void>"
        },
        {
          "name": "requireInsertOnSave",
          "returns": "void"
        },
        {
          "name": "resetAiUsage",
          "returns": "void"
        },
        {
          "name": "save",
          "async": true,
          "returns": "any"
        },
        {
          "name": "saveSlotConfig",
          "async": true,
          "params": [
            "slotId: string",
            "data: Record<string>"
          ],
          "returns": "Promise<void>"
        },
        {
          "name": "shutdown",
          "async": true,
          "returns": "Promise<void>"
        },
        {
          "name": "summarizeAiUsage",
          "async": true,
          "params": [
            "options?: AiUsageSummaryOptions"
          ],
          "returns": "Promise<Record<string, AiUsageStats>>"
        },
        {
          "name": "toJSON",
          "returns": "any"
        },
        {
          "name": "toPlainObject",
          "returns": "Record<string>"
        },
        {
          "name": "toPublicJSON",
          "params": [
            "options?: PublicJsonOptions"
          ],
          "returns": "Record<string>"
        },
        {
          "name": "validate",
          "async": true,
          "returns": "Promise<void>"
        },
        {
          "name": "withDatabase",
          "async": true,
          "params": [
            "db: DatabaseInterface",
            "operation: Function"
          ],
          "returns": "Promise<T>"
        }
      ],
      "tenant": {
        "scoped": true,
        "mode": "optional",
        "field": "tenantId"
      },
      "tableStrategy": "sti",
      "conflictColumns": [
        "tenant_id",
        "slug",
        "context",
        "_meta_type"
      ],
      "surfaces": [],
      "relationshipFeatures": [
        "uuidColumns"
      ],
      "tags": [],
      "risks": []
    },
    {
      "name": "AgentConfig",
      "qualifiedName": "@happyvertical/smrt-agents:AgentConfig",
      "collection": "agentconfigs",
      "tableName": "agent_configs",
      "packageName": "@happyvertical/smrt-agents",
      "extends": "SmrtObject",
      "fields": [
        {
          "name": "tenantId",
          "type": "text",
          "required": false,
          "columnType": "UUID"
        },
        {
          "name": "agentId",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "agentClass",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "slotId",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "schemaVersion",
          "type": "integer",
          "required": false,
          "columnType": "INTEGER"
        }
      ],
      "relationships": [],
      "methods": [
        "forAgent",
        "forAgents",
        "forSlot",
        "saveSlot"
      ],
      "methodSignatures": [
        {
          "name": "forAgent",
          "async": true,
          "static": true,
          "params": [
            "agentId: string",
            "options: SmrtClassOptions"
          ],
          "returns": "Promise<Map<string, Record<string>>>"
        },
        {
          "name": "forAgents",
          "async": true,
          "static": true,
          "params": [
            "agentIds: string[]",
            "options: SmrtClassOptions"
          ],
          "returns": "Promise<Map<string, Map<string, Record<string>>>>"
        },
        {
          "name": "forSlot",
          "async": true,
          "static": true,
          "params": [
            "agentId: string",
            "slotId: string",
            "options: SmrtClassOptions"
          ],
          "returns": "Promise<Record<string> | undefined>"
        },
        {
          "name": "saveSlot",
          "async": true,
          "static": true,
          "params": [
            "data: object",
            "options: SmrtClassOptions"
          ],
          "returns": "Promise<AgentConfig>"
        }
      ],
      "tenant": {
        "scoped": true,
        "mode": "optional",
        "field": "tenantId"
      },
      "conflictColumns": [
        "tenant_id",
        "slug",
        "context"
      ],
      "surfaces": [
        {
          "kind": "api",
          "name": "agentconfigs.list",
          "operation": "list",
          "objectName": "@happyvertical/smrt-agents:AgentConfig",
          "path": "/agentconfigs",
          "method": "GET"
        },
        {
          "kind": "api",
          "name": "agentconfigs.get",
          "operation": "get",
          "objectName": "@happyvertical/smrt-agents:AgentConfig",
          "path": "/agentconfigs/[id]",
          "method": "GET"
        },
        {
          "kind": "api",
          "name": "agentconfigs.create",
          "operation": "create",
          "objectName": "@happyvertical/smrt-agents:AgentConfig",
          "path": "/agentconfigs",
          "method": "POST"
        },
        {
          "kind": "api",
          "name": "agentconfigs.update",
          "operation": "update",
          "objectName": "@happyvertical/smrt-agents:AgentConfig",
          "path": "/agentconfigs/[id]",
          "method": "PATCH"
        },
        {
          "kind": "api",
          "name": "agentconfigs.delete",
          "operation": "delete",
          "objectName": "@happyvertical/smrt-agents:AgentConfig",
          "path": "/agentconfigs/[id]",
          "method": "DELETE"
        },
        {
          "kind": "cli",
          "name": "agentconfig_list",
          "operation": "list",
          "objectName": "@happyvertical/smrt-agents:AgentConfig"
        },
        {
          "kind": "cli",
          "name": "agentconfig_get",
          "operation": "get",
          "objectName": "@happyvertical/smrt-agents:AgentConfig"
        },
        {
          "kind": "cli",
          "name": "agentconfig_create",
          "operation": "create",
          "objectName": "@happyvertical/smrt-agents:AgentConfig"
        },
        {
          "kind": "cli",
          "name": "agentconfig_update",
          "operation": "update",
          "objectName": "@happyvertical/smrt-agents:AgentConfig"
        },
        {
          "kind": "cli",
          "name": "agentconfig_delete",
          "operation": "delete",
          "objectName": "@happyvertical/smrt-agents:AgentConfig"
        },
        {
          "kind": "mcp",
          "name": "agentconfig_list",
          "operation": "list",
          "objectName": "@happyvertical/smrt-agents:AgentConfig"
        },
        {
          "kind": "mcp",
          "name": "agentconfig_get",
          "operation": "get",
          "objectName": "@happyvertical/smrt-agents:AgentConfig"
        }
      ],
      "relationshipFeatures": [
        "uuidColumns"
      ],
      "tags": [],
      "risks": []
    },
    {
      "name": "AgentConfigCollection",
      "qualifiedName": "@happyvertical/smrt-agents:AgentConfigCollection",
      "collection": "agentconfigs",
      "tableName": "agent_configs",
      "packageName": "@happyvertical/smrt-agents",
      "extends": "SmrtCollection",
      "fields": [],
      "relationships": [],
      "methods": [
        "findByTenant",
        "findGlobal",
        "findWithGlobals"
      ],
      "methodSignatures": [
        {
          "name": "findByTenant",
          "async": true,
          "params": [
            "tenantId: string"
          ],
          "returns": "Promise<AgentConfig[]>"
        },
        {
          "name": "findGlobal",
          "async": true,
          "returns": "Promise<AgentConfig[]>"
        },
        {
          "name": "findWithGlobals",
          "async": true,
          "params": [
            "tenantId: string"
          ],
          "returns": "Promise<AgentConfig[]>"
        }
      ],
      "surfaces": [],
      "relationshipFeatures": [
        "uuidColumns"
      ],
      "tags": [],
      "risks": []
    },
    {
      "name": "AgentSchedule",
      "qualifiedName": "@happyvertical/smrt-agents:AgentSchedule",
      "collection": "agentschedules",
      "tableName": "_smrt_agent_schedules",
      "packageName": "@happyvertical/smrt-agents",
      "extends": "SmrtObject",
      "fields": [
        {
          "name": "tenantId",
          "type": "text",
          "required": false,
          "columnType": "UUID"
        },
        {
          "name": "agentType",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "agentId",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "cron",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "timezone",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "enabled",
          "type": "boolean",
          "required": false,
          "columnType": "BOOLEAN"
        },
        {
          "name": "status",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "lastRun",
          "type": "datetime",
          "required": false,
          "columnType": "TIMESTAMP"
        },
        {
          "name": "nextRun",
          "type": "datetime",
          "required": false,
          "columnType": "TIMESTAMP"
        },
        {
          "name": "lastStatus",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "lastError",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "runCount",
          "type": "integer",
          "required": false,
          "columnType": "INTEGER"
        },
        {
          "name": "successCount",
          "type": "integer",
          "required": false,
          "columnType": "INTEGER"
        },
        {
          "name": "failureCount",
          "type": "integer",
          "required": false,
          "columnType": "INTEGER"
        },
        {
          "name": "maxConcurrent",
          "type": "integer",
          "required": false,
          "columnType": "INTEGER"
        },
        {
          "name": "runningCount",
          "type": "integer",
          "required": false,
          "columnType": "INTEGER"
        },
        {
          "name": "timeout",
          "type": "integer",
          "required": false,
          "columnType": "INTEGER"
        },
        {
          "name": "method",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "methodArgs",
          "type": "json",
          "required": false,
          "columnType": "TEXT"
        }
      ],
      "relationships": [],
      "methods": [
        "beforeSave",
        "calculateNextRun",
        "disable",
        "enable",
        "getDescription",
        "pause",
        "resume"
      ],
      "methodSignatures": [
        {
          "name": "beforeSave",
          "async": true,
          "returns": "Promise<void>"
        },
        {
          "name": "calculateNextRun",
          "returns": "void"
        },
        {
          "name": "disable",
          "async": true,
          "returns": "Promise<void>"
        },
        {
          "name": "enable",
          "async": true,
          "returns": "Promise<void>"
        },
        {
          "name": "getDescription",
          "returns": "string"
        },
        {
          "name": "pause",
          "async": true,
          "returns": "Promise<void>"
        },
        {
          "name": "resume",
          "async": true,
          "returns": "Promise<void>"
        }
      ],
      "tenant": {
        "scoped": true,
        "mode": "optional",
        "field": "tenantId"
      },
      "conflictColumns": [
        "tenant_id",
        "slug",
        "context"
      ],
      "surfaces": [
        {
          "kind": "api",
          "name": "agentschedules.list",
          "operation": "list",
          "objectName": "@happyvertical/smrt-agents:AgentSchedule",
          "path": "/agentschedules",
          "method": "GET"
        },
        {
          "kind": "api",
          "name": "agentschedules.get",
          "operation": "get",
          "objectName": "@happyvertical/smrt-agents:AgentSchedule",
          "path": "/agentschedules/[id]",
          "method": "GET"
        },
        {
          "kind": "api",
          "name": "agentschedules.create",
          "operation": "create",
          "objectName": "@happyvertical/smrt-agents:AgentSchedule",
          "path": "/agentschedules",
          "method": "POST"
        },
        {
          "kind": "api",
          "name": "agentschedules.update",
          "operation": "update",
          "objectName": "@happyvertical/smrt-agents:AgentSchedule",
          "path": "/agentschedules/[id]",
          "method": "PATCH"
        },
        {
          "kind": "api",
          "name": "agentschedules.delete",
          "operation": "delete",
          "objectName": "@happyvertical/smrt-agents:AgentSchedule",
          "path": "/agentschedules/[id]",
          "method": "DELETE"
        },
        {
          "kind": "cli",
          "name": "agentschedule_list",
          "operation": "list",
          "objectName": "@happyvertical/smrt-agents:AgentSchedule"
        },
        {
          "kind": "cli",
          "name": "agentschedule_get",
          "operation": "get",
          "objectName": "@happyvertical/smrt-agents:AgentSchedule"
        },
        {
          "kind": "cli",
          "name": "agentschedule_create",
          "operation": "create",
          "objectName": "@happyvertical/smrt-agents:AgentSchedule"
        },
        {
          "kind": "cli",
          "name": "agentschedule_update",
          "operation": "update",
          "objectName": "@happyvertical/smrt-agents:AgentSchedule"
        },
        {
          "kind": "cli",
          "name": "agentschedule_delete",
          "operation": "delete",
          "objectName": "@happyvertical/smrt-agents:AgentSchedule"
        },
        {
          "kind": "cli",
          "name": "agentschedule_enable",
          "operation": "enable",
          "objectName": "@happyvertical/smrt-agents:AgentSchedule"
        },
        {
          "kind": "cli",
          "name": "agentschedule_disable",
          "operation": "disable",
          "objectName": "@happyvertical/smrt-agents:AgentSchedule"
        },
        {
          "kind": "mcp",
          "name": "agentschedule_list",
          "operation": "list",
          "objectName": "@happyvertical/smrt-agents:AgentSchedule"
        },
        {
          "kind": "mcp",
          "name": "agentschedule_get",
          "operation": "get",
          "objectName": "@happyvertical/smrt-agents:AgentSchedule"
        }
      ],
      "relationshipFeatures": [
        "uuidColumns"
      ],
      "tags": [],
      "risks": []
    },
    {
      "name": "AgentScheduleCollection",
      "qualifiedName": "@happyvertical/smrt-agents:AgentScheduleCollection",
      "collection": "agentschedules",
      "tableName": "_smrt_agent_schedules",
      "packageName": "@happyvertical/smrt-agents",
      "extends": "SmrtCollection",
      "fields": [],
      "relationships": [],
      "methods": [
        "findByTenant",
        "findGlobal",
        "findWithGlobals",
        "listByAgentType",
        "listByStatus"
      ],
      "methodSignatures": [
        {
          "name": "findByTenant",
          "async": true,
          "params": [
            "tenantId: string"
          ],
          "returns": "Promise<AgentSchedule[]>"
        },
        {
          "name": "findGlobal",
          "async": true,
          "returns": "Promise<AgentSchedule[]>"
        },
        {
          "name": "findWithGlobals",
          "async": true,
          "params": [
            "tenantId: string"
          ],
          "returns": "Promise<AgentSchedule[]>"
        },
        {
          "name": "listByAgentType",
          "async": true,
          "params": [
            "agentType: string",
            "options?: object"
          ],
          "returns": "Promise<AgentSchedule[]>"
        },
        {
          "name": "listByStatus",
          "async": true,
          "params": [
            "status: ScheduleStatus | ScheduleStatus[]",
            "options?: object"
          ],
          "returns": "Promise<AgentSchedule[]>"
        }
      ],
      "surfaces": [],
      "relationshipFeatures": [
        "uuidColumns"
      ],
      "tags": [],
      "risks": []
    },
    {
      "name": "TenantAgent",
      "qualifiedName": "@happyvertical/smrt-agents:TenantAgent",
      "collection": "tenantagents",
      "tableName": "tenant_agents",
      "packageName": "@happyvertical/smrt-agents",
      "extends": "SmrtObject",
      "fields": [
        {
          "name": "tenantId",
          "type": "text",
          "required": true,
          "columnType": "UUID"
        },
        {
          "name": "agentClass",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "status",
          "type": "text",
          "required": false,
          "columnType": "TEXT"
        },
        {
          "name": "permissions",
          "type": "json",
          "required": false,
          "columnType": "JSON"
        }
      ],
      "relationships": [],
      "methods": [],
      "tenant": {
        "scoped": true,
        "mode": "required",
        "field": "tenantId"
      },
      "conflictColumns": [
        "tenant_id",
        "agent_class"
      ],
      "surfaces": [
        {
          "kind": "api",
          "name": "tenantagents.list",
          "operation": "list",
          "objectName": "@happyvertical/smrt-agents:TenantAgent",
          "path": "/tenantagents",
          "method": "GET"
        },
        {
          "kind": "api",
          "name": "tenantagents.get",
          "operation": "get",
          "objectName": "@happyvertical/smrt-agents:TenantAgent",
          "path": "/tenantagents/[id]",
          "method": "GET"
        },
        {
          "kind": "api",
          "name": "tenantagents.create",
          "operation": "create",
          "objectName": "@happyvertical/smrt-agents:TenantAgent",
          "path": "/tenantagents",
          "method": "POST"
        },
        {
          "kind": "api",
          "name": "tenantagents.update",
          "operation": "update",
          "objectName": "@happyvertical/smrt-agents:TenantAgent",
          "path": "/tenantagents/[id]",
          "method": "PATCH"
        },
        {
          "kind": "api",
          "name": "tenantagents.delete",
          "operation": "delete",
          "objectName": "@happyvertical/smrt-agents:TenantAgent",
          "path": "/tenantagents/[id]",
          "method": "DELETE"
        },
        {
          "kind": "cli",
          "name": "tenantagent_list",
          "operation": "list",
          "objectName": "@happyvertical/smrt-agents:TenantAgent"
        },
        {
          "kind": "cli",
          "name": "tenantagent_get",
          "operation": "get",
          "objectName": "@happyvertical/smrt-agents:TenantAgent"
        },
        {
          "kind": "mcp",
          "name": "tenantagent_list",
          "operation": "list",
          "objectName": "@happyvertical/smrt-agents:TenantAgent"
        },
        {
          "kind": "mcp",
          "name": "tenantagent_get",
          "operation": "get",
          "objectName": "@happyvertical/smrt-agents:TenantAgent"
        }
      ],
      "relationshipFeatures": [
        "uuidColumns"
      ],
      "tags": [],
      "risks": []
    },
    {
      "name": "TenantAgentCollection",
      "qualifiedName": "@happyvertical/smrt-agents:TenantAgentCollection",
      "collection": "tenantagents",
      "tableName": "tenant_agents",
      "packageName": "@happyvertical/smrt-agents",
      "extends": "SmrtCollection",
      "fields": [],
      "relationships": [],
      "methods": [
        "clearOverride",
        "disableAgent",
        "enableAgent",
        "findByTenantAndClass",
        "resolveForTenant",
        "setPermissions"
      ],
      "methodSignatures": [
        {
          "name": "clearOverride",
          "async": true,
          "params": [
            "tenantId: string",
            "agentClass: string"
          ],
          "returns": "Promise<void>"
        },
        {
          "name": "disableAgent",
          "async": true,
          "params": [
            "tenantId: string",
            "agentClass: string"
          ],
          "returns": "Promise<TenantAgent>"
        },
        {
          "name": "enableAgent",
          "async": true,
          "params": [
            "tenantId: string",
            "agentClass: string"
          ],
          "returns": "Promise<TenantAgent>"
        },
        {
          "name": "findByTenantAndClass",
          "async": true,
          "params": [
            "tenantId: string",
            "agentClass: string"
          ],
          "returns": "Promise<TenantAgent | null>"
        },
        {
          "name": "resolveForTenant",
          "async": true,
          "params": [
            "tenantId: string",
            "getAncestorIds: Function",
            "manifests?: Map<string, AgentManifestInfo>"
          ],
          "returns": "Promise<ResolvedAgentAvailability[]>"
        },
        {
          "name": "setPermissions",
          "async": true,
          "params": [
            "tenantId: string",
            "agentClass: string",
            "permissions: Record<string, boolean>"
          ],
          "returns": "Promise<TenantAgent>"
        }
      ],
      "surfaces": [],
      "relationshipFeatures": [
        "uuidColumns"
      ],
      "tags": [],
      "risks": []
    }
  ],
  "surfaces": [
    {
      "kind": "api",
      "name": "agentconfigs.list",
      "operation": "list",
      "objectName": "@happyvertical/smrt-agents:AgentConfig",
      "path": "/agentconfigs",
      "method": "GET"
    },
    {
      "kind": "api",
      "name": "agentconfigs.get",
      "operation": "get",
      "objectName": "@happyvertical/smrt-agents:AgentConfig",
      "path": "/agentconfigs/[id]",
      "method": "GET"
    },
    {
      "kind": "api",
      "name": "agentconfigs.create",
      "operation": "create",
      "objectName": "@happyvertical/smrt-agents:AgentConfig",
      "path": "/agentconfigs",
      "method": "POST"
    },
    {
      "kind": "api",
      "name": "agentconfigs.update",
      "operation": "update",
      "objectName": "@happyvertical/smrt-agents:AgentConfig",
      "path": "/agentconfigs/[id]",
      "method": "PATCH"
    },
    {
      "kind": "api",
      "name": "agentconfigs.delete",
      "operation": "delete",
      "objectName": "@happyvertical/smrt-agents:AgentConfig",
      "path": "/agentconfigs/[id]",
      "method": "DELETE"
    },
    {
      "kind": "cli",
      "name": "agentconfig_list",
      "operation": "list",
      "objectName": "@happyvertical/smrt-agents:AgentConfig"
    },
    {
      "kind": "cli",
      "name": "agentconfig_get",
      "operation": "get",
      "objectName": "@happyvertical/smrt-agents:AgentConfig"
    },
    {
      "kind": "cli",
      "name": "agentconfig_create",
      "operation": "create",
      "objectName": "@happyvertical/smrt-agents:AgentConfig"
    },
    {
      "kind": "cli",
      "name": "agentconfig_update",
      "operation": "update",
      "objectName": "@happyvertical/smrt-agents:AgentConfig"
    },
    {
      "kind": "cli",
      "name": "agentconfig_delete",
      "operation": "delete",
      "objectName": "@happyvertical/smrt-agents:AgentConfig"
    },
    {
      "kind": "mcp",
      "name": "agentconfig_list",
      "operation": "list",
      "objectName": "@happyvertical/smrt-agents:AgentConfig"
    },
    {
      "kind": "mcp",
      "name": "agentconfig_get",
      "operation": "get",
      "objectName": "@happyvertical/smrt-agents:AgentConfig"
    },
    {
      "kind": "api",
      "name": "agentschedules.list",
      "operation": "list",
      "objectName": "@happyvertical/smrt-agents:AgentSchedule",
      "path": "/agentschedules",
      "method": "GET"
    },
    {
      "kind": "api",
      "name": "agentschedules.get",
      "operation": "get",
      "objectName": "@happyvertical/smrt-agents:AgentSchedule",
      "path": "/agentschedules/[id]",
      "method": "GET"
    },
    {
      "kind": "api",
      "name": "agentschedules.create",
      "operation": "create",
      "objectName": "@happyvertical/smrt-agents:AgentSchedule",
      "path": "/agentschedules",
      "method": "POST"
    },
    {
      "kind": "api",
      "name": "agentschedules.update",
      "operation": "update",
      "objectName": "@happyvertical/smrt-agents:AgentSchedule",
      "path": "/agentschedules/[id]",
      "method": "PATCH"
    },
    {
      "kind": "api",
      "name": "agentschedules.delete",
      "operation": "delete",
      "objectName": "@happyvertical/smrt-agents:AgentSchedule",
      "path": "/agentschedules/[id]",
      "method": "DELETE"
    },
    {
      "kind": "cli",
      "name": "agentschedule_list",
      "operation": "list",
      "objectName": "@happyvertical/smrt-agents:AgentSchedule"
    },
    {
      "kind": "cli",
      "name": "agentschedule_get",
      "operation": "get",
      "objectName": "@happyvertical/smrt-agents:AgentSchedule"
    },
    {
      "kind": "cli",
      "name": "agentschedule_create",
      "operation": "create",
      "objectName": "@happyvertical/smrt-agents:AgentSchedule"
    },
    {
      "kind": "cli",
      "name": "agentschedule_update",
      "operation": "update",
      "objectName": "@happyvertical/smrt-agents:AgentSchedule"
    },
    {
      "kind": "cli",
      "name": "agentschedule_delete",
      "operation": "delete",
      "objectName": "@happyvertical/smrt-agents:AgentSchedule"
    },
    {
      "kind": "cli",
      "name": "agentschedule_enable",
      "operation": "enable",
      "objectName": "@happyvertical/smrt-agents:AgentSchedule"
    },
    {
      "kind": "cli",
      "name": "agentschedule_disable",
      "operation": "disable",
      "objectName": "@happyvertical/smrt-agents:AgentSchedule"
    },
    {
      "kind": "mcp",
      "name": "agentschedule_list",
      "operation": "list",
      "objectName": "@happyvertical/smrt-agents:AgentSchedule"
    },
    {
      "kind": "mcp",
      "name": "agentschedule_get",
      "operation": "get",
      "objectName": "@happyvertical/smrt-agents:AgentSchedule"
    },
    {
      "kind": "api",
      "name": "tenantagents.list",
      "operation": "list",
      "objectName": "@happyvertical/smrt-agents:TenantAgent",
      "path": "/tenantagents",
      "method": "GET"
    },
    {
      "kind": "api",
      "name": "tenantagents.get",
      "operation": "get",
      "objectName": "@happyvertical/smrt-agents:TenantAgent",
      "path": "/tenantagents/[id]",
      "method": "GET"
    },
    {
      "kind": "api",
      "name": "tenantagents.create",
      "operation": "create",
      "objectName": "@happyvertical/smrt-agents:TenantAgent",
      "path": "/tenantagents",
      "method": "POST"
    },
    {
      "kind": "api",
      "name": "tenantagents.update",
      "operation": "update",
      "objectName": "@happyvertical/smrt-agents:TenantAgent",
      "path": "/tenantagents/[id]",
      "method": "PATCH"
    },
    {
      "kind": "api",
      "name": "tenantagents.delete",
      "operation": "delete",
      "objectName": "@happyvertical/smrt-agents:TenantAgent",
      "path": "/tenantagents/[id]",
      "method": "DELETE"
    },
    {
      "kind": "cli",
      "name": "tenantagent_list",
      "operation": "list",
      "objectName": "@happyvertical/smrt-agents:TenantAgent"
    },
    {
      "kind": "cli",
      "name": "tenantagent_get",
      "operation": "get",
      "objectName": "@happyvertical/smrt-agents:TenantAgent"
    },
    {
      "kind": "mcp",
      "name": "tenantagent_list",
      "operation": "list",
      "objectName": "@happyvertical/smrt-agents:TenantAgent"
    },
    {
      "kind": "mcp",
      "name": "tenantagent_get",
      "operation": "get",
      "objectName": "@happyvertical/smrt-agents:TenantAgent"
    }
  ],
  "prompts": [],
  "relationshipsV2": {
    "foreignKeyFields": 0,
    "crossPackageRefFields": 0,
    "junctionCollections": 0,
    "hierarchicalObjects": 0,
    "polymorphicAssociations": 0,
    "uuidColumns": 11
  },
  "agentDoc": "# @happyvertical/smrt-agents\n\nAgent framework for autonomous actors with inter-agent messaging, interest-based object discovery, scheduling, and multi-tenant bindings.\n\n## Agent Lifecycle\n\n`initialize()` → `validate()` → `run()` → `shutdown()`\n\n- Extend `Agent` (which extends `SmrtObject`) and implement `run()`\n- Status tracking: `idle → initializing → running → error/shutdown`\n- `execute()` runs the full lifecycle automatically\n- Process signal handling is opt-in via `manageProcessSignals: true` and is intended for single-agent processes\n\n## DispatchBus — Inter-Agent Communication\n\nAgents communicate via persistent async messaging through core's DispatchBus:\n\n```typescript\n// Emitting (in any agent)\nconst bus = await this.getDispatch();\nawait bus.emit('campaign.completed', { campaignId: '123' }, { source: 'Suasor' });\n\n// Subscribing (in receiving agent)\nasync handleDispatch(payload: unknown, metadata: DispatchMetadata): Promise<void> {\n  if (metadata.type === 'campaign.completed') await this.recordRevenue(payload);\n}\nasync run() { await this.processDispatches(); } // processes via handleDispatch()\n```\n\nCLI: `smrt dispatch:list`, `dispatch:process --subscriber Fiscus`, `dispatch:retry`, `dispatch:cleanup`\n\n## Interests — Object Discovery\n\nAgents query objects they care about via declarative filters:\n\n```typescript\nconstructor(options) {\n  super({ ...options, interests: {\n    objects: { Meeting: { filter: { status: 'upcoming' }, handler: async (m) => ({ action: 'recap' }) } },\n    qualify: async (items) => items.filter(/* AI-based post-filter */),\n  }});\n}\nasync run() { for (const { type, data } of await this.interesting()) { ... } }\n```\n\n## Configuration\n\n- **File-based**: `getModuleConfig('agent-name', defaults)` from `smrt.config.ts`\n- **DB-persisted**: `saveSlotConfig(slotId, data)` for UI overrides. Persona-backed\n  agents use `AgentOptions.personaId` as the durable config owner; legacy agents\n  use the saved Agent row id.\n- **Merged**: `getMergedConfig('slotId')` — DB overrides file config\n- **UI slots**: `static uiSlots` declares admin panels (id, label, icon, order,\n  `scope`, optional versioned `settingsSchema`). Without a registered custom\n  component, `AgentSettingsForm` renders that schema.\n\n## TenantAgent — Multi-Tenant Bindings\n\nJunction table (`tenant_agents`) binding agents to tenants with permission overrides and hierarchy resolution:\n- Explicit binding: row exists for tenant (source: 'explicit')\n- Inherited: walks up tenant hierarchy (source: 'inherited')\n- Permissions: manifest defaults merged with per-tenant overrides\n\n## AgentSchedule\n\nCron-based scheduling stored in `_smrt_agent_schedules`. Fields: `agentType`, `cron`, `method` (default: 'run'), `maxConcurrent`, `timeout`. Executed by ScheduleRunner from smrt-jobs.\n\n## Lazy agent_config Resolution (issue #1161)\n\nPersisted `agent_config` snapshots env-derived values at sync time, so rotated env vars don't reach already-stored schedule rows. Two complementary mechanisms unfreeze them:\n\n1. **`$env` sentinels in persisted config** — register a global resolver and reference it from the JSON:\n\n   ```ts\n   import { registerConfigResolver } from '@happyvertical/smrt-agents';\n   registerConfigResolver('sharedAssetStorage', () => resolveSharedAssetStorage());\n   // persisted: { \"assetStorage\": { \"$env\": \"sharedAssetStorage\" } }\n   ```\n\n2. **`static configResolvers` on the agent class** — declarative, discoverable via the class itself:\n\n   ```ts\n   class Praeco extends Agent {\n     static override configResolvers = {\n       assetStorage: () => resolveSharedAssetStorage(),\n     };\n   }\n   ```\n\nThe TaskRunner calls `resolveLazyConfig()` immediately before constructing the agent, so live values always win over snapshotted ones. Re-exported from `@happyvertical/smrt-core` (`resolveLazyConfig`, `registerConfigResolver`, `getClassConfigResolvers`, …) for cases where agents isn't on the import path.\n\n## Learning Trait (issue #1886) — opt-in\n\nAny agent can opt into a confidence-scored **recall-before / capture-after** loop backed by core's `LearningMemory` (over `_smrt_contexts` + `_smrt_embeddings`). **Off by default** — a non-opted agent behaves byte-for-byte as today; the lifecycle's learning branches are never entered.\n\n```typescript\n@smrt()\nclass InvoiceAgent extends Agent {\n  static override learning = true; // or { minConfidence: 0.8, scope: 'invoices', ... }\n  protected config = {};\n\n  async run() {\n    // recall-before-run already populated `recalledMemories` (confidence >= floor)\n    const cached = this.recalledMemories.find((m) => m.key === this.docUrl);\n    const strategy = cached?.value ?? (await this.generateStrategy());\n\n    // stage the episode; the lifecycle reinforces it after run()\n    this.stageLearning({ scope: this.learningScope(), key: this.docUrl, value: strategy });\n\n    // a validated failure decays the memory without throwing\n    if (!ok) this.reportLearningOutcome({ success: false, error: 'no match' });\n  }\n}\n```\n\n- **`capture` semantics** (`LearningMemory`): success strengthens `confidence` toward 1.0 and increments `success_count`; failure decays toward `failureConfidence` (0.3) and increments `failure_count`. A single failure drops a confident memory below the reuse floor (0.7), so recall stops returning it. Refreshes `last_used_at`; honours `expires_at` and optional time-decay.\n- **Memory isolation**: bound to `(agentType, agentInstanceId)` as `(owner_class, owner_id)`, so two tenants on the same agent class never share memory. `tenantId` is threaded into the optional semantic-search `where`.\n- **Seams to override**: `learningScope()`, `recallForRun(memory)`, `captureForRun(memory, outcome)`, `getLearningSemanticSearch()`. Helpers for `run()`: `stageLearning(episode)`, `reportLearningOutcome(outcome)`, `getLearningMemory()`, and the `recalledMemories` field.\n- **Config**: `static learning: boolean | AgentLearningConfig` — `{ enabled?, scope?, minConfidence?, successConfidence?, failureConfidence?, reinforcement?, decayHalfLifeMs? }`. `LearningMemory` and its types are re-exported from `@happyvertical/smrt-core`.\n\n## Multi-Instance Agents (issue #1890) — opt-in\n\n`static multiInstance = false` by default: a class is a **singleton** (the N=1 case) and is byte-for-byte unchanged — one dispatch subscriber keyed by the agent type, one memory scope, class-wide interests. Set `static multiInstance = true` to run N durable instances (personas, from `@happyvertical/smrt-personas`) of one class per tenant, each independent.\n\nThe framework provides only the per-instance **identity**; a package scopes its own dispatch/interests to the instance's config by overriding the seams.\n\n- **`AgentOptions.personaId`** — durable persona/settings identity, including\n  the default persona. Independent from execution instance identity.\n- **`AgentOptions.instanceKey`** — the durable execution-instance key (typically\n  the persona id, but null for the default persona). Honored **only** when\n  `multiInstance` is true, so passing it to a non-opted agent is a no-op.\n- **`getInstanceKey()`** → the key, or `null` for a singleton (opt-in off, or no key).\n- **`getDispatchSubscriber()`** → `` `${agentType}#${key}` `` for a multi-instance agent, the bare `agentType` for a singleton. Used everywhere the agent subscribes/seeds/processes, so each instance has its own subscription rows and pending-dispatch queue — two instances never compete for or double-process each other's dispatches. Composed by the exported `instanceScopedSubscriber(agentType, key)`.\n- **`learningScope()`** — suffixed with `#<key>` for a multi-instance agent, so instances learn independently (singleton scope unchanged).\n- **Seams to override** (both default to singleton behavior):\n  - `resolveSignalSubscriptions()` — derive **instance-scoped** signal types from the instance config so an emit meant for one instance only matches its subscription.\n  - `instanceInterestFilter()` — an `ObjectFilter` AND-merged (as the base layer) into every `interesting()` query so instances partition the objects they process.\n\nThe **`default` persona reuses the singleton identity** (a `null` key), which is what makes the singleton→multi upgrade non-destructive — see `@happyvertical/smrt-personas` (`personaInstanceKey`, `upgradeSingletonToDefaultPersona`).\n\n## Principal Execution (issue #1888)\n\n`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`.\n\n## Data Surface Read Tools (issue #2447)\n\n`createDataSurfaceTools()` produces the `data.discover`, `data.inspect`, and\n`data.query` `PrincipalTool`s consumed through chat's `extraTools` seam. The\ncaller supplies a server-owned surface catalog and executor; the tools copy\n`userId`, `tenantId`, database, and permissions only from the live\n`PrincipalRun`. Discovery and inspection first assert the collection's read\ncatalog permission and omit denied surfaces/fields. Query requests and results\nare normalized with the core bounded data-query protocol, including projection,\ncursor/page, row/byte, fingerprint, freshness, total, and truncation rules.\nSensitive/read-permission fields are removed from descriptors, and\n`DataSurfaceField` policy metadata is stripped before the core schema validator.\nExecutor-provided paginated rows retain their order and are validated with a\nstable identity tie-breaker (including type-aware numeric/date comparisons),\nwhile internal sort keys are stripped when they were not requested in the\nprojection. Execution has a bounded deadline; public executor/result failures\nuse stable generic errors while optional `onFailure` telemetry receives the\nauthenticated/delegated principal and detailed server-side error. Hidden field\nrequest failures also use a stable public error. Tool arguments never contain\nprincipal or tenant authority.\n\n## Report Data-Surface Tools (issue #2462)\n\n`createReportDataSurfaceTools()` maps server-owned report definitions into the\ngeneric `data.discover`, `data.inspect`, and `data.query` catalog, and adds\nprincipal-bound `reports.query`, `reports.refresh`, `reports.drilldown`, and\n`reports.export` tools. It reuses the reports package's materialized-query,\nlifecycle, drilldown, and snapshot contracts rather than reimplementing them.\nReport ids, collections, query seams, browser delivery, background queues, and\naction hosts come only from the configured server catalog; tool arguments never\ncarry principal, tenant, or report-constructor authority.\n\n- Generic discovery excludes sensitive and permission-gated report columns.\n- Discovered report fields retain safe `kind`, `filterScope`, and capability\n  metadata, while the surface reports its available actions and lifecycle\n  freshness support. Actions are filtered by the current tool allow-list and\n  effective permissions. This lets agents distinguish dimensions/buckets\n  (`where`) from measures (`having`) without exposing hidden columns or\n  authority.\n- Silent reads do not change browser state; visible reads require a host-bound\n  acknowledgement whose post-command revision is not older than the requested\n  compare-and-swap revision; background requests contain no principal or tenant\n  payload.\n- Read results request the tenant-safe report lifecycle whenever an\n  authenticated database is available, so `freshness` and the redacted\n  lifecycle state cover stale and lock-skipped materializations.\n- Refresh and export use app-owned action hosts for live authorization and\n  auditing. Export captures an opaque immutable snapshot and preserves the\n  reports package's preview/confirmation protocol.\n- Drilldown re-reads a single accessible materialized row before it builds the\n  inherited source query, so callers cannot inject row values from another\n  tenant.\n\n## Agent Orchestration (issue #1892) — invoke-agent + principal delegation\n\nA 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.\n\n```typescript\nimport { createInvokeAgentTool, rootDelegationEnvelope } from '@happyvertical/smrt-agents';\n\nconst tool = createInvokeAgentTool({\n  db,\n  parentEnvelope: rootDelegationEnvelope({ runAsUserId, tenantId, onBehalfOfUserId }),\n  worker: async ({ run, agentClass, task }) => runWorker(run, agentClass, task),\n});\n// Offered through the chat tool loop as an `extraTools` entry, gated by the\n// persona's allowedTools like any other tool (slug: 'agents.invoke').\n```\n\n- **`DelegationEnvelope`** carries the **immutable principal** (`runAsUserId` + `tenantId` + originating `onBehalfOfUserId`) and a bounded `depth`. `deriveDelegationEnvelope()` copies the principal verbatim and asserts `depth <= MAX_DELEGATION_DEPTH` (3) — a worker cannot invoke a further worker under a broader principal (`PrincipalWideningError` / `DelegationDepthExceededError`).\n- **`createInvokeAgentTool()`** → a `PrincipalTool` whose handler derives the child envelope with the principal taken **from the live run context, never the tool args**, so the invoke-agent tool is structurally immune to principal widening.\n- **`executeDelegatedInvocation()`** runs the worker via `executeAsPrincipal` under that same principal and emits a correlated `agent.completed` dispatch; **`surfaceAgentCompletions(bus, correlationId)`** reads it back into the conversation.\n- **Transports** (pluggable): the default `inlineInvokeAgentTransport` runs the worker in-process (completion surfaces in the same turn); `createDispatchInvokeTransport(bus)` emits an `agent.invoke` signal a worker processes via `processAgentInvocations()` (async). A job-queue transport (enqueue on the `agents` queue) is a consumer-supplied `InvokeAgentTransport` — orchestration never hard-depends on `@happyvertical/smrt-jobs`, which sits *below* agents in the dependency graph.\n\n## Key Files\n\n| File | Purpose |\n|------|---------|\n| `src/agent.ts` | Base Agent class — lifecycle, dispatch, interests, config, opt-in learning trait, multi-instance identity |\n| `src/execute-as-principal.ts` | `executeAsPrincipal` / `PrincipalRun` — run agent work as a persona's bound user (#1888) |\n| `src/report-data-surface.ts` | Principal-bound report discovery, query, lifecycle, drilldown, and export tools (#2462) |\n| `src/delegation.ts` | `DelegationEnvelope` — immutable principal + bounded delegation depth (#1892) |\n| `src/invoke-agent.ts` | `invoke-agent` tool, worker executor, completion-dispatch convention, transports (#1892) |\n| `src/learning.ts` | `AgentLearningConfig` + `resolveAgentLearning()` declaration normalisation |\n| `src/schedule.ts` | AgentSchedule model — cron, execution tracking |\n| `src/tenant-agent.ts` | TenantAgent — junction table, hierarchical resolution |\n| `src/interests.ts` | Interest filter types and configuration |\n| `src/config.ts` | File + DB config management, UI slots |\n"
}