@elizaos/plugin-secrets-manager 1.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +1461 -0
- package/dist/index.js +4171 -0
- package/dist/index.js.map +1 -0
- package/package.json +82 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/plugin.ts","../src/services/secrets.ts","../src/types.ts","../src/crypto/encryption.ts","../src/storage/interface.ts","../src/storage/memory-store.ts","../src/storage/character-store.ts","../src/storage/world-store.ts","../src/storage/component-store.ts","../src/validation.ts","../src/services/plugin-activator.ts","../src/actions/set-secret.ts","../src/actions/manage-secret.ts","../src/providers/secrets-status.ts","../src/onboarding/config.ts","../src/onboarding/service.ts","../src/onboarding/provider.ts","../src/onboarding/action.ts"],"sourcesContent":["/**\n * Secrets Manager Plugin\n *\n * Comprehensive secret management for ElizaOS with:\n * - Multi-level storage (global, world, user)\n * - Encryption at rest\n * - Dynamic plugin activation when secrets become available\n * - Natural language secret management\n * - Conversational onboarding flow (Discord, Telegram)\n */\n\nimport type { Plugin } from \"@elizaos/core\";\nimport { logger } from \"@elizaos/core\";\n\nimport { SecretsService } from \"./services/secrets.js\";\nimport { PluginActivatorService } from \"./services/plugin-activator.js\";\nimport { setSecretAction, manageSecretAction } from \"./actions/index.js\";\nimport {\n secretsStatusProvider,\n secretsInfoProvider,\n} from \"./providers/index.js\";\nimport {\n OnboardingService,\n updateSettingsAction,\n onboardingSettingsProvider,\n missingSecretsProvider,\n} from \"./onboarding/index.js\";\n\n/**\n * Plugin configuration\n */\nexport interface SecretsManagerPluginConfig {\n /** Enable encryption for stored secrets (default: true) */\n enableEncryption?: boolean;\n /** Custom salt for encryption key derivation */\n encryptionSalt?: string;\n /** Enable access logging (default: true) */\n enableAccessLogging?: boolean;\n /** Enable automatic plugin activation when secrets are available (default: true) */\n enableAutoActivation?: boolean;\n /** Polling interval for checking plugin requirements (ms, default: 5000) */\n activationPollingMs?: number;\n}\n\n/**\n * Secrets Manager Plugin\n *\n * Provides comprehensive secret management capabilities:\n *\n * **Storage Levels:**\n * - Global: Agent-wide secrets (API keys, tokens) stored in character settings\n * - World: Server/channel-specific secrets stored in world metadata\n * - User: Per-user secrets stored as components\n *\n * **Features:**\n * - Automatic encryption using AES-256-GCM\n * - Natural language secret management via actions\n * - Plugin activation when required secrets become available\n * - Access logging and auditing\n * - Backward compatibility with ENV_ prefixed settings\n *\n * **Usage:**\n * ```typescript\n * import { secretsManagerPlugin } from '@elizaos/plugin-secrets-manager';\n *\n * const runtime = createAgentRuntime({\n * plugins: [secretsManagerPlugin],\n * });\n *\n * // Get the secrets service\n * const secrets = runtime.getService<SecretsService>('SECRETS');\n *\n * // Set a global secret\n * await secrets.setGlobal('OPENAI_API_KEY', 'sk-...');\n *\n * // Get a global secret\n * const apiKey = await secrets.getGlobal('OPENAI_API_KEY');\n * ```\n */\nexport const secretsManagerPlugin: Plugin = {\n name: \"@elizaos/plugin-secrets-manager\",\n description:\n \"Multi-level secret management with encryption, dynamic plugin activation, and conversational onboarding\",\n\n // Services\n services: [SecretsService, PluginActivatorService, OnboardingService],\n\n // Actions for natural language secret management and onboarding\n actions: [setSecretAction, manageSecretAction, updateSettingsAction],\n\n // Providers for context injection\n providers: [\n secretsStatusProvider,\n secretsInfoProvider,\n onboardingSettingsProvider,\n missingSecretsProvider,\n ],\n\n // Plugin initialization\n init: async (config: SecretsManagerPluginConfig, runtime) => {\n logger.info(\"[SecretsManagerPlugin] Initializing\");\n\n // Configuration is passed to services via their start() methods\n // The runtime will call Service.start() for each service\n\n logger.info(\"[SecretsManagerPlugin] Initialized\");\n },\n};\n\n// Default export\nexport default secretsManagerPlugin;\n\n// Re-export types and utilities\nexport * from \"./types.js\";\nexport * from \"./services/index.js\";\nexport * from \"./storage/index.js\";\nexport * from \"./crypto/index.js\";\nexport * from \"./onboarding/index.js\";\nexport {\n validateSecret,\n ValidationStrategies,\n registerValidator,\n inferValidationStrategy,\n} from \"./validation.js\";\n","/**\n * Secrets Service\n *\n * Core service for multi-level secret management in ElizaOS.\n * Provides unified API for accessing global, world, and user secrets\n * with encryption, access control, and change notification support.\n */\n\nimport {\n Service,\n logger,\n type IAgentRuntime,\n type ServiceTypeName,\n} from \"@elizaos/core\";\nimport type {\n SecretConfig,\n SecretContext,\n SecretMetadata,\n SecretAccessLog,\n SecretChangeEvent,\n SecretChangeCallback,\n SecretsServiceConfig,\n ValidationResult,\n ISecretStorage,\n PluginSecretRequirement,\n} from \"../types.js\";\nimport {\n PermissionDeniedError,\n SecretsError,\n MAX_ACCESS_LOG_ENTRIES,\n} from \"../types.js\";\nimport { KeyManager, deriveKeyFromAgentId } from \"../crypto/index.js\";\nimport {\n CharacterSettingsStorage,\n WorldMetadataStorage,\n ComponentSecretStorage,\n CompositeSecretStorage,\n} from \"../storage/index.js\";\nimport { validateSecret, ValidationStrategies } from \"../validation.js\";\n\n/**\n * Service type identifier\n */\nexport const SECRETS_SERVICE_TYPE = \"SECRETS\" as ServiceTypeName;\n\n/**\n * Default service configuration\n */\nconst DEFAULT_CONFIG: SecretsServiceConfig = {\n enableEncryption: true,\n encryptionSalt: undefined,\n enableAccessLogging: true,\n maxAccessLogEntries: MAX_ACCESS_LOG_ENTRIES,\n};\n\n/**\n * Secrets Service\n *\n * Unified service for managing secrets at all levels:\n * - Global: Stored in character settings (agent-wide config, API keys)\n * - World: Stored in world metadata (server/channel-specific)\n * - User: Stored as components (per-user secrets)\n */\nexport class SecretsService extends Service {\n static serviceType: ServiceTypeName = SECRETS_SERVICE_TYPE;\n capabilityDescription =\n \"Manage secrets at global, world, and user levels with encryption and access control\";\n\n private secretsConfig: SecretsServiceConfig;\n private keyManager!: KeyManager;\n private storage!: CompositeSecretStorage;\n private globalStorage!: CharacterSettingsStorage;\n private worldStorage!: WorldMetadataStorage;\n private userStorage!: ComponentSecretStorage;\n\n private accessLogs: SecretAccessLog[] = [];\n private changeCallbacks: Map<string, SecretChangeCallback[]> = new Map();\n private globalChangeCallbacks: SecretChangeCallback[] = [];\n\n constructor(runtime?: IAgentRuntime, config?: Partial<SecretsServiceConfig>) {\n super(runtime);\n this.secretsConfig = { ...DEFAULT_CONFIG, ...config };\n\n // Initialize encryption key manager\n this.keyManager = new KeyManager();\n if (runtime) {\n this.keyManager.initializeFromAgentId(\n runtime.agentId,\n this.secretsConfig.encryptionSalt ??\n (runtime.getSetting(\"ENCRYPTION_SALT\") as string),\n );\n\n // Initialize storage backends\n this.globalStorage = new CharacterSettingsStorage(\n runtime,\n this.keyManager,\n );\n this.worldStorage = new WorldMetadataStorage(runtime, this.keyManager);\n this.userStorage = new ComponentSecretStorage(runtime, this.keyManager);\n\n // Create composite storage\n this.storage = new CompositeSecretStorage({\n globalStorage: this.globalStorage,\n worldStorage: this.worldStorage,\n userStorage: this.userStorage,\n });\n }\n }\n\n /**\n * Start the service\n */\n static async start(\n runtime: IAgentRuntime,\n config?: Partial<SecretsServiceConfig>,\n ): Promise<SecretsService> {\n const service = new SecretsService(runtime, config);\n await service.initialize();\n return service;\n }\n\n /**\n * Initialize the service\n */\n private async initialize(): Promise<void> {\n logger.info(\"[SecretsService] Initializing\");\n\n await this.storage.initialize();\n\n // Migrate legacy env vars if needed\n const migrated = await this.globalStorage.migrateFromEnvVars();\n if (migrated > 0) {\n logger.info(`[SecretsService] Migrated ${migrated} legacy env vars`);\n }\n\n // Sync secrets to process.env for backward compatibility\n const synced = await this.globalStorage.syncAllToEnv();\n logger.debug(`[SecretsService] Synced ${synced} secrets to process.env`);\n\n logger.info(\"[SecretsService] Initialized\");\n }\n\n /**\n * Stop the service\n */\n async stop(): Promise<void> {\n logger.info(\"[SecretsService] Stopping\");\n\n // Clear sensitive data\n this.keyManager.clear();\n this.accessLogs = [];\n this.changeCallbacks.clear();\n this.globalChangeCallbacks = [];\n\n logger.info(\"[SecretsService] Stopped\");\n }\n\n // ============================================================================\n // Core Secret Operations\n // ============================================================================\n\n /**\n * Get a secret value\n */\n async get(key: string, context: SecretContext): Promise<string | null> {\n this.logAccess(key, \"read\", context, true);\n\n const value = await this.storage.get(key, context);\n\n if (value === null) {\n this.logAccess(key, \"read\", context, false, \"Secret not found\");\n }\n\n return value;\n }\n\n /**\n * Set a secret value\n */\n async set(\n key: string,\n value: string,\n context: SecretContext,\n config?: Partial<SecretConfig>,\n ): Promise<boolean> {\n this.logAccess(key, \"write\", context, true);\n\n // Validate if validation method specified\n if (config?.validationMethod && config.validationMethod !== \"none\") {\n const validation = await this.validate(\n key,\n value,\n config.validationMethod,\n );\n if (!validation.isValid) {\n this.logAccess(\n key,\n \"write\",\n context,\n false,\n `Validation failed: ${validation.error}`,\n );\n throw new SecretsError(\n `Validation failed for ${key}: ${validation.error}`,\n \"VALIDATION_FAILED\",\n { key, error: validation.error },\n );\n }\n }\n\n // Get previous value for change event\n const previousValue = await this.storage.get(key, context);\n\n const success = await this.storage.set(key, value, context, config);\n\n if (success) {\n // Sync to process.env if global\n if (context.level === \"global\") {\n await this.globalStorage.syncToEnv(key);\n }\n\n // Emit change event\n await this.emitChangeEvent({\n type: previousValue === null ? \"created\" : \"updated\",\n key,\n value,\n previousValue: previousValue ?? undefined,\n context,\n timestamp: Date.now(),\n });\n } else {\n this.logAccess(key, \"write\", context, false, \"Storage operation failed\");\n }\n\n return success;\n }\n\n /**\n * Delete a secret\n */\n async delete(key: string, context: SecretContext): Promise<boolean> {\n this.logAccess(key, \"delete\", context, true);\n\n const previousValue = await this.storage.get(key, context);\n const success = await this.storage.delete(key, context);\n\n if (success) {\n // Remove from process.env if global\n if (context.level === \"global\") {\n delete process.env[key];\n }\n\n // Emit change event\n await this.emitChangeEvent({\n type: \"deleted\",\n key,\n value: null,\n previousValue: previousValue ?? undefined,\n context,\n timestamp: Date.now(),\n });\n } else {\n this.logAccess(key, \"delete\", context, false, \"Secret not found\");\n }\n\n return success;\n }\n\n /**\n * Check if a secret exists\n */\n async exists(key: string, context: SecretContext): Promise<boolean> {\n return this.storage.exists(key, context);\n }\n\n /**\n * List secrets (metadata only, no values)\n */\n async list(context: SecretContext): Promise<SecretMetadata> {\n return this.storage.list(context);\n }\n\n /**\n * Get secret configuration\n */\n async getConfig(\n key: string,\n context: SecretContext,\n ): Promise<SecretConfig | null> {\n return this.storage.getConfig(key, context);\n }\n\n /**\n * Update secret configuration\n */\n async updateConfig(\n key: string,\n context: SecretContext,\n config: Partial<SecretConfig>,\n ): Promise<boolean> {\n return this.storage.updateConfig(key, context, config);\n }\n\n // ============================================================================\n // Convenience Methods\n // ============================================================================\n\n /**\n * Get a global secret (agent-level)\n */\n async getGlobal(key: string): Promise<string | null> {\n return this.get(key, { level: \"global\", agentId: this.runtime.agentId });\n }\n\n /**\n * Set a global secret (agent-level)\n */\n async setGlobal(\n key: string,\n value: string,\n config?: Partial<SecretConfig>,\n ): Promise<boolean> {\n return this.set(\n key,\n value,\n { level: \"global\", agentId: this.runtime.agentId },\n config,\n );\n }\n\n /**\n * Get a world secret\n */\n async getWorld(key: string, worldId: string): Promise<string | null> {\n return this.get(key, {\n level: \"world\",\n worldId,\n agentId: this.runtime.agentId,\n });\n }\n\n /**\n * Set a world secret\n */\n async setWorld(\n key: string,\n value: string,\n worldId: string,\n config?: Partial<SecretConfig>,\n ): Promise<boolean> {\n return this.set(\n key,\n value,\n { level: \"world\", worldId, agentId: this.runtime.agentId },\n config,\n );\n }\n\n /**\n * Get a user secret\n */\n async getUser(key: string, userId: string): Promise<string | null> {\n return this.get(key, {\n level: \"user\",\n userId,\n agentId: this.runtime.agentId,\n requesterId: userId,\n });\n }\n\n /**\n * Set a user secret\n */\n async setUser(\n key: string,\n value: string,\n userId: string,\n config?: Partial<SecretConfig>,\n ): Promise<boolean> {\n return this.set(\n key,\n value,\n {\n level: \"user\",\n userId,\n agentId: this.runtime.agentId,\n requesterId: userId,\n },\n config,\n );\n }\n\n // ============================================================================\n // Validation\n // ============================================================================\n\n /**\n * Validate a secret value\n */\n async validate(\n key: string,\n value: string,\n strategy?: string,\n ): Promise<ValidationResult> {\n return validateSecret(key, value, strategy);\n }\n\n /**\n * Get available validation strategies\n */\n getValidationStrategies(): string[] {\n return Object.keys(ValidationStrategies);\n }\n\n // ============================================================================\n // Plugin Requirements\n // ============================================================================\n\n /**\n * Check which secrets are missing for a plugin\n */\n async checkPluginRequirements(\n pluginId: string,\n requirements: Record<string, PluginSecretRequirement>,\n ): Promise<{\n ready: boolean;\n missingRequired: string[];\n missingOptional: string[];\n invalid: string[];\n }> {\n const missingRequired: string[] = [];\n const missingOptional: string[] = [];\n const invalid: string[] = [];\n\n for (const [key, requirement] of Object.entries(requirements)) {\n const value = await this.getGlobal(key);\n\n if (value === null) {\n if (requirement.required) {\n missingRequired.push(key);\n } else {\n missingOptional.push(key);\n }\n continue;\n }\n\n // Validate if validation method specified\n if (\n requirement.validationMethod &&\n requirement.validationMethod !== \"none\"\n ) {\n const validation = await this.validate(\n key,\n value,\n requirement.validationMethod,\n );\n if (!validation.isValid) {\n invalid.push(key);\n }\n }\n }\n\n return {\n ready: missingRequired.length === 0 && invalid.length === 0,\n missingRequired,\n missingOptional,\n invalid,\n };\n }\n\n /**\n * Get missing secrets for a set of keys\n */\n async getMissingSecrets(\n keys: string[],\n level: \"global\" | \"world\" | \"user\" = \"global\",\n ): Promise<string[]> {\n const missing: string[] = [];\n\n for (const key of keys) {\n let exists: boolean;\n\n switch (level) {\n case \"global\":\n exists = await this.exists(key, {\n level: \"global\",\n agentId: this.runtime.agentId,\n });\n break;\n case \"world\":\n case \"user\":\n // Would need worldId/userId for these\n exists = false;\n break;\n default:\n exists = false;\n }\n\n if (!exists) {\n missing.push(key);\n }\n }\n\n return missing;\n }\n\n // ============================================================================\n // Change Notifications\n // ============================================================================\n\n /**\n * Register a callback for changes to a specific secret\n */\n onSecretChanged(key: string, callback: SecretChangeCallback): () => void {\n const callbacks = this.changeCallbacks.get(key) ?? [];\n callbacks.push(callback);\n this.changeCallbacks.set(key, callbacks);\n\n // Return unsubscribe function\n return () => {\n const cbs = this.changeCallbacks.get(key);\n if (cbs) {\n const index = cbs.indexOf(callback);\n if (index !== -1) {\n cbs.splice(index, 1);\n }\n }\n };\n }\n\n /**\n * Register a callback for all secret changes\n */\n onAnySecretChanged(callback: SecretChangeCallback): () => void {\n this.globalChangeCallbacks.push(callback);\n\n return () => {\n const index = this.globalChangeCallbacks.indexOf(callback);\n if (index !== -1) {\n this.globalChangeCallbacks.splice(index, 1);\n }\n };\n }\n\n /**\n * Emit a change event to registered callbacks\n */\n private async emitChangeEvent(event: SecretChangeEvent): Promise<void> {\n // Notify key-specific callbacks\n const keyCallbacks = this.changeCallbacks.get(event.key) ?? [];\n for (const callback of keyCallbacks) {\n await callback(event.key, event.value, event.context);\n }\n\n // Notify global callbacks\n for (const callback of this.globalChangeCallbacks) {\n await callback(event.key, event.value, event.context);\n }\n\n logger.debug(\n `[SecretsService] Emitted ${event.type} event for ${event.key}`,\n );\n }\n\n // ============================================================================\n // Access Logging\n // ============================================================================\n\n /**\n * Log a secret access attempt\n */\n private logAccess(\n key: string,\n action: \"read\" | \"write\" | \"delete\" | \"share\",\n context: SecretContext,\n success: boolean,\n error?: string,\n ): void {\n if (!this.secretsConfig.enableAccessLogging) {\n return;\n }\n\n const log: SecretAccessLog = {\n secretKey: key,\n accessedBy: context.requesterId ?? context.userId ?? context.agentId,\n action,\n timestamp: Date.now(),\n context,\n success,\n error,\n };\n\n this.accessLogs.push(log);\n\n // Trim logs if over limit\n if (this.accessLogs.length > this.secretsConfig.maxAccessLogEntries) {\n this.accessLogs = this.accessLogs.slice(\n -this.secretsConfig.maxAccessLogEntries,\n );\n }\n\n if (!success && error) {\n logger.debug(\n `[SecretsService] Access denied: ${action} ${key} - ${error}`,\n );\n }\n }\n\n /**\n * Get access logs\n */\n getAccessLogs(filter?: {\n key?: string;\n action?: string;\n context?: Partial<SecretContext>;\n since?: number;\n }): SecretAccessLog[] {\n let logs = [...this.accessLogs];\n\n if (filter?.key) {\n logs = logs.filter((l) => l.secretKey === filter.key);\n }\n\n if (filter?.action) {\n logs = logs.filter((l) => l.action === filter.action);\n }\n\n if (filter?.since) {\n logs = logs.filter((l) => l.timestamp >= filter.since!);\n }\n\n if (filter?.context) {\n logs = logs.filter((l) => {\n if (filter.context!.level && l.context.level !== filter.context!.level)\n return false;\n if (\n filter.context!.worldId &&\n l.context.worldId !== filter.context!.worldId\n )\n return false;\n if (\n filter.context!.userId &&\n l.context.userId !== filter.context!.userId\n )\n return false;\n return true;\n });\n }\n\n return logs;\n }\n\n /**\n * Clear access logs\n */\n clearAccessLogs(): void {\n this.accessLogs = [];\n }\n\n // ============================================================================\n // Storage Access\n // ============================================================================\n\n /**\n * Get the global storage backend\n */\n getGlobalStorage(): CharacterSettingsStorage {\n return this.globalStorage;\n }\n\n /**\n * Get the world storage backend\n */\n getWorldStorage(): WorldMetadataStorage {\n return this.worldStorage;\n }\n\n /**\n * Get the user storage backend\n */\n getUserStorage(): ComponentSecretStorage {\n return this.userStorage;\n }\n\n /**\n * Get the key manager (for advanced use cases)\n */\n getKeyManager(): KeyManager {\n return this.keyManager;\n }\n}\n","/**\n * Plugin Secrets Manager - Shared Type Definitions\n *\n * This module defines all core types for the multi-level secrets management system.\n * Designed for ElizaOS native storage: character settings, world metadata, and components.\n */\n\nimport type { UUID } from \"@elizaos/core\";\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nexport const SECRET_KEY_MAX_LENGTH = 256;\nexport const SECRET_VALUE_MAX_LENGTH = 65536;\nexport const SECRET_DESCRIPTION_MAX_LENGTH = 1024;\nexport const SECRET_KEY_PATTERN = /^[A-Z][A-Z0-9_]*$/;\nexport const MAX_ACCESS_LOG_ENTRIES = 1000;\n\n// ============================================================================\n// Enums\n// ============================================================================\n\nexport type SecretLevel = \"global\" | \"world\" | \"user\";\n\nexport type SecretType =\n | \"api_key\"\n | \"private_key\"\n | \"public_key\"\n | \"url\"\n | \"credential\"\n | \"token\"\n | \"config\"\n | \"secret\";\n\nexport type SecretStatus =\n | \"missing\"\n | \"generating\"\n | \"validating\"\n | \"invalid\"\n | \"valid\"\n | \"expired\"\n | \"revoked\";\n\nexport type SecretPermissionType = \"read\" | \"write\" | \"delete\" | \"share\";\n\nexport type ValidationStrategy =\n | \"none\"\n | \"api_key:openai\"\n | \"api_key:anthropic\"\n | \"api_key:groq\"\n | \"api_key:google\"\n | \"api_key:mistral\"\n | \"api_key:cohere\"\n | \"url:valid\"\n | \"url:reachable\"\n | \"custom\";\n\nexport type StorageBackend = \"memory\" | \"character\" | \"world\" | \"component\";\n\n// ============================================================================\n// Core Secret Types\n// ============================================================================\n\n/**\n * Configuration for a single secret/environment variable\n */\nexport interface SecretConfig {\n /** Type classification of the secret */\n type: SecretType;\n /** Whether this secret is required for the plugin to function */\n required: boolean;\n /** Human-readable description */\n description: string;\n /** Whether this secret can be auto-generated */\n canGenerate: boolean;\n /** Validation method to use */\n validationMethod?: ValidationStrategy;\n /** Current status of the secret */\n status: SecretStatus;\n /** Last error message if validation failed */\n lastError?: string;\n /** Number of validation attempts */\n attempts: number;\n /** Timestamp when secret was created */\n createdAt?: number;\n /** Timestamp when secret was last validated */\n validatedAt?: number;\n /** Plugin that declared this secret requirement */\n plugin: string;\n /** Storage level (global, world, or user) */\n level: SecretLevel;\n /** Owner entity ID for user-level secrets */\n ownerId?: string;\n /** World ID for world-level secrets */\n worldId?: string;\n /** Whether the value is encrypted */\n encrypted?: boolean;\n /** Explicit permissions granted to other entities */\n permissions?: SecretPermission[];\n /** List of entity IDs with shared access */\n sharedWith?: string[];\n /** Optional expiration timestamp */\n expiresAt?: number;\n}\n\n/**\n * Stored secret with value and config\n */\nexport interface StoredSecret {\n /** The secret value (may be encrypted) */\n value: string | EncryptedSecret;\n /** Secret configuration */\n config: SecretConfig;\n}\n\n/**\n * Context for secret operations - determines access level and scope\n */\nexport interface SecretContext {\n /** Storage level to operate on */\n level: SecretLevel;\n /** World ID (required for world-level operations) */\n worldId?: string;\n /** User ID (required for user-level operations) */\n userId?: string;\n /** Agent ID (always required) */\n agentId: string;\n /** Entity making the request (for permission checks) */\n requesterId?: string;\n}\n\n/**\n * Permission grant for a secret\n */\nexport interface SecretPermission {\n /** Entity ID that has this permission */\n entityId: string;\n /** List of allowed operations */\n permissions: SecretPermissionType[];\n /** Entity that granted this permission */\n grantedBy: string;\n /** Timestamp when permission was granted */\n grantedAt: number;\n /** Optional expiration timestamp */\n expiresAt?: number;\n}\n\n/**\n * Metadata collection for multiple secrets (without values)\n */\nexport interface SecretMetadata {\n [key: string]: SecretConfig;\n}\n\n/**\n * Access log entry for auditing\n */\nexport interface SecretAccessLog {\n /** Secret key that was accessed */\n secretKey: string;\n /** Entity that performed the access */\n accessedBy: string;\n /** Type of access operation */\n action: SecretPermissionType;\n /** Timestamp of access */\n timestamp: number;\n /** Context of the access */\n context: SecretContext;\n /** Whether the access succeeded */\n success: boolean;\n /** Error message if access failed */\n error?: string;\n}\n\n// ============================================================================\n// Encryption Types\n// ============================================================================\n\n/**\n * Encrypted secret container\n */\nexport interface EncryptedSecret {\n /** Encrypted value (base64) */\n value: string;\n /** Initialization vector (base64) */\n iv: string;\n /** Authentication tag for GCM mode (base64) */\n authTag?: string;\n /** Encryption algorithm used */\n algorithm: \"aes-256-gcm\" | \"aes-256-cbc\";\n /** Key identifier for key rotation */\n keyId: string;\n}\n\n/**\n * Key derivation parameters\n */\nexport interface KeyDerivationParams {\n /** Salt for key derivation (base64) */\n salt: string;\n /** Number of iterations for PBKDF2 */\n iterations: number;\n /** Algorithm used for derivation */\n algorithm: \"pbkdf2-sha256\" | \"argon2id\";\n /** Key length in bytes */\n keyLength: number;\n}\n\n// ============================================================================\n// Plugin Activation Types\n// ============================================================================\n\n/**\n * Secret requirement declared by a plugin\n */\nexport interface PluginSecretRequirement {\n /** Human-readable description */\n description: string;\n /** Type of secret */\n type: SecretType;\n /** Whether the secret is required for plugin to function */\n required: boolean;\n /** Validation method to use */\n validationMethod?: ValidationStrategy;\n /** Environment variable name (for backward compatibility) */\n envVar?: string;\n /** Whether this secret can be auto-generated */\n canGenerate?: boolean;\n /** Generation script if auto-generatable */\n generationScript?: string;\n}\n\n/**\n * Status of plugin requirements\n */\nexport interface PluginRequirementStatus {\n /** Plugin identifier */\n pluginId: string;\n /** Whether all required secrets are available */\n ready: boolean;\n /** List of missing required secrets */\n missingRequired: string[];\n /** List of missing optional secrets */\n missingOptional: string[];\n /** List of invalid secrets */\n invalid: string[];\n /** Overall status message */\n message: string;\n}\n\n/**\n * Callback for secret changes\n */\nexport type SecretChangeCallback = (\n key: string,\n value: string | null,\n context: SecretContext,\n) => Promise<void>;\n\n/**\n * Plugin activation registration\n */\nexport interface PendingPluginActivation {\n /** Plugin identifier */\n pluginId: string;\n /** Required secrets for activation */\n requiredSecrets: string[];\n /** Callback to invoke when ready */\n callback: () => Promise<void>;\n /** Registration timestamp */\n registeredAt: number;\n}\n\n// ============================================================================\n// Storage Interface Types\n// ============================================================================\n\n/**\n * Storage backend interface\n */\nexport interface ISecretStorage {\n /** Storage backend type */\n readonly storageType: StorageBackend;\n\n /** Initialize the storage backend */\n initialize(): Promise<void>;\n\n /** Check if a secret exists */\n exists(key: string, context: SecretContext): Promise<boolean>;\n\n /** Get a secret value */\n get(key: string, context: SecretContext): Promise<string | null>;\n\n /** Set a secret value */\n set(\n key: string,\n value: string,\n context: SecretContext,\n config?: Partial<SecretConfig>,\n ): Promise<boolean>;\n\n /** Delete a secret */\n delete(key: string, context: SecretContext): Promise<boolean>;\n\n /** List all secrets in a context */\n list(context: SecretContext): Promise<SecretMetadata>;\n\n /** Get secret configuration without value */\n getConfig(key: string, context: SecretContext): Promise<SecretConfig | null>;\n\n /** Update secret configuration */\n updateConfig(\n key: string,\n context: SecretContext,\n config: Partial<SecretConfig>,\n ): Promise<boolean>;\n}\n\n// ============================================================================\n// Validation Types\n// ============================================================================\n\n/**\n * Result of secret validation\n */\nexport interface ValidationResult {\n /** Whether the value is valid */\n isValid: boolean;\n /** Error message if invalid */\n error?: string;\n /** Additional details */\n details?: string;\n /** Validation timestamp */\n validatedAt: number;\n}\n\n/**\n * Custom validation function signature\n */\nexport type CustomValidator = (\n key: string,\n value: string,\n) => Promise<ValidationResult>;\n\n/**\n * Validation strategy registry entry\n */\nexport interface ValidationStrategyEntry {\n /** Strategy identifier */\n id: ValidationStrategy;\n /** Human-readable name */\n name: string;\n /** Description of validation */\n description: string;\n /** Validator function */\n validate: CustomValidator;\n}\n\n// ============================================================================\n// Generation Types\n// ============================================================================\n\n/**\n * Script for auto-generating secrets\n */\nexport interface GenerationScript {\n /** Variable name to generate */\n variableName: string;\n /** Plugin that owns this script */\n pluginName: string;\n /** Script content (shell/node) */\n script: string;\n /** Required dependencies */\n dependencies: string[];\n /** Number of generation attempts */\n attempts: number;\n /** Last output */\n output?: string;\n /** Last error */\n error?: string;\n /** Current status */\n status: \"pending\" | \"running\" | \"success\" | \"failed\";\n /** Creation timestamp */\n createdAt: number;\n}\n\n// ============================================================================\n// Service Types\n// ============================================================================\n\n/**\n * Secrets service configuration\n */\nexport interface SecretsServiceConfig {\n /** Whether to enable encryption */\n enableEncryption: boolean;\n /** Salt for key derivation */\n encryptionSalt?: string;\n /** Whether to enable access logging */\n enableAccessLogging: boolean;\n /** Maximum access log entries to keep */\n maxAccessLogEntries: number;\n}\n\n/**\n * Plugin activator service configuration\n */\nexport interface PluginActivatorConfig {\n /** Whether to enable auto-activation */\n enableAutoActivation: boolean;\n /** Polling interval for checking requirements (ms) */\n pollingIntervalMs: number;\n /** Maximum time to wait for secrets (ms, 0 = forever) */\n maxWaitMs: number;\n}\n\n// ============================================================================\n// Event Types\n// ============================================================================\n\n/**\n * Secret change event\n */\nexport interface SecretChangeEvent {\n /** Event type */\n type: \"created\" | \"updated\" | \"deleted\" | \"expired\";\n /** Secret key */\n key: string;\n /** New value (null for deleted) */\n value: string | null;\n /** Previous value (if updated) */\n previousValue?: string;\n /** Context of the change */\n context: SecretContext;\n /** Timestamp */\n timestamp: number;\n}\n\n/**\n * Plugin activation event\n */\nexport interface PluginActivationEvent {\n /** Event type */\n type: \"queued\" | \"activated\" | \"failed\" | \"timeout\";\n /** Plugin identifier */\n pluginId: string;\n /** Missing secrets (if queued/failed) */\n missingSecrets?: string[];\n /** Error message (if failed) */\n error?: string;\n /** Timestamp */\n timestamp: number;\n}\n\n// ============================================================================\n// Form Types (for web-based secret collection)\n// ============================================================================\n\nexport type FormFieldType =\n | \"text\"\n | \"password\"\n | \"textarea\"\n | \"select\"\n | \"checkbox\"\n | \"radio\"\n | \"file\"\n | \"hidden\";\n\nexport interface FormValidationRule {\n /** Rule type */\n type: \"required\" | \"minLength\" | \"maxLength\" | \"pattern\" | \"custom\";\n /** Value for the rule */\n value?: string | number | boolean;\n /** Error message */\n message: string;\n}\n\nexport interface FormField {\n /** Field name (becomes secret key) */\n name: string;\n /** Field label */\n label: string;\n /** Field type */\n type: FormFieldType;\n /** Placeholder text */\n placeholder?: string;\n /** Default value */\n defaultValue?: string;\n /** Help text */\n helpText?: string;\n /** Options for select/radio */\n options?: Array<{ value: string; label: string }>;\n /** Validation rules */\n validation?: FormValidationRule[];\n /** Whether field is disabled */\n disabled?: boolean;\n /** Custom CSS classes */\n className?: string;\n}\n\nexport interface FormSchema {\n /** Form title */\n title: string;\n /** Form description */\n description?: string;\n /** Form fields */\n fields: FormField[];\n /** Submit button text */\n submitText?: string;\n /** Cancel button text */\n cancelText?: string;\n /** Success message */\n successMessage?: string;\n /** Redirect URL after success */\n redirectUrl?: string;\n}\n\nexport interface FormSession {\n /** Session ID */\n id: string;\n /** Form schema */\n schema: FormSchema;\n /** Context for storing secrets */\n context: SecretContext;\n /** Expiration timestamp */\n expiresAt: number;\n /** Created timestamp */\n createdAt: number;\n /** Public URL for form access */\n publicUrl?: string;\n /** Tunnel ID (if using ngrok) */\n tunnelId?: string;\n /** Whether form has been submitted */\n submitted: boolean;\n /** Submission timestamp */\n submittedAt?: number;\n}\n\nexport interface FormSubmission {\n /** Session ID */\n sessionId: string;\n /** Submitted values */\n values: Record<string, string>;\n /** Submission timestamp */\n submittedAt: number;\n /** Client IP address */\n clientIp?: string;\n /** User agent */\n userAgent?: string;\n}\n\n// ============================================================================\n// Error Types\n// ============================================================================\n\nexport class SecretsError extends Error {\n constructor(\n message: string,\n public readonly code: string,\n public readonly details?: Record<string, unknown>,\n ) {\n super(message);\n this.name = \"SecretsError\";\n }\n}\n\nexport class PermissionDeniedError extends SecretsError {\n constructor(\n key: string,\n action: SecretPermissionType,\n context: SecretContext,\n ) {\n super(\n `Permission denied: cannot ${action} secret '${key}' at level '${context.level}'`,\n \"PERMISSION_DENIED\",\n { key, action, context },\n );\n this.name = \"PermissionDeniedError\";\n }\n}\n\nexport class SecretNotFoundError extends SecretsError {\n constructor(key: string, context: SecretContext) {\n super(\n `Secret '${key}' not found at level '${context.level}'`,\n \"SECRET_NOT_FOUND\",\n { key, context },\n );\n this.name = \"SecretNotFoundError\";\n }\n}\n\nexport class ValidationError extends SecretsError {\n constructor(key: string, message: string, details?: Record<string, unknown>) {\n super(\n `Validation failed for secret '${key}': ${message}`,\n \"VALIDATION_FAILED\",\n { key, ...details },\n );\n this.name = \"ValidationError\";\n }\n}\n\nexport class EncryptionError extends SecretsError {\n constructor(message: string, details?: Record<string, unknown>) {\n super(message, \"ENCRYPTION_ERROR\", details);\n this.name = \"EncryptionError\";\n }\n}\n\nexport class StorageError extends SecretsError {\n constructor(message: string, details?: Record<string, unknown>) {\n super(message, \"STORAGE_ERROR\", details);\n this.name = \"StorageError\";\n }\n}\n","/**\n * Encryption module for secrets management\n *\n * Provides AES-256-GCM encryption with secure key derivation for protecting sensitive data.\n * Compatible with the OpenClaw encryption approach while providing additional security features.\n */\n\nimport {\n createCipheriv,\n createDecipheriv,\n randomBytes,\n createHash,\n pbkdf2Sync,\n scryptSync,\n} from \"crypto\";\nimport type { EncryptedSecret, KeyDerivationParams } from \"../types.js\";\nimport { EncryptionError } from \"../types.js\";\n\n// ============================================================================\n// Constants\n// ============================================================================\n\nconst ALGORITHM_GCM = \"aes-256-gcm\";\nconst ALGORITHM_CBC = \"aes-256-cbc\";\nconst IV_LENGTH = 16;\nconst AUTH_TAG_LENGTH = 16;\nconst KEY_LENGTH = 32; // 256 bits\nconst DEFAULT_SALT_LENGTH = 32;\nconst DEFAULT_PBKDF2_ITERATIONS = 100000;\n\n// ============================================================================\n// Key Derivation\n// ============================================================================\n\n/**\n * Generate a cryptographically secure random salt\n */\nexport function generateSalt(length: number = DEFAULT_SALT_LENGTH): string {\n return randomBytes(length).toString(\"base64\");\n}\n\n/**\n * Generate a random encryption key\n */\nexport function generateKey(): Buffer {\n return randomBytes(KEY_LENGTH);\n}\n\n/**\n * Derive an encryption key from a password/passphrase using PBKDF2\n *\n * @param password - The password or passphrase to derive from\n * @param salt - The salt (should be unique per key)\n * @param iterations - Number of PBKDF2 iterations (default: 100000)\n * @returns The derived key as a Buffer\n */\nexport function deriveKeyPbkdf2(\n password: string,\n salt: string | Buffer,\n iterations: number = DEFAULT_PBKDF2_ITERATIONS,\n): Buffer {\n const saltBuffer =\n typeof salt === \"string\" ? Buffer.from(salt, \"base64\") : salt;\n return pbkdf2Sync(password, saltBuffer, iterations, KEY_LENGTH, \"sha256\");\n}\n\n/**\n * Derive an encryption key from a password using scrypt (more memory-hard)\n *\n * @param password - The password or passphrase to derive from\n * @param salt - The salt (should be unique per key)\n * @returns The derived key as a Buffer\n */\nexport function deriveKeyScrypt(\n password: string,\n salt: string | Buffer,\n): Buffer {\n const saltBuffer =\n typeof salt === \"string\" ? Buffer.from(salt, \"base64\") : salt;\n return scryptSync(password, saltBuffer, KEY_LENGTH, {\n N: 16384,\n r: 8,\n p: 1,\n });\n}\n\n/**\n * Derive a key from agent ID and salt (OpenClaw compatible)\n *\n * This method provides backward compatibility with OpenClaw's key derivation approach.\n * For new implementations, prefer deriveKeyPbkdf2 or deriveKeyScrypt.\n *\n * @param agentId - The agent's unique identifier\n * @param salt - Optional salt (defaults to 'default-salt')\n * @returns The derived key as a Buffer\n */\nexport function deriveKeyFromAgentId(\n agentId: string,\n salt: string = \"default-salt\",\n): Buffer {\n return createHash(\"sha256\")\n .update(agentId + salt)\n .digest();\n}\n\n/**\n * Create key derivation parameters for storage\n */\nexport function createKeyDerivationParams(\n salt?: string,\n iterations: number = DEFAULT_PBKDF2_ITERATIONS,\n): KeyDerivationParams {\n return {\n salt: salt ?? generateSalt(),\n iterations,\n algorithm: \"pbkdf2-sha256\",\n keyLength: KEY_LENGTH,\n };\n}\n\n// ============================================================================\n// Encryption\n// ============================================================================\n\n/**\n * Encrypt a value using AES-256-GCM\n *\n * GCM mode provides both confidentiality and authenticity, making it the preferred\n * choice for encrypting secrets. The authentication tag prevents tampering.\n *\n * @param plaintext - The value to encrypt\n * @param key - The encryption key (32 bytes)\n * @param keyId - Identifier for the key (for rotation support)\n * @returns Encrypted secret container\n */\nexport function encryptGcm(\n plaintext: string,\n key: Buffer,\n keyId: string = \"default\",\n): EncryptedSecret {\n if (key.length !== KEY_LENGTH) {\n throw new EncryptionError(\n `Invalid key length: expected ${KEY_LENGTH}, got ${key.length}`,\n );\n }\n\n const iv = randomBytes(IV_LENGTH);\n const cipher = createCipheriv(ALGORITHM_GCM, key, iv);\n\n let encrypted = cipher.update(plaintext, \"utf8\", \"base64\");\n encrypted += cipher.final(\"base64\");\n\n const authTag = cipher.getAuthTag();\n\n return {\n value: encrypted,\n iv: iv.toString(\"base64\"),\n authTag: authTag.toString(\"base64\"),\n algorithm: \"aes-256-gcm\",\n keyId,\n };\n}\n\n/**\n * Encrypt a value using AES-256-CBC (fallback for compatibility)\n *\n * CBC mode is provided for backward compatibility. For new implementations,\n * prefer encryptGcm which provides authentication.\n *\n * @param plaintext - The value to encrypt\n * @param key - The encryption key (32 bytes)\n * @param keyId - Identifier for the key (for rotation support)\n * @returns Encrypted secret container\n */\nexport function encryptCbc(\n plaintext: string,\n key: Buffer,\n keyId: string = \"default\",\n): EncryptedSecret {\n if (key.length !== KEY_LENGTH) {\n throw new EncryptionError(\n `Invalid key length: expected ${KEY_LENGTH}, got ${key.length}`,\n );\n }\n\n const iv = randomBytes(IV_LENGTH);\n const cipher = createCipheriv(ALGORITHM_CBC, key, iv);\n\n let encrypted = cipher.update(plaintext, \"utf8\", \"base64\");\n encrypted += cipher.final(\"base64\");\n\n return {\n value: encrypted,\n iv: iv.toString(\"base64\"),\n algorithm: \"aes-256-cbc\",\n keyId,\n };\n}\n\n/**\n * Encrypt a value using the default algorithm (GCM)\n */\nexport function encrypt(\n plaintext: string,\n key: Buffer,\n keyId: string = \"default\",\n): EncryptedSecret {\n return encryptGcm(plaintext, key, keyId);\n}\n\n// ============================================================================\n// Decryption\n// ============================================================================\n\n/**\n * Decrypt a value encrypted with AES-256-GCM\n *\n * @param encrypted - The encrypted secret container\n * @param key - The decryption key (32 bytes)\n * @returns The decrypted plaintext\n */\nexport function decryptGcm(encrypted: EncryptedSecret, key: Buffer): string {\n if (key.length !== KEY_LENGTH) {\n throw new EncryptionError(\n `Invalid key length: expected ${KEY_LENGTH}, got ${key.length}`,\n );\n }\n\n if (encrypted.algorithm !== \"aes-256-gcm\") {\n throw new EncryptionError(\n `Algorithm mismatch: expected aes-256-gcm, got ${encrypted.algorithm}`,\n );\n }\n\n if (!encrypted.authTag) {\n throw new EncryptionError(\"Missing authentication tag for GCM decryption\");\n }\n\n const iv = Buffer.from(encrypted.iv, \"base64\");\n const authTag = Buffer.from(encrypted.authTag, \"base64\");\n const decipher = createDecipheriv(ALGORITHM_GCM, key, iv);\n decipher.setAuthTag(authTag);\n\n let decrypted = decipher.update(encrypted.value, \"base64\", \"utf8\");\n decrypted += decipher.final(\"utf8\");\n\n return decrypted;\n}\n\n/**\n * Decrypt a value encrypted with AES-256-CBC\n *\n * @param encrypted - The encrypted secret container\n * @param key - The decryption key (32 bytes)\n * @returns The decrypted plaintext\n */\nexport function decryptCbc(encrypted: EncryptedSecret, key: Buffer): string {\n if (key.length !== KEY_LENGTH) {\n throw new EncryptionError(\n `Invalid key length: expected ${KEY_LENGTH}, got ${key.length}`,\n );\n }\n\n if (encrypted.algorithm !== \"aes-256-cbc\") {\n throw new EncryptionError(\n `Algorithm mismatch: expected aes-256-cbc, got ${encrypted.algorithm}`,\n );\n }\n\n const iv = Buffer.from(encrypted.iv, \"base64\");\n const decipher = createDecipheriv(ALGORITHM_CBC, key, iv);\n\n let decrypted = decipher.update(encrypted.value, \"base64\", \"utf8\");\n decrypted += decipher.final(\"utf8\");\n\n return decrypted;\n}\n\n/**\n * Decrypt a value using the appropriate algorithm\n *\n * @param encrypted - The encrypted secret container (or raw string for backward compat)\n * @param key - The decryption key (32 bytes)\n * @returns The decrypted plaintext\n */\nexport function decrypt(\n encrypted: EncryptedSecret | string,\n key: Buffer,\n): string {\n // Handle backward compatibility with unencrypted strings\n if (typeof encrypted === \"string\") {\n return encrypted;\n }\n\n switch (encrypted.algorithm) {\n case \"aes-256-gcm\":\n return decryptGcm(encrypted, key);\n case \"aes-256-cbc\":\n return decryptCbc(encrypted, key);\n default:\n throw new EncryptionError(\n `Unsupported algorithm: ${encrypted.algorithm}`,\n );\n }\n}\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/**\n * Check if a value appears to be an encrypted secret\n */\nexport function isEncryptedSecret(value: unknown): value is EncryptedSecret {\n if (!value || typeof value !== \"object\") {\n return false;\n }\n\n const obj = value as Record<string, unknown>;\n return (\n typeof obj.value === \"string\" &&\n typeof obj.iv === \"string\" &&\n typeof obj.algorithm === \"string\" &&\n (obj.algorithm === \"aes-256-gcm\" || obj.algorithm === \"aes-256-cbc\")\n );\n}\n\n/**\n * Generate a secure random string for tokens, IDs, etc.\n */\nexport function generateSecureToken(length: number = 32): string {\n return randomBytes(length).toString(\"hex\");\n}\n\n/**\n * Hash a value for comparison or fingerprinting (not for passwords)\n */\nexport function hashValue(\n value: string,\n algorithm: \"sha256\" | \"sha512\" = \"sha256\",\n): string {\n return createHash(algorithm).update(value).digest(\"hex\");\n}\n\n/**\n * Securely compare two strings in constant time to prevent timing attacks\n */\nexport function secureCompare(a: string, b: string): boolean {\n if (a.length !== b.length) {\n return false;\n }\n\n const bufA = Buffer.from(a);\n const bufB = Buffer.from(b);\n\n let result = 0;\n for (let i = 0; i < bufA.length; i++) {\n result |= bufA[i] ^ bufB[i];\n }\n\n return result === 0;\n}\n\n// ============================================================================\n// Key Manager Class\n// ============================================================================\n\n/**\n * Manages encryption keys with support for rotation and multiple key IDs\n */\nexport class KeyManager {\n private keys: Map<string, Buffer> = new Map();\n private currentKeyId: string = \"default\";\n private derivationParams: KeyDerivationParams | null = null;\n\n constructor(options?: {\n primaryKey?: Buffer;\n primaryKeyId?: string;\n derivationParams?: KeyDerivationParams;\n }) {\n if (options?.primaryKey) {\n const keyId = options.primaryKeyId ?? \"default\";\n this.keys.set(keyId, options.primaryKey);\n this.currentKeyId = keyId;\n }\n if (options?.derivationParams) {\n this.derivationParams = options.derivationParams;\n }\n }\n\n /**\n * Initialize with a password-derived key\n */\n initializeFromPassword(password: string, salt?: string): void {\n this.derivationParams = createKeyDerivationParams(salt);\n const key = deriveKeyPbkdf2(\n password,\n this.derivationParams.salt,\n this.derivationParams.iterations,\n );\n this.keys.set(\"default\", key);\n this.currentKeyId = \"default\";\n }\n\n /**\n * Initialize with an agent ID (OpenClaw compatible)\n */\n initializeFromAgentId(agentId: string, salt?: string): void {\n const key = deriveKeyFromAgentId(agentId, salt);\n this.keys.set(\"default\", key);\n this.currentKeyId = \"default\";\n }\n\n /**\n * Add a key for decryption (supports key rotation)\n */\n addKey(keyId: string, key: Buffer): void {\n this.keys.set(keyId, key);\n }\n\n /**\n * Set the current key for encryption\n */\n setCurrentKey(keyId: string): void {\n if (!this.keys.has(keyId)) {\n throw new EncryptionError(`Key not found: ${keyId}`);\n }\n this.currentKeyId = keyId;\n }\n\n /**\n * Get the current key ID\n */\n getCurrentKeyId(): string {\n return this.currentKeyId;\n }\n\n /**\n * Get a key by ID\n */\n getKey(keyId: string): Buffer | undefined {\n return this.keys.get(keyId);\n }\n\n /**\n * Get the current encryption key\n */\n getCurrentKey(): Buffer {\n const key = this.keys.get(this.currentKeyId);\n if (!key) {\n throw new EncryptionError(\"No encryption key configured\");\n }\n return key;\n }\n\n /**\n * Get derivation parameters (for storage)\n */\n getDerivationParams(): KeyDerivationParams | null {\n return this.derivationParams;\n }\n\n /**\n * Encrypt a value with the current key\n */\n encrypt(plaintext: string): EncryptedSecret {\n return encryptGcm(plaintext, this.getCurrentKey(), this.currentKeyId);\n }\n\n /**\n * Decrypt a value (automatically selects the correct key)\n */\n decrypt(encrypted: EncryptedSecret | string): string {\n if (typeof encrypted === \"string\") {\n return encrypted;\n }\n\n const key = this.keys.get(encrypted.keyId);\n if (!key) {\n throw new EncryptionError(\n `Key not found for decryption: ${encrypted.keyId}`,\n );\n }\n\n return decrypt(encrypted, key);\n }\n\n /**\n * Re-encrypt a value with the current key (for key rotation)\n */\n reencrypt(encrypted: EncryptedSecret): EncryptedSecret {\n const plaintext = this.decrypt(encrypted);\n return this.encrypt(plaintext);\n }\n\n /**\n * Clear all keys from memory\n */\n clear(): void {\n // Overwrite key buffers before clearing\n for (const key of this.keys.values()) {\n key.fill(0);\n }\n this.keys.clear();\n }\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport {\n ALGORITHM_GCM,\n ALGORITHM_CBC,\n IV_LENGTH,\n KEY_LENGTH,\n DEFAULT_SALT_LENGTH,\n DEFAULT_PBKDF2_ITERATIONS,\n};\n","/**\n * Storage Interface Definitions\n *\n * Defines the contract that all storage backends must implement.\n * Designed for ElizaOS native storage patterns.\n */\n\nimport type {\n SecretConfig,\n SecretContext,\n SecretMetadata,\n StorageBackend,\n ISecretStorage,\n} from \"../types.js\";\n\n// Re-export interface for convenience\nexport type { ISecretStorage };\n\n/**\n * Abstract base class for secret storage implementations\n *\n * Provides common functionality and enforces the storage interface.\n */\nexport abstract class BaseSecretStorage implements ISecretStorage {\n abstract readonly storageType: StorageBackend;\n\n abstract initialize(): Promise<void>;\n\n abstract exists(key: string, context: SecretContext): Promise<boolean>;\n\n abstract get(key: string, context: SecretContext): Promise<string | null>;\n\n abstract set(\n key: string,\n value: string,\n context: SecretContext,\n config?: Partial<SecretConfig>,\n ): Promise<boolean>;\n\n abstract delete(key: string, context: SecretContext): Promise<boolean>;\n\n abstract list(context: SecretContext): Promise<SecretMetadata>;\n\n abstract getConfig(\n key: string,\n context: SecretContext,\n ): Promise<SecretConfig | null>;\n\n abstract updateConfig(\n key: string,\n context: SecretContext,\n config: Partial<SecretConfig>,\n ): Promise<boolean>;\n\n /**\n * Create a default secret configuration\n */\n protected createDefaultConfig(\n key: string,\n context: SecretContext,\n partial?: Partial<SecretConfig>,\n ): SecretConfig {\n return {\n type: partial?.type ?? \"secret\",\n required: partial?.required ?? false,\n description: partial?.description ?? `Secret: ${key}`,\n canGenerate: partial?.canGenerate ?? false,\n validationMethod: partial?.validationMethod,\n status: partial?.status ?? \"valid\",\n lastError: partial?.lastError,\n attempts: partial?.attempts ?? 0,\n createdAt: partial?.createdAt ?? Date.now(),\n validatedAt: partial?.validatedAt ?? Date.now(),\n plugin: partial?.plugin ?? context.level,\n level: context.level,\n ownerId: context.userId,\n worldId: context.worldId,\n encrypted: partial?.encrypted ?? true,\n permissions: partial?.permissions ?? [],\n sharedWith: partial?.sharedWith ?? [],\n expiresAt: partial?.expiresAt,\n };\n }\n}\n\n/**\n * Composite storage that delegates to multiple backends based on context\n */\nexport class CompositeSecretStorage implements ISecretStorage {\n readonly storageType: StorageBackend = \"memory\";\n\n private globalStorage: ISecretStorage;\n private worldStorage: ISecretStorage;\n private userStorage: ISecretStorage;\n\n constructor(options: {\n globalStorage: ISecretStorage;\n worldStorage: ISecretStorage;\n userStorage: ISecretStorage;\n }) {\n this.globalStorage = options.globalStorage;\n this.worldStorage = options.worldStorage;\n this.userStorage = options.userStorage;\n }\n\n async initialize(): Promise<void> {\n await Promise.all([\n this.globalStorage.initialize(),\n this.worldStorage.initialize(),\n this.userStorage.initialize(),\n ]);\n }\n\n private getStorageForContext(context: SecretContext): ISecretStorage {\n switch (context.level) {\n case \"global\":\n return this.globalStorage;\n case \"world\":\n return this.worldStorage;\n case \"user\":\n return this.userStorage;\n default:\n return this.globalStorage;\n }\n }\n\n async exists(key: string, context: SecretContext): Promise<boolean> {\n return this.getStorageForContext(context).exists(key, context);\n }\n\n async get(key: string, context: SecretContext): Promise<string | null> {\n return this.getStorageForContext(context).get(key, context);\n }\n\n async set(\n key: string,\n value: string,\n context: SecretContext,\n config?: Partial<SecretConfig>,\n ): Promise<boolean> {\n return this.getStorageForContext(context).set(key, value, context, config);\n }\n\n async delete(key: string, context: SecretContext): Promise<boolean> {\n return this.getStorageForContext(context).delete(key, context);\n }\n\n async list(context: SecretContext): Promise<SecretMetadata> {\n return this.getStorageForContext(context).list(context);\n }\n\n async getConfig(\n key: string,\n context: SecretContext,\n ): Promise<SecretConfig | null> {\n return this.getStorageForContext(context).getConfig(key, context);\n }\n\n async updateConfig(\n key: string,\n context: SecretContext,\n config: Partial<SecretConfig>,\n ): Promise<boolean> {\n return this.getStorageForContext(context).updateConfig(\n key,\n context,\n config,\n );\n }\n}\n","/**\n * Memory-based Secret Storage\n *\n * In-memory storage backend for secrets. Useful for testing and\n * ephemeral environments where persistence is not required.\n */\n\nimport type {\n SecretConfig,\n SecretContext,\n SecretMetadata,\n StorageBackend,\n} from \"../types.js\";\nimport { BaseSecretStorage } from \"./interface.js\";\n\n/**\n * Internal storage entry combining value and config\n */\ninterface StorageEntry {\n value: string;\n config: SecretConfig;\n}\n\n/**\n * Memory-based secret storage implementation\n */\nexport class MemorySecretStorage extends BaseSecretStorage {\n readonly storageType: StorageBackend = \"memory\";\n\n private store: Map<string, StorageEntry> = new Map();\n\n async initialize(): Promise<void> {\n // Nothing to initialize for memory storage\n }\n\n async exists(key: string, context: SecretContext): Promise<boolean> {\n const storageKey = this.generateStorageKey(key, context);\n return this.store.has(storageKey);\n }\n\n async get(key: string, context: SecretContext): Promise<string | null> {\n const storageKey = this.generateStorageKey(key, context);\n const entry = this.store.get(storageKey);\n if (!entry) {\n return null;\n }\n\n // Check expiration\n if (entry.config.expiresAt && entry.config.expiresAt < Date.now()) {\n this.store.delete(storageKey);\n return null;\n }\n\n return entry.value;\n }\n\n async set(\n key: string,\n value: string,\n context: SecretContext,\n config?: Partial<SecretConfig>,\n ): Promise<boolean> {\n const storageKey = this.generateStorageKey(key, context);\n const existingEntry = this.store.get(storageKey);\n\n const fullConfig = this.createDefaultConfig(key, context, {\n ...existingEntry?.config,\n ...config,\n });\n\n this.store.set(storageKey, {\n value,\n config: fullConfig,\n });\n\n return true;\n }\n\n async delete(key: string, context: SecretContext): Promise<boolean> {\n const storageKey = this.generateStorageKey(key, context);\n return this.store.delete(storageKey);\n }\n\n async list(context: SecretContext): Promise<SecretMetadata> {\n const prefix = this.getContextPrefix(context);\n const metadata: SecretMetadata = {};\n\n for (const [storageKey, entry] of this.store) {\n if (storageKey.startsWith(prefix)) {\n const originalKey = this.extractOriginalKey(storageKey, context);\n if (originalKey) {\n // Check expiration\n if (entry.config.expiresAt && entry.config.expiresAt < Date.now()) {\n this.store.delete(storageKey);\n continue;\n }\n metadata[originalKey] = { ...entry.config };\n }\n }\n }\n\n return metadata;\n }\n\n async getConfig(\n key: string,\n context: SecretContext,\n ): Promise<SecretConfig | null> {\n const storageKey = this.generateStorageKey(key, context);\n const entry = this.store.get(storageKey);\n if (!entry) {\n return null;\n }\n return { ...entry.config };\n }\n\n async updateConfig(\n key: string,\n context: SecretContext,\n config: Partial<SecretConfig>,\n ): Promise<boolean> {\n const storageKey = this.generateStorageKey(key, context);\n const entry = this.store.get(storageKey);\n if (!entry) {\n return false;\n }\n\n entry.config = {\n ...entry.config,\n ...config,\n };\n\n this.store.set(storageKey, entry);\n return true;\n }\n\n /**\n * Generate a storage key from the secret key and context\n */\n private generateStorageKey(key: string, context: SecretContext): string {\n switch (context.level) {\n case \"global\":\n return `global:${context.agentId}:${key}`;\n case \"world\":\n return `world:${context.worldId}:${key}`;\n case \"user\":\n return `user:${context.userId}:${key}`;\n default:\n return `unknown:${key}`;\n }\n }\n\n /**\n * Get the storage key prefix for a context level\n */\n private getContextPrefix(context: SecretContext): string {\n switch (context.level) {\n case \"global\":\n return `global:${context.agentId}:`;\n case \"world\":\n return `world:${context.worldId}:`;\n case \"user\":\n return `user:${context.userId}:`;\n default:\n return \"\";\n }\n }\n\n /**\n * Extract the original key from a storage key\n */\n private extractOriginalKey(\n storageKey: string,\n context: SecretContext,\n ): string | null {\n const prefix = this.getContextPrefix(context);\n if (!storageKey.startsWith(prefix)) {\n return null;\n }\n return storageKey.slice(prefix.length);\n }\n\n /**\n * Clear all stored secrets (for testing)\n */\n clear(): void {\n this.store.clear();\n }\n\n /**\n * Get the number of stored secrets (for testing)\n */\n size(): number {\n return this.store.size;\n }\n}\n","/**\n * Character Settings Storage\n *\n * Stores global secrets in the character's settings.secrets object.\n * This is the primary storage for agent-level configuration and API keys.\n *\n * Note: This implementation directly accesses character.settings rather than\n * using getSetting()/setSetting() because those methods don't support object\n * values - they only return primitives (string | boolean | number | null).\n */\n\nimport type { IAgentRuntime } from \"@elizaos/core\";\nimport { logger } from \"@elizaos/core\";\nimport type {\n SecretConfig,\n SecretContext,\n SecretMetadata,\n StorageBackend,\n StoredSecret,\n EncryptedSecret,\n} from \"../types.js\";\nimport { BaseSecretStorage } from \"./interface.js\";\nimport { KeyManager, isEncryptedSecret } from \"../crypto/index.js\";\n\nconst SECRETS_KEY = \"secrets\";\nconst METADATA_KEY = \"__secrets_metadata\";\n\n/**\n * Character settings-based storage for global secrets\n *\n * Secrets are stored in character.settings.secrets with metadata\n * tracked separately for configuration management.\n */\nexport class CharacterSettingsStorage extends BaseSecretStorage {\n readonly storageType: StorageBackend = \"character\";\n\n private runtime: IAgentRuntime;\n private keyManager: KeyManager;\n private initialized: boolean = false;\n\n constructor(runtime: IAgentRuntime, keyManager: KeyManager) {\n super();\n this.runtime = runtime;\n this.keyManager = keyManager;\n }\n\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n logger.debug(\"[CharacterSettingsStorage] Initializing\");\n\n // Ensure settings and secrets objects exist\n this.ensureSettingsStructure();\n\n this.initialized = true;\n logger.debug(\"[CharacterSettingsStorage] Initialized\");\n }\n\n /**\n * Ensure the character.settings.secrets structure exists\n */\n private ensureSettingsStructure(): void {\n if (!this.runtime.character.settings) {\n this.runtime.character.settings = {};\n }\n if (!this.runtime.character.settings[SECRETS_KEY]) {\n this.runtime.character.settings[SECRETS_KEY] = {};\n }\n }\n\n async exists(key: string, _context: SecretContext): Promise<boolean> {\n this.ensureSettingsStructure();\n const secrets = this.getSecretsObject();\n return key in secrets;\n }\n\n async get(key: string, context: SecretContext): Promise<string | null> {\n this.ensureSettingsStructure();\n const secrets = this.getSecretsObject();\n const stored = secrets[key];\n\n if (stored === undefined || stored === null) {\n return null;\n }\n\n // Handle different storage formats\n if (typeof stored === \"string\") {\n // Plain string value\n return stored;\n }\n\n if (typeof stored === \"object\") {\n const storedSecret = stored as StoredSecret;\n\n // Check expiration\n if (\n storedSecret.config?.expiresAt &&\n storedSecret.config.expiresAt < Date.now()\n ) {\n await this.delete(key, context);\n return null;\n }\n\n // Handle encrypted value\n if (isEncryptedSecret(storedSecret.value)) {\n return this.keyManager.decrypt(storedSecret.value);\n }\n\n // Plain value in object form\n if (typeof storedSecret.value === \"string\") {\n return storedSecret.value;\n }\n }\n\n return null;\n }\n\n async set(\n key: string,\n value: string,\n context: SecretContext,\n config?: Partial<SecretConfig>,\n ): Promise<boolean> {\n this.ensureSettingsStructure();\n const secrets = this.getSecretsObject();\n const existingStored = secrets[key] as StoredSecret | string | undefined;\n const existingConfig =\n typeof existingStored === \"object\" ? existingStored.config : undefined;\n\n const fullConfig = this.createDefaultConfig(key, context, {\n ...existingConfig,\n ...config,\n });\n\n // Encrypt value if encryption is enabled\n const shouldEncrypt = fullConfig.encrypted !== false;\n const storedValue: string | EncryptedSecret = shouldEncrypt\n ? this.keyManager.encrypt(value)\n : value;\n\n const storedSecret: StoredSecret = {\n value: storedValue,\n config: fullConfig,\n };\n\n // Store directly in character.settings.secrets\n secrets[key] = storedSecret;\n\n logger.debug(`[CharacterSettingsStorage] Set secret: ${key}`);\n return true;\n }\n\n async delete(key: string, _context: SecretContext): Promise<boolean> {\n this.ensureSettingsStructure();\n const secrets = this.getSecretsObject();\n\n if (!(key in secrets)) {\n return false;\n }\n\n delete secrets[key];\n\n logger.debug(`[CharacterSettingsStorage] Deleted secret: ${key}`);\n return true;\n }\n\n async list(_context: SecretContext): Promise<SecretMetadata> {\n const secrets = this.getSecretsObject();\n const metadata: SecretMetadata = {};\n\n for (const [key, stored] of Object.entries(secrets)) {\n if (key === METADATA_KEY) {\n continue;\n }\n\n if (typeof stored === \"object\" && stored !== null) {\n const storedSecret = stored as StoredSecret;\n\n // Check expiration\n if (\n storedSecret.config?.expiresAt &&\n storedSecret.config.expiresAt < Date.now()\n ) {\n continue;\n }\n\n if (storedSecret.config) {\n metadata[key] = { ...storedSecret.config };\n }\n } else {\n // Legacy string-only format\n metadata[key] = this.createDefaultConfig(key, {\n level: \"global\",\n agentId: this.runtime.agentId,\n });\n }\n }\n\n return metadata;\n }\n\n async getConfig(\n key: string,\n context: SecretContext,\n ): Promise<SecretConfig | null> {\n const secrets = this.getSecretsObject();\n const stored = secrets[key];\n\n if (!stored) {\n return null;\n }\n\n if (typeof stored === \"object\" && \"config\" in stored) {\n return { ...(stored as StoredSecret).config };\n }\n\n // Legacy format - create default config\n return this.createDefaultConfig(key, context);\n }\n\n async updateConfig(\n key: string,\n _context: SecretContext,\n config: Partial<SecretConfig>,\n ): Promise<boolean> {\n this.ensureSettingsStructure();\n const secrets = this.getSecretsObject();\n const stored = secrets[key];\n\n if (!stored) {\n return false;\n }\n\n if (typeof stored === \"object\" && \"config\" in stored) {\n const storedSecret = stored as StoredSecret;\n storedSecret.config = {\n ...storedSecret.config,\n ...config,\n };\n secrets[key] = storedSecret;\n } else {\n // Upgrade legacy format\n const defaultConfig = this.createDefaultConfig(key, {\n level: \"global\",\n agentId: this.runtime.agentId,\n });\n const storedSecret: StoredSecret = {\n value: stored as string,\n config: { ...defaultConfig, ...config },\n };\n secrets[key] = storedSecret;\n }\n\n return true;\n }\n\n /**\n * Get the secrets object from character settings\n *\n * Accesses character.settings.secrets directly instead of using getSetting()\n * because getSetting() only returns primitives, not objects.\n */\n private getSecretsObject(): Record<string, StoredSecret | string> {\n this.ensureSettingsStructure();\n const settings = this.runtime.character.settings as Record<string, unknown>;\n const secrets = settings[SECRETS_KEY];\n\n if (!secrets || typeof secrets !== \"object\") {\n return {};\n }\n\n return secrets as Record<string, StoredSecret | string>;\n }\n\n /**\n * Migrate legacy environment variable format to new format\n */\n async migrateFromEnvVars(envVarPrefix: string = \"ENV_\"): Promise<number> {\n let migrated = 0;\n const settings = this.runtime.character?.settings ?? {};\n\n for (const [key, value] of Object.entries(settings)) {\n if (key.startsWith(envVarPrefix) && typeof value === \"string\") {\n const secretKey = key.slice(envVarPrefix.length);\n const exists = await this.exists(secretKey, {\n level: \"global\",\n agentId: this.runtime.agentId,\n });\n\n if (!exists) {\n await this.set(\n secretKey,\n value,\n { level: \"global\", agentId: this.runtime.agentId },\n {\n description: `Migrated from ${key}`,\n encrypted: true,\n },\n );\n migrated++;\n }\n }\n }\n\n logger.info(\n `[CharacterSettingsStorage] Migrated ${migrated} env vars to secrets`,\n );\n return migrated;\n }\n\n /**\n * Get a secret as an environment variable (for backward compatibility)\n */\n async getAsEnvVar(key: string): Promise<string | null> {\n return this.get(key, { level: \"global\", agentId: this.runtime.agentId });\n }\n\n /**\n * Sync a secret to process.env (for plugins that read env vars directly)\n */\n async syncToEnv(key: string, envVarName?: string): Promise<boolean> {\n const value = await this.getAsEnvVar(key);\n if (value === null) {\n return false;\n }\n\n const envKey = envVarName ?? key;\n process.env[envKey] = value;\n return true;\n }\n\n /**\n * Sync all secrets to process.env\n */\n async syncAllToEnv(): Promise<number> {\n const metadata = await this.list({\n level: \"global\",\n agentId: this.runtime.agentId,\n });\n let synced = 0;\n\n for (const key of Object.keys(metadata)) {\n if (await this.syncToEnv(key)) {\n synced++;\n }\n }\n\n return synced;\n }\n}\n","/**\n * World Metadata Storage\n *\n * Stores world-level secrets in the world's metadata.secrets object.\n * This is used for server/channel-specific configuration like Discord tokens.\n */\n\nimport type { IAgentRuntime, UUID, World } from \"@elizaos/core\";\nimport { logger, Role } from \"@elizaos/core\";\nimport type {\n SecretConfig,\n SecretContext,\n SecretMetadata,\n StorageBackend,\n StoredSecret,\n EncryptedSecret,\n} from \"../types.js\";\nimport { BaseSecretStorage } from \"./interface.js\";\nimport { KeyManager, isEncryptedSecret } from \"../crypto/index.js\";\nimport { PermissionDeniedError, StorageError } from \"../types.js\";\n\n/**\n * Extended metadata with secrets support\n * Using index signature for compatibility with World.metadata\n */\ninterface WorldMetadataWithSecrets {\n [key: string]: unknown;\n secrets?: Record<string, StoredSecret | string>;\n}\n\n/**\n * World metadata-based storage for world-level secrets\n *\n * Secrets are stored in world.metadata.secrets with access control\n * based on world roles (OWNER/ADMIN can write, all members can read).\n */\nexport class WorldMetadataStorage extends BaseSecretStorage {\n readonly storageType: StorageBackend = \"world\";\n\n private runtime: IAgentRuntime;\n private keyManager: KeyManager;\n private worldCache: Map<string, World> = new Map();\n\n constructor(runtime: IAgentRuntime, keyManager: KeyManager) {\n super();\n this.runtime = runtime;\n this.keyManager = keyManager;\n }\n\n async initialize(): Promise<void> {\n logger.debug(\"[WorldMetadataStorage] Initialized\");\n }\n\n async exists(key: string, context: SecretContext): Promise<boolean> {\n if (!context.worldId) {\n return false;\n }\n\n const secrets = await this.getWorldSecrets(context.worldId);\n return key in secrets;\n }\n\n async get(key: string, context: SecretContext): Promise<string | null> {\n if (!context.worldId) {\n logger.warn(\"[WorldMetadataStorage] Cannot get secret without worldId\");\n return null;\n }\n\n const secrets = await this.getWorldSecrets(context.worldId);\n const stored = secrets[key];\n\n if (stored === undefined || stored === null) {\n return null;\n }\n\n // Handle different storage formats\n if (typeof stored === \"string\") {\n return stored;\n }\n\n if (typeof stored === \"object\") {\n const storedSecret = stored as StoredSecret;\n\n // Check expiration\n if (\n storedSecret.config?.expiresAt &&\n storedSecret.config.expiresAt < Date.now()\n ) {\n await this.delete(key, context);\n return null;\n }\n\n // Handle encrypted value\n if (isEncryptedSecret(storedSecret.value)) {\n return this.keyManager.decrypt(storedSecret.value);\n }\n\n if (typeof storedSecret.value === \"string\") {\n return storedSecret.value;\n }\n }\n\n return null;\n }\n\n async set(\n key: string,\n value: string,\n context: SecretContext,\n config?: Partial<SecretConfig>,\n ): Promise<boolean> {\n if (!context.worldId) {\n throw new StorageError(\"Cannot set world secret without worldId\");\n }\n\n // Check write permission\n if (context.requesterId) {\n const hasPermission = await this.checkWritePermission(\n context.worldId,\n context.requesterId,\n );\n if (!hasPermission) {\n throw new PermissionDeniedError(key, \"write\", context);\n }\n }\n\n const world = await this.getWorld(context.worldId);\n if (!world) {\n throw new StorageError(`World not found: ${context.worldId}`);\n }\n\n // Ensure metadata structure exists\n if (!world.metadata) {\n (world as { metadata?: unknown }).metadata = {};\n }\n // Use type assertion to access secrets (stored in world metadata)\n const worldMeta = world.metadata as unknown as WorldMetadataWithSecrets;\n if (!worldMeta.secrets) {\n worldMeta.secrets = {};\n }\n\n const secrets = worldMeta.secrets;\n const existingStored = secrets[key] as StoredSecret | string | undefined;\n const existingConfig =\n typeof existingStored === \"object\" ? existingStored.config : undefined;\n\n const fullConfig = this.createDefaultConfig(key, context, {\n ...existingConfig,\n ...config,\n worldId: context.worldId,\n });\n\n // Encrypt value if encryption is enabled\n const shouldEncrypt = fullConfig.encrypted !== false;\n const storedValue: string | EncryptedSecret = shouldEncrypt\n ? this.keyManager.encrypt(value)\n : value;\n\n const storedSecret: StoredSecret = {\n value: storedValue,\n config: fullConfig,\n };\n\n secrets[key] = storedSecret;\n worldMeta.secrets = secrets;\n\n await this.runtime.updateWorld(world);\n this.worldCache.set(context.worldId, world);\n\n logger.debug(\n `[WorldMetadataStorage] Set secret: ${key} for world: ${context.worldId}`,\n );\n return true;\n }\n\n async delete(key: string, context: SecretContext): Promise<boolean> {\n if (!context.worldId) {\n return false;\n }\n\n // Check write permission\n if (context.requesterId) {\n const hasPermission = await this.checkWritePermission(\n context.worldId,\n context.requesterId,\n );\n if (!hasPermission) {\n throw new PermissionDeniedError(key, \"delete\", context);\n }\n }\n\n const world = await this.getWorld(context.worldId);\n if (!world) {\n return false;\n }\n const metadata = world.metadata as WorldMetadataWithSecrets | undefined;\n if (!metadata?.secrets) {\n return false;\n }\n\n const secrets = metadata.secrets;\n if (!(key in secrets)) {\n return false;\n }\n\n delete secrets[key];\n metadata.secrets = secrets;\n\n await this.runtime.updateWorld(world);\n this.worldCache.set(context.worldId, world);\n\n logger.debug(\n `[WorldMetadataStorage] Deleted secret: ${key} from world: ${context.worldId}`,\n );\n return true;\n }\n\n async list(context: SecretContext): Promise<SecretMetadata> {\n if (!context.worldId) {\n return {};\n }\n\n const secrets = await this.getWorldSecrets(context.worldId);\n const metadata: SecretMetadata = {};\n\n for (const [key, stored] of Object.entries(secrets)) {\n if (typeof stored === \"object\" && stored !== null) {\n const storedSecret = stored as StoredSecret;\n\n // Check expiration\n if (\n storedSecret.config?.expiresAt &&\n storedSecret.config.expiresAt < Date.now()\n ) {\n continue;\n }\n\n if (storedSecret.config) {\n metadata[key] = { ...storedSecret.config };\n }\n } else {\n // Legacy string format\n metadata[key] = this.createDefaultConfig(key, context);\n }\n }\n\n return metadata;\n }\n\n async getConfig(\n key: string,\n context: SecretContext,\n ): Promise<SecretConfig | null> {\n if (!context.worldId) {\n return null;\n }\n\n const secrets = await this.getWorldSecrets(context.worldId);\n const stored = secrets[key];\n\n if (!stored) {\n return null;\n }\n\n if (typeof stored === \"object\" && \"config\" in stored) {\n return { ...(stored as StoredSecret).config };\n }\n\n return this.createDefaultConfig(key, context);\n }\n\n async updateConfig(\n key: string,\n context: SecretContext,\n config: Partial<SecretConfig>,\n ): Promise<boolean> {\n if (!context.worldId) {\n return false;\n }\n\n // Check write permission\n if (context.requesterId) {\n const hasPermission = await this.checkWritePermission(\n context.worldId,\n context.requesterId,\n );\n if (!hasPermission) {\n throw new PermissionDeniedError(key, \"write\", context);\n }\n }\n\n const world = await this.getWorld(context.worldId);\n if (!world) {\n return false;\n }\n const metadata = world.metadata as WorldMetadataWithSecrets | undefined;\n if (!metadata?.secrets) {\n return false;\n }\n\n const secrets = metadata.secrets;\n const stored = secrets[key];\n\n if (!stored) {\n return false;\n }\n\n if (typeof stored === \"object\" && \"config\" in stored) {\n const storedSecret = stored as StoredSecret;\n storedSecret.config = {\n ...storedSecret.config,\n ...config,\n };\n secrets[key] = storedSecret;\n } else {\n // Upgrade legacy format\n const defaultConfig = this.createDefaultConfig(key, context);\n const storedSecret: StoredSecret = {\n value: stored as string,\n config: { ...defaultConfig, ...config },\n };\n secrets[key] = storedSecret;\n }\n\n metadata.secrets = secrets;\n await this.runtime.updateWorld(world);\n this.worldCache.set(context.worldId, world);\n\n return true;\n }\n\n /**\n * Get a world from cache or database\n */\n private async getWorld(worldId: string): Promise<World | null> {\n // Check cache first\n const cached = this.worldCache.get(worldId);\n if (cached) {\n return cached;\n }\n\n // Load from database\n const world = await this.runtime.getWorld(worldId as UUID);\n if (world) {\n this.worldCache.set(worldId, world);\n }\n\n return world;\n }\n\n /**\n * Get secrets object from world metadata\n */\n private async getWorldSecrets(\n worldId: string,\n ): Promise<Record<string, StoredSecret | string>> {\n const world = await this.getWorld(worldId);\n const metadata = world?.metadata as WorldMetadataWithSecrets | undefined;\n if (!metadata?.secrets) {\n return {};\n }\n return metadata.secrets;\n }\n\n /**\n * Check if a user has write permission in a world\n */\n private async checkWritePermission(\n worldId: string,\n userId: string,\n ): Promise<boolean> {\n const world = await this.getWorld(worldId);\n if (!world) {\n return false;\n }\n\n // Agent always has permission\n if (userId === this.runtime.agentId) {\n return true;\n }\n\n // Check world roles\n const roles = world.metadata?.roles as Record<string, Role> | undefined;\n if (!roles) {\n return false;\n }\n\n const userRole = roles[userId];\n return userRole === Role.OWNER || userRole === Role.ADMIN;\n }\n\n /**\n * Clear the world cache\n */\n clearCache(): void {\n this.worldCache.clear();\n }\n\n /**\n * Invalidate a specific world in the cache\n */\n invalidateWorld(worldId: string): void {\n this.worldCache.delete(worldId);\n }\n}\n","/**\n * Component Storage\n *\n * Stores user-level secrets as Components in the ElizaOS database.\n * Each user's secrets are isolated via the component's entityId.\n */\n\nimport type { IAgentRuntime, UUID, Component } from \"@elizaos/core\";\nimport { logger, createUniqueUuid } from \"@elizaos/core\";\nimport type {\n SecretConfig,\n SecretContext,\n SecretMetadata,\n StorageBackend,\n StoredSecret,\n EncryptedSecret,\n} from \"../types.js\";\nimport { BaseSecretStorage } from \"./interface.js\";\nimport { KeyManager, isEncryptedSecret } from \"../crypto/index.js\";\nimport { PermissionDeniedError, StorageError } from \"../types.js\";\n\nconst COMPONENT_TYPE = \"secret\";\n\n/**\n * Component data structure for secret storage\n * Index signature added for Metadata compatibility\n */\ninterface SecretComponentData {\n key: string;\n value: string | EncryptedSecret;\n config: SecretConfig;\n updatedAt: number;\n [key: string]: string | EncryptedSecret | SecretConfig | number | undefined;\n}\n\n/**\n * Component-based storage for user-level secrets\n *\n * Each secret is stored as a Component with type='secret' and entityId\n * set to the user's ID, providing natural isolation per user.\n */\nexport class ComponentSecretStorage extends BaseSecretStorage {\n readonly storageType: StorageBackend = \"component\";\n\n private runtime: IAgentRuntime;\n private keyManager: KeyManager;\n\n constructor(runtime: IAgentRuntime, keyManager: KeyManager) {\n super();\n this.runtime = runtime;\n this.keyManager = keyManager;\n }\n\n async initialize(): Promise<void> {\n logger.debug(\"[ComponentSecretStorage] Initialized\");\n }\n\n async exists(key: string, context: SecretContext): Promise<boolean> {\n if (!context.userId) {\n return false;\n }\n\n const component = await this.findSecretComponent(context.userId, key);\n return component !== null;\n }\n\n async get(key: string, context: SecretContext): Promise<string | null> {\n if (!context.userId) {\n logger.warn(\"[ComponentSecretStorage] Cannot get secret without userId\");\n return null;\n }\n\n // Check permission - only the user can access their own secrets\n if (context.requesterId && context.requesterId !== context.userId) {\n throw new PermissionDeniedError(key, \"read\", context);\n }\n\n const component = await this.findSecretComponent(context.userId, key);\n if (!component) {\n return null;\n }\n\n const data = component.data as SecretComponentData;\n if (!data) {\n return null;\n }\n\n // Check expiration\n if (data.config?.expiresAt && data.config.expiresAt < Date.now()) {\n await this.delete(key, context);\n return null;\n }\n\n // Handle encrypted value\n if (isEncryptedSecret(data.value)) {\n return this.keyManager.decrypt(data.value);\n }\n\n if (typeof data.value === \"string\") {\n return data.value;\n }\n\n return null;\n }\n\n async set(\n key: string,\n value: string,\n context: SecretContext,\n config?: Partial<SecretConfig>,\n ): Promise<boolean> {\n if (!context.userId) {\n throw new StorageError(\"Cannot set user secret without userId\");\n }\n\n // Check permission - only the user can set their own secrets\n if (context.requesterId && context.requesterId !== context.userId) {\n throw new PermissionDeniedError(key, \"write\", context);\n }\n\n const existingComponent = await this.findSecretComponent(\n context.userId,\n key,\n );\n const existingData = existingComponent?.data as\n | SecretComponentData\n | undefined;\n const existingConfig = existingData?.config;\n\n const fullConfig = this.createDefaultConfig(key, context, {\n ...existingConfig,\n ...config,\n ownerId: context.userId,\n });\n\n // Encrypt value if encryption is enabled\n const shouldEncrypt = fullConfig.encrypted !== false;\n const storedValue: string | EncryptedSecret = shouldEncrypt\n ? this.keyManager.encrypt(value)\n : value;\n\n const componentData: SecretComponentData = {\n key,\n value: storedValue,\n config: fullConfig,\n updatedAt: Date.now(),\n };\n\n if (existingComponent) {\n // Update existing component\n await this.runtime.updateComponent({\n ...existingComponent,\n data: componentData as unknown as Component[\"data\"],\n });\n logger.debug(\n `[ComponentSecretStorage] Updated secret: ${key} for user: ${context.userId}`,\n );\n } else {\n // Create new component\n const newComponent: Component = {\n id: createUniqueUuid(this.runtime, `${context.userId}-secret-${key}`),\n createdAt: Date.now(),\n entityId: context.userId as UUID,\n agentId: this.runtime.agentId,\n roomId: this.runtime.agentId,\n worldId: this.runtime.agentId,\n sourceEntityId: context.userId as UUID,\n type: COMPONENT_TYPE,\n data: componentData as unknown as Component[\"data\"],\n };\n\n await this.runtime.createComponent(newComponent);\n logger.debug(\n `[ComponentSecretStorage] Created secret: ${key} for user: ${context.userId}`,\n );\n }\n\n return true;\n }\n\n async delete(key: string, context: SecretContext): Promise<boolean> {\n if (!context.userId) {\n return false;\n }\n\n // Check permission - only the user can delete their own secrets\n if (context.requesterId && context.requesterId !== context.userId) {\n throw new PermissionDeniedError(key, \"delete\", context);\n }\n\n const component = await this.findSecretComponent(context.userId, key);\n if (!component) {\n return false;\n }\n\n await this.runtime.deleteComponent(component.id);\n logger.debug(\n `[ComponentSecretStorage] Deleted secret: ${key} for user: ${context.userId}`,\n );\n return true;\n }\n\n async list(context: SecretContext): Promise<SecretMetadata> {\n if (!context.userId) {\n return {};\n }\n\n // Check permission\n if (context.requesterId && context.requesterId !== context.userId) {\n throw new PermissionDeniedError(\"*\", \"read\", context);\n }\n\n const components = await this.runtime.getComponents(context.userId as UUID);\n const metadata: SecretMetadata = {};\n\n for (const component of components) {\n if (component.type !== COMPONENT_TYPE) {\n continue;\n }\n\n const data = component.data as SecretComponentData;\n if (!data?.key || !data?.config) {\n continue;\n }\n\n // Check expiration\n if (data.config.expiresAt && data.config.expiresAt < Date.now()) {\n continue;\n }\n\n metadata[data.key] = { ...data.config };\n }\n\n return metadata;\n }\n\n async getConfig(\n key: string,\n context: SecretContext,\n ): Promise<SecretConfig | null> {\n if (!context.userId) {\n return null;\n }\n\n const component = await this.findSecretComponent(context.userId, key);\n if (!component) {\n return null;\n }\n\n const data = component.data as SecretComponentData;\n return data?.config ? { ...data.config } : null;\n }\n\n async updateConfig(\n key: string,\n context: SecretContext,\n config: Partial<SecretConfig>,\n ): Promise<boolean> {\n if (!context.userId) {\n return false;\n }\n\n // Check permission\n if (context.requesterId && context.requesterId !== context.userId) {\n throw new PermissionDeniedError(key, \"write\", context);\n }\n\n const component = await this.findSecretComponent(context.userId, key);\n if (!component) {\n return false;\n }\n\n const data = component.data as SecretComponentData;\n if (!data) {\n return false;\n }\n\n data.config = {\n ...data.config,\n ...config,\n };\n data.updatedAt = Date.now();\n\n await this.runtime.updateComponent({\n ...component,\n data: data as unknown as Component[\"data\"],\n });\n\n return true;\n }\n\n /**\n * Find a secret component for a user by key\n */\n private async findSecretComponent(\n userId: string,\n key: string,\n ): Promise<Component | null> {\n const components = await this.runtime.getComponents(userId as UUID);\n\n for (const component of components) {\n if (component.type !== COMPONENT_TYPE) {\n continue;\n }\n\n const data = component.data as SecretComponentData | undefined;\n if (data?.key === key) {\n return component;\n }\n }\n\n return null;\n }\n\n /**\n * Get all secret keys for a user\n */\n async listKeys(userId: string): Promise<string[]> {\n const components = await this.runtime.getComponents(userId as UUID);\n const keys: string[] = [];\n\n for (const component of components) {\n if (component.type !== COMPONENT_TYPE) {\n continue;\n }\n\n const data = component.data as SecretComponentData;\n if (data?.key) {\n keys.push(data.key);\n }\n }\n\n return keys;\n }\n\n /**\n * Delete all secrets for a user\n */\n async deleteAllForUser(userId: string): Promise<number> {\n const components = await this.runtime.getComponents(userId as UUID);\n let deleted = 0;\n\n for (const component of components) {\n if (component.type !== COMPONENT_TYPE) {\n continue;\n }\n\n await this.runtime.deleteComponent(component.id);\n deleted++;\n }\n\n logger.info(\n `[ComponentSecretStorage] Deleted ${deleted} secrets for user: ${userId}`,\n );\n return deleted;\n }\n\n /**\n * Count secrets for a user\n */\n async countForUser(userId: string): Promise<number> {\n const components = await this.runtime.getComponents(userId as UUID);\n let count = 0;\n\n for (const component of components) {\n if (component.type === COMPONENT_TYPE) {\n count++;\n }\n }\n\n return count;\n }\n}\n","/**\n * Secret Validation Module\n *\n * Provides validation strategies for different types of secrets\n * including API keys, URLs, and custom validation.\n */\n\nimport { logger } from \"@elizaos/core\";\nimport type {\n ValidationResult,\n ValidationStrategy,\n CustomValidator,\n} from \"./types.js\";\n\n/**\n * Validation strategy implementations\n */\nexport const ValidationStrategies: Record<string, CustomValidator> = {\n /**\n * No validation - always passes\n */\n none: async (_key: string, _value: string): Promise<ValidationResult> => ({\n isValid: true,\n validatedAt: Date.now(),\n }),\n\n /**\n * OpenAI API key validation\n * Format: sk-... or sk-proj-...\n */\n \"api_key:openai\": async (\n key: string,\n value: string,\n ): Promise<ValidationResult> => {\n const validatedAt = Date.now();\n\n if (!value.startsWith(\"sk-\")) {\n return {\n isValid: false,\n error: 'OpenAI API key must start with \"sk-\"',\n validatedAt,\n };\n }\n\n if (value.length < 20) {\n return {\n isValid: false,\n error: \"OpenAI API key is too short\",\n validatedAt,\n };\n }\n\n // Optionally verify by making a test request\n const shouldVerify = process.env.VALIDATE_API_KEYS === \"true\";\n if (shouldVerify) {\n const verified = await verifyOpenAIKey(value);\n if (!verified.isValid) {\n return { ...verified, validatedAt };\n }\n }\n\n return { isValid: true, validatedAt };\n },\n\n /**\n * Anthropic API key validation\n * Format: sk-ant-...\n */\n \"api_key:anthropic\": async (\n key: string,\n value: string,\n ): Promise<ValidationResult> => {\n const validatedAt = Date.now();\n\n if (!value.startsWith(\"sk-ant-\")) {\n return {\n isValid: false,\n error: 'Anthropic API key must start with \"sk-ant-\"',\n validatedAt,\n };\n }\n\n if (value.length < 30) {\n return {\n isValid: false,\n error: \"Anthropic API key is too short\",\n validatedAt,\n };\n }\n\n // Optionally verify by making a test request\n const shouldVerify = process.env.VALIDATE_API_KEYS === \"true\";\n if (shouldVerify) {\n const verified = await verifyAnthropicKey(value);\n if (!verified.isValid) {\n return { ...verified, validatedAt };\n }\n }\n\n return { isValid: true, validatedAt };\n },\n\n /**\n * Groq API key validation\n * Format: gsk_...\n */\n \"api_key:groq\": async (\n key: string,\n value: string,\n ): Promise<ValidationResult> => {\n const validatedAt = Date.now();\n\n if (!value.startsWith(\"gsk_\")) {\n return {\n isValid: false,\n error: 'Groq API key must start with \"gsk_\"',\n validatedAt,\n };\n }\n\n if (value.length < 20) {\n return {\n isValid: false,\n error: \"Groq API key is too short\",\n validatedAt,\n };\n }\n\n return { isValid: true, validatedAt };\n },\n\n /**\n * Google API key validation\n * Format: AIza...\n */\n \"api_key:google\": async (\n key: string,\n value: string,\n ): Promise<ValidationResult> => {\n const validatedAt = Date.now();\n\n if (!value.startsWith(\"AIza\")) {\n return {\n isValid: false,\n error: 'Google API key must start with \"AIza\"',\n validatedAt,\n };\n }\n\n if (value.length < 30) {\n return {\n isValid: false,\n error: \"Google API key is too short\",\n validatedAt,\n };\n }\n\n return { isValid: true, validatedAt };\n },\n\n /**\n * Mistral API key validation\n */\n \"api_key:mistral\": async (\n key: string,\n value: string,\n ): Promise<ValidationResult> => {\n const validatedAt = Date.now();\n\n if (value.length < 20) {\n return {\n isValid: false,\n error: \"Mistral API key is too short\",\n validatedAt,\n };\n }\n\n return { isValid: true, validatedAt };\n },\n\n /**\n * Cohere API key validation\n */\n \"api_key:cohere\": async (\n key: string,\n value: string,\n ): Promise<ValidationResult> => {\n const validatedAt = Date.now();\n\n if (value.length < 20) {\n return {\n isValid: false,\n error: \"Cohere API key is too short\",\n validatedAt,\n };\n }\n\n return { isValid: true, validatedAt };\n },\n\n /**\n * URL format validation\n */\n \"url:valid\": async (\n key: string,\n value: string,\n ): Promise<ValidationResult> => {\n const validatedAt = Date.now();\n\n try {\n new URL(value);\n return { isValid: true, validatedAt };\n } catch {\n return {\n isValid: false,\n error: \"Invalid URL format\",\n validatedAt,\n };\n }\n },\n\n /**\n * URL reachability validation\n */\n \"url:reachable\": async (\n key: string,\n value: string,\n ): Promise<ValidationResult> => {\n const validatedAt = Date.now();\n\n try {\n new URL(value);\n } catch {\n return {\n isValid: false,\n error: \"Invalid URL format\",\n validatedAt,\n };\n }\n\n try {\n const response = await fetch(value, {\n method: \"HEAD\",\n signal: AbortSignal.timeout(5000),\n });\n\n if (!response.ok) {\n return {\n isValid: false,\n error: `URL returned status ${response.status}`,\n validatedAt,\n };\n }\n\n return { isValid: true, validatedAt };\n } catch (error) {\n return {\n isValid: false,\n error: `URL is not reachable: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n validatedAt,\n };\n }\n },\n\n /**\n * Custom validation placeholder\n */\n custom: async (key: string, value: string): Promise<ValidationResult> => {\n // Custom validation should be registered separately\n return {\n isValid: true,\n details: \"Custom validation not implemented\",\n validatedAt: Date.now(),\n };\n },\n};\n\n/**\n * Registry for custom validators\n */\nconst customValidators: Map<string, CustomValidator> = new Map();\n\n/**\n * Register a custom validator\n */\nexport function registerValidator(\n name: string,\n validator: CustomValidator,\n): void {\n customValidators.set(name, validator);\n logger.debug(`[Validation] Registered custom validator: ${name}`);\n}\n\n/**\n * Unregister a custom validator\n */\nexport function unregisterValidator(name: string): boolean {\n return customValidators.delete(name);\n}\n\n/**\n * Get a validator by strategy name\n */\nexport function getValidator(strategy: string): CustomValidator | undefined {\n // Check built-in strategies first\n if (strategy in ValidationStrategies) {\n return ValidationStrategies[strategy];\n }\n\n // Check custom validators\n return customValidators.get(strategy);\n}\n\n/**\n * Validate a secret value\n */\nexport async function validateSecret(\n key: string,\n value: string,\n strategy?: string,\n): Promise<ValidationResult> {\n const strategyName = strategy ?? \"none\";\n const validator = getValidator(strategyName);\n\n if (!validator) {\n logger.warn(`[Validation] Unknown validation strategy: ${strategyName}`);\n return {\n isValid: true,\n details: `Unknown validation strategy: ${strategyName}`,\n validatedAt: Date.now(),\n };\n }\n\n try {\n return await validator(key, value);\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : \"Validation error\";\n logger.error(`[Validation] Error validating ${key}: ${errorMessage}`);\n return {\n isValid: false,\n error: errorMessage,\n validatedAt: Date.now(),\n };\n }\n}\n\n/**\n * Infer validation strategy from secret key name\n */\nexport function inferValidationStrategy(key: string): ValidationStrategy {\n const upperKey = key.toUpperCase();\n\n if (upperKey.includes(\"OPENAI\") && upperKey.includes(\"KEY\")) {\n return \"api_key:openai\";\n }\n\n if (upperKey.includes(\"ANTHROPIC\") && upperKey.includes(\"KEY\")) {\n return \"api_key:anthropic\";\n }\n\n if (upperKey.includes(\"GROQ\") && upperKey.includes(\"KEY\")) {\n return \"api_key:groq\";\n }\n\n if (upperKey.includes(\"GOOGLE\") && upperKey.includes(\"KEY\")) {\n return \"api_key:google\";\n }\n\n if (upperKey.includes(\"MISTRAL\") && upperKey.includes(\"KEY\")) {\n return \"api_key:mistral\";\n }\n\n if (upperKey.includes(\"COHERE\") && upperKey.includes(\"KEY\")) {\n return \"api_key:cohere\";\n }\n\n if (upperKey.includes(\"URL\") || upperKey.includes(\"ENDPOINT\")) {\n return \"url:valid\";\n }\n\n return \"none\";\n}\n\n// ============================================================================\n// API Key Verification Helpers\n// ============================================================================\n\n/**\n * Verify OpenAI API key by making a test request\n */\nasync function verifyOpenAIKey(\n apiKey: string,\n): Promise<{ isValid: boolean; error?: string }> {\n try {\n const response = await fetch(\"https://api.openai.com/v1/models\", {\n method: \"GET\",\n headers: {\n Authorization: `Bearer ${apiKey}`,\n },\n signal: AbortSignal.timeout(10000),\n });\n\n if (response.status === 401) {\n return { isValid: false, error: \"Invalid API key\" };\n }\n\n if (response.status === 429) {\n // Rate limited but key is valid\n return { isValid: true };\n }\n\n if (!response.ok) {\n return {\n isValid: false,\n error: `API returned status ${response.status}`,\n };\n }\n\n return { isValid: true };\n } catch (error) {\n return {\n isValid: false,\n error: `Failed to verify: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n };\n }\n}\n\n/**\n * Verify Anthropic API key by making a test request\n */\nasync function verifyAnthropicKey(\n apiKey: string,\n): Promise<{ isValid: boolean; error?: string }> {\n try {\n const response = await fetch(\"https://api.anthropic.com/v1/messages\", {\n method: \"POST\",\n headers: {\n \"x-api-key\": apiKey,\n \"anthropic-version\": \"2023-06-01\",\n \"content-type\": \"application/json\",\n },\n body: JSON.stringify({\n model: \"claude-3-haiku-20240307\",\n max_tokens: 1,\n messages: [{ role: \"user\", content: \"Hi\" }],\n }),\n signal: AbortSignal.timeout(10000),\n });\n\n if (response.status === 401) {\n return { isValid: false, error: \"Invalid API key\" };\n }\n\n if (response.status === 429) {\n // Rate limited but key is valid\n return { isValid: true };\n }\n\n // 400 with \"model\" error means key is valid but request is invalid\n // We don't care about that for validation\n if (response.status === 400) {\n const body = (await response.json().catch(() => ({}))) as {\n error?: { type?: string };\n };\n if (body.error?.type === \"invalid_request_error\") {\n return { isValid: true };\n }\n }\n\n if (!response.ok && response.status !== 400) {\n return {\n isValid: false,\n error: `API returned status ${response.status}`,\n };\n }\n\n return { isValid: true };\n } catch (error) {\n return {\n isValid: false,\n error: `Failed to verify: ${error instanceof Error ? error.message : \"Unknown error\"}`,\n };\n }\n}\n\n// ============================================================================\n// Exports\n// ============================================================================\n\nexport { validateSecret as validate };\n","/**\n * Plugin Activator Service\n *\n * Enables dynamic plugin activation when required secrets become available.\n * Plugins can register for activation with their secret requirements,\n * and will be activated automatically once all secrets are present.\n */\n\nimport {\n Service,\n logger,\n type IAgentRuntime,\n type Plugin,\n type ServiceTypeName,\n} from \"@elizaos/core\";\nimport type {\n PendingPluginActivation,\n PluginActivatorConfig,\n PluginRequirementStatus,\n PluginSecretRequirement,\n SecretContext,\n} from \"../types.js\";\nimport { SecretsService, SECRETS_SERVICE_TYPE } from \"./secrets.js\";\n\n/**\n * Service type identifier\n */\nexport const PLUGIN_ACTIVATOR_SERVICE_TYPE =\n \"PLUGIN_ACTIVATOR\" as ServiceTypeName;\n\n/**\n * Default configuration\n */\nconst DEFAULT_CONFIG: PluginActivatorConfig = {\n enableAutoActivation: true,\n pollingIntervalMs: 5000,\n maxWaitMs: 0, // 0 = wait forever\n};\n\n/**\n * Extended Plugin interface with secret requirements\n */\nexport interface PluginWithSecrets extends Plugin {\n /** Required secrets for this plugin to function */\n requiredSecrets?: Record<string, PluginSecretRequirement>;\n\n /** Called when all required secrets become available */\n onSecretsReady?: (runtime: IAgentRuntime) => Promise<void>;\n\n /** Called when a required secret changes */\n onSecretChanged?: (\n key: string,\n value: string | null,\n runtime: IAgentRuntime,\n ) => Promise<void>;\n}\n\n/**\n * Plugin Activator Service\n *\n * Manages the lifecycle of plugins that depend on secrets:\n * - Tracks plugins waiting for secrets\n * - Automatically activates plugins when requirements are met\n * - Notifies plugins when their secrets change\n */\nexport class PluginActivatorService extends Service {\n static serviceType: ServiceTypeName = PLUGIN_ACTIVATOR_SERVICE_TYPE;\n capabilityDescription =\n \"Activate plugins dynamically when their required secrets become available\";\n\n private activatorConfig: PluginActivatorConfig;\n private secretsService: SecretsService | null = null;\n private pendingPlugins: Map<string, PendingPluginActivation> = new Map();\n private activatedPlugins: Set<string> = new Set();\n private pluginSecretMapping: Map<string, Set<string>> = new Map();\n private pollingInterval: ReturnType<typeof setInterval> | null = null;\n private unsubscribeSecretChanges: (() => void) | null = null;\n\n constructor(\n runtime?: IAgentRuntime,\n config?: Partial<PluginActivatorConfig>,\n ) {\n super(runtime);\n this.activatorConfig = { ...DEFAULT_CONFIG, ...config };\n }\n\n /**\n * Start the service\n */\n static async start(\n runtime: IAgentRuntime,\n config?: Partial<PluginActivatorConfig>,\n ): Promise<PluginActivatorService> {\n const service = new PluginActivatorService(runtime, config);\n await service.initialize();\n return service;\n }\n\n /**\n * Initialize the service\n */\n private async initialize(): Promise<void> {\n logger.info(\"[PluginActivator] Initializing\");\n\n // Get secrets service\n this.secretsService =\n this.runtime.getService<SecretsService>(SECRETS_SERVICE_TYPE);\n if (!this.secretsService) {\n logger.warn(\n \"[PluginActivator] SecretsService not available, activation will be limited\",\n );\n } else {\n // Subscribe to secret changes\n this.unsubscribeSecretChanges = this.secretsService.onAnySecretChanged(\n async (key, value, context) => {\n await this.onSecretChanged(key, value, context);\n },\n );\n }\n\n // Start polling if auto-activation enabled\n if (\n this.activatorConfig.enableAutoActivation &&\n this.activatorConfig.pollingIntervalMs > 0\n ) {\n this.startPolling();\n }\n\n logger.info(\"[PluginActivator] Initialized\");\n }\n\n /**\n * Stop the service\n */\n async stop(): Promise<void> {\n logger.info(\"[PluginActivator] Stopping\");\n\n if (this.pollingInterval) {\n clearInterval(this.pollingInterval);\n this.pollingInterval = null;\n }\n\n if (this.unsubscribeSecretChanges) {\n this.unsubscribeSecretChanges();\n this.unsubscribeSecretChanges = null;\n }\n\n this.pendingPlugins.clear();\n this.activatedPlugins.clear();\n this.pluginSecretMapping.clear();\n\n logger.info(\"[PluginActivator] Stopped\");\n }\n\n // ============================================================================\n // Plugin Registration\n // ============================================================================\n\n /**\n * Register a plugin for activation when secrets are ready\n */\n async registerPlugin(\n plugin: PluginWithSecrets,\n activationCallback?: () => Promise<void>,\n ): Promise<boolean> {\n const pluginId = plugin.name;\n\n if (this.activatedPlugins.has(pluginId)) {\n logger.debug(`[PluginActivator] Plugin ${pluginId} already activated`);\n return true;\n }\n\n if (\n !plugin.requiredSecrets ||\n Object.keys(plugin.requiredSecrets).length === 0\n ) {\n // No secrets required, activate immediately\n logger.info(\n `[PluginActivator] Plugin ${pluginId} has no secret requirements, activating`,\n );\n return this.activatePlugin(pluginId, plugin, activationCallback);\n }\n\n // Check current secret status\n const status = await this.checkPluginRequirements(plugin);\n\n if (status.ready) {\n // All secrets available, activate now\n logger.info(\n `[PluginActivator] Plugin ${pluginId} has all required secrets, activating`,\n );\n return this.activatePlugin(pluginId, plugin, activationCallback);\n }\n\n // Queue for later activation\n logger.info(\n `[PluginActivator] Plugin ${pluginId} queued, waiting for: ${status.missingRequired.join(\", \")}`,\n );\n\n const requiredSecrets = Object.entries(plugin.requiredSecrets)\n .filter(([_, req]) => req.required)\n .map(([key]) => key);\n\n this.pendingPlugins.set(pluginId, {\n pluginId,\n requiredSecrets,\n callback: async () => {\n await this.activatePlugin(pluginId, plugin, activationCallback);\n },\n registeredAt: Date.now(),\n });\n\n // Track which secrets this plugin needs\n for (const secretKey of requiredSecrets) {\n const plugins = this.pluginSecretMapping.get(secretKey) ?? new Set();\n plugins.add(pluginId);\n this.pluginSecretMapping.set(secretKey, plugins);\n }\n\n return false;\n }\n\n /**\n * Unregister a pending plugin\n */\n unregisterPlugin(pluginId: string): boolean {\n const pending = this.pendingPlugins.get(pluginId);\n if (!pending) {\n return false;\n }\n\n // Remove from secret mapping\n for (const secretKey of pending.requiredSecrets) {\n const plugins = this.pluginSecretMapping.get(secretKey);\n if (plugins) {\n plugins.delete(pluginId);\n if (plugins.size === 0) {\n this.pluginSecretMapping.delete(secretKey);\n }\n }\n }\n\n this.pendingPlugins.delete(pluginId);\n logger.info(`[PluginActivator] Unregistered plugin ${pluginId}`);\n return true;\n }\n\n // ============================================================================\n // Plugin Activation\n // ============================================================================\n\n /**\n * Activate a plugin\n */\n private async activatePlugin(\n pluginId: string,\n plugin: PluginWithSecrets,\n callback?: () => Promise<void>,\n ): Promise<boolean> {\n try {\n // Call the activation callback\n if (callback) {\n await callback();\n }\n\n // Call plugin's onSecretsReady if defined\n if (plugin.onSecretsReady) {\n await plugin.onSecretsReady(this.runtime);\n }\n\n this.activatedPlugins.add(pluginId);\n this.pendingPlugins.delete(pluginId);\n\n logger.info(`[PluginActivator] Activated plugin ${pluginId}`);\n return true;\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n logger.error(\n `[PluginActivator] Failed to activate plugin ${pluginId}: ${errorMessage}`,\n );\n return false;\n }\n }\n\n /**\n * Check requirements for a plugin\n */\n async checkPluginRequirements(\n plugin: PluginWithSecrets,\n ): Promise<PluginRequirementStatus> {\n if (!plugin.requiredSecrets) {\n return {\n pluginId: plugin.name,\n ready: true,\n missingRequired: [],\n missingOptional: [],\n invalid: [],\n message: \"No secrets required\",\n };\n }\n\n if (!this.secretsService) {\n // Can't check without secrets service\n const required = Object.entries(plugin.requiredSecrets)\n .filter(([_, req]) => req.required)\n .map(([key]) => key);\n\n return {\n pluginId: plugin.name,\n ready: required.length === 0,\n missingRequired: required,\n missingOptional: [],\n invalid: [],\n message: \"SecretsService not available\",\n };\n }\n\n const result = await this.secretsService.checkPluginRequirements(\n plugin.name,\n plugin.requiredSecrets,\n );\n return {\n pluginId: plugin.name,\n ...result,\n message: result.ready\n ? \"All secrets available\"\n : `Missing: ${result.missingRequired.join(\", \")}`,\n };\n }\n\n /**\n * Get status of all registered plugins\n */\n getPluginStatuses(): Map<\n string,\n { pending: boolean; activated: boolean; missingSecrets: string[] }\n > {\n const statuses = new Map<\n string,\n { pending: boolean; activated: boolean; missingSecrets: string[] }\n >();\n\n for (const [pluginId, pending] of this.pendingPlugins) {\n statuses.set(pluginId, {\n pending: true,\n activated: false,\n missingSecrets: pending.requiredSecrets,\n });\n }\n\n for (const pluginId of this.activatedPlugins) {\n statuses.set(pluginId, {\n pending: false,\n activated: true,\n missingSecrets: [],\n });\n }\n\n return statuses;\n }\n\n // ============================================================================\n // Secret Change Handling\n // ============================================================================\n\n /**\n * Handle secret change event\n */\n private async onSecretChanged(\n key: string,\n value: string | null,\n context: SecretContext,\n ): Promise<void> {\n // Only process global secret changes for plugin activation\n if (context.level !== \"global\") {\n return;\n }\n\n // Check if any pending plugins need this secret\n const affectedPlugins = this.pluginSecretMapping.get(key);\n if (!affectedPlugins || affectedPlugins.size === 0) {\n return;\n }\n\n logger.debug(\n `[PluginActivator] Secret ${key} changed, checking ${affectedPlugins.size} plugins`,\n );\n\n for (const pluginId of affectedPlugins) {\n const pending = this.pendingPlugins.get(pluginId);\n if (!pending) {\n continue;\n }\n\n // Check if all required secrets are now available\n const missing = await this.getMissingSecrets(pending.requiredSecrets);\n if (missing.length === 0) {\n logger.info(\n `[PluginActivator] All secrets available for ${pluginId}, activating`,\n );\n await pending.callback();\n }\n }\n }\n\n /**\n * Get missing secrets from a list\n */\n private async getMissingSecrets(keys: string[]): Promise<string[]> {\n if (!this.secretsService) {\n return keys;\n }\n\n return this.secretsService.getMissingSecrets(keys, \"global\");\n }\n\n // ============================================================================\n // Polling\n // ============================================================================\n\n /**\n * Start polling for pending plugins\n */\n private startPolling(): void {\n if (this.pollingInterval) {\n return;\n }\n\n this.pollingInterval = setInterval(async () => {\n await this.checkPendingPlugins();\n }, this.activatorConfig.pollingIntervalMs);\n\n logger.debug(\n `[PluginActivator] Started polling every ${this.activatorConfig.pollingIntervalMs}ms`,\n );\n }\n\n /**\n * Stop polling\n */\n private stopPolling(): void {\n if (this.pollingInterval) {\n clearInterval(this.pollingInterval);\n this.pollingInterval = null;\n }\n }\n\n /**\n * Check all pending plugins\n */\n private async checkPendingPlugins(): Promise<void> {\n if (this.pendingPlugins.size === 0) {\n return;\n }\n\n const now = Date.now();\n\n for (const [pluginId, pending] of this.pendingPlugins) {\n // Check timeout\n if (this.activatorConfig.maxWaitMs > 0) {\n const elapsed = now - pending.registeredAt;\n if (elapsed > this.activatorConfig.maxWaitMs) {\n logger.warn(\n `[PluginActivator] Plugin ${pluginId} timed out waiting for secrets`,\n );\n this.unregisterPlugin(pluginId);\n continue;\n }\n }\n\n // Check if secrets are now available\n const missing = await this.getMissingSecrets(pending.requiredSecrets);\n if (missing.length === 0) {\n logger.info(`[PluginActivator] Secrets now available for ${pluginId}`);\n await pending.callback();\n }\n }\n }\n\n // ============================================================================\n // Utility Methods\n // ============================================================================\n\n /**\n * Get list of pending plugins\n */\n getPendingPlugins(): string[] {\n return Array.from(this.pendingPlugins.keys());\n }\n\n /**\n * Get list of activated plugins\n */\n getActivatedPlugins(): string[] {\n return Array.from(this.activatedPlugins);\n }\n\n /**\n * Check if a plugin is pending\n */\n isPending(pluginId: string): boolean {\n return this.pendingPlugins.has(pluginId);\n }\n\n /**\n * Check if a plugin is activated\n */\n isActivated(pluginId: string): boolean {\n return this.activatedPlugins.has(pluginId);\n }\n\n /**\n * Get secrets required by pending plugins\n */\n getRequiredSecrets(): Set<string> {\n const secrets = new Set<string>();\n for (const pending of this.pendingPlugins.values()) {\n for (const key of pending.requiredSecrets) {\n secrets.add(key);\n }\n }\n return secrets;\n }\n\n /**\n * Get plugins waiting for a specific secret\n */\n getPluginsWaitingFor(secretKey: string): string[] {\n const plugins = this.pluginSecretMapping.get(secretKey);\n return plugins ? Array.from(plugins) : [];\n }\n}\n","/**\n * Set Secret Action\n *\n * Allows the agent to set secrets from user input through natural language.\n * Extracts key-value pairs and stores them at the appropriate level.\n */\n\nimport {\n type Action,\n type ActionResult,\n type IAgentRuntime,\n type Memory,\n type State,\n type HandlerCallback,\n type JsonValue,\n ModelType,\n logger,\n composePromptFromState,\n type ActionExample,\n} from \"@elizaos/core\";\nimport { SecretsService, SECRETS_SERVICE_TYPE } from \"../services/secrets.js\";\nimport type { SecretContext, SecretType } from \"../types.js\";\nimport { inferValidationStrategy } from \"../validation.js\";\n\n/**\n * Type for extracted secrets from user message\n */\ninterface ExtractedSecret {\n key: string;\n value: string;\n description?: string;\n type?: \"api_key\" | \"secret\" | \"credential\" | \"url\" | \"config\";\n}\n\ninterface ExtractedSecrets {\n secrets: ExtractedSecret[];\n level?: \"global\" | \"world\" | \"user\";\n}\n\n/**\n * Template for extracting secrets from user message\n */\nconst extractSecretsTemplate = `You are extracting secret/configuration values from the user's message.\n\nThe user wants to set one or more secrets. Extract:\n1. The secret key (should be UPPERCASE_WITH_UNDERSCORES format)\n2. The secret value\n3. Optional description\n4. Secret type (api_key, secret, credential, url, or config)\n\nCommon patterns:\n- \"Set my OpenAI key to sk-...\" -> key: OPENAI_API_KEY, value: sk-...\n- \"My Anthropic API key is sk-ant-...\" -> key: ANTHROPIC_API_KEY, value: sk-ant-...\n- \"Use this Discord token: ...\" -> key: DISCORD_BOT_TOKEN, value: ...\n- \"Set DATABASE_URL to postgres://...\" -> key: DATABASE_URL, value: postgres://...\n\n{{recentMessages}}\n\nExtract the secrets from the user's message. If the key name isn't explicitly specified, infer an appropriate UPPERCASE_WITH_UNDERSCORES name based on the context.`;\n\n/**\n * Set Secret Action\n */\nexport const setSecretAction: Action = {\n name: \"SET_SECRET\",\n similes: [\n \"STORE_SECRET\",\n \"SAVE_SECRET\",\n \"SET_API_KEY\",\n \"CONFIGURE_SECRET\",\n \"SET_ENV_VAR\",\n \"STORE_API_KEY\",\n \"SET_TOKEN\",\n \"SAVE_KEY\",\n ],\n description:\n \"Set a secret value (API key, token, password, etc.) for the agent to use\",\n\n validate: async (\n runtime: IAgentRuntime,\n message: Memory,\n state?: State,\n ): Promise<boolean> => {\n const text = message.content.text?.toLowerCase() ?? \"\";\n\n // Check for secret-setting intent\n const setPatterns = [\n /\\bset\\b.*\\b(key|token|secret|password|credential|api)/i,\n /\\bmy\\b.*\\b(key|token|secret|api)\\b.*\\bis\\b/i,\n /\\buse\\b.*\\b(key|token|this)\\b/i,\n /\\bstore\\b.*\\b(key|token|secret)/i,\n /\\bconfigure\\b.*\\b(key|token|secret)/i,\n /\\bsave\\b.*\\b(key|token|secret)/i,\n /sk-[a-zA-Z0-9]+/i, // OpenAI key pattern\n /sk-ant-[a-zA-Z0-9]+/i, // Anthropic key pattern\n /gsk_[a-zA-Z0-9]+/i, // Groq key pattern\n ];\n\n const hasIntent = setPatterns.some((pattern) => pattern.test(text));\n if (!hasIntent) {\n return false;\n }\n\n // Check if secrets service is available\n const secretsService =\n runtime.getService<SecretsService>(SECRETS_SERVICE_TYPE);\n return secretsService !== null;\n },\n\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n state?: State,\n _options?,\n callback?: HandlerCallback,\n ) => {\n logger.info(\"[SetSecret] Processing secret set request\");\n\n const secretsService =\n runtime.getService<SecretsService>(SECRETS_SERVICE_TYPE);\n if (!secretsService) {\n if (callback) {\n await callback({\n text: \"Secret management is not available. Please ensure the secrets plugin is properly configured.\",\n action: \"SET_SECRET\",\n });\n }\n return { success: false, text: \"Secrets service not available\" };\n }\n\n // Build state for prompt\n const currentState = state ?? (await runtime.composeState(message));\n\n // Extract secrets from user message using LLM\n let extracted: ExtractedSecrets;\n try {\n const prompt = composePromptFromState({\n state: currentState,\n template: extractSecretsTemplate,\n });\n\n const result = (await runtime.useModel(ModelType.OBJECT_SMALL, {\n prompt,\n })) as Record<string, JsonValue>;\n\n // Validate and transform the result\n const secretsArray = Array.isArray(result.secrets) ? result.secrets : [];\n extracted = {\n secrets: secretsArray\n .filter(\n (s): s is Record<string, JsonValue> =>\n s !== null && typeof s === \"object\",\n )\n .map((s) => ({\n key: String(s.key || \"\"),\n value: String(s.value || \"\"),\n description: s.description ? String(s.description) : undefined,\n type: s.type as ExtractedSecret[\"type\"],\n }))\n .filter((s) => s.key && s.value),\n level: result.level as ExtractedSecrets[\"level\"],\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n logger.error(`[SetSecret] Failed to extract secrets: ${errorMessage}`);\n if (callback) {\n await callback({\n text: 'I had trouble understanding the secret you wanted to set. Could you please provide it in a clearer format? For example: \"Set my OPENAI_API_KEY to sk-...\"',\n action: \"SET_SECRET\",\n });\n }\n return { success: false, text: \"Failed to extract secrets from message\" };\n }\n\n if (!extracted.secrets || extracted.secrets.length === 0) {\n if (callback) {\n await callback({\n text: 'I couldn\\'t find any secrets to set in your message. Please provide a key and value, like: \"Set my OPENAI_API_KEY to sk-...\"',\n action: \"SET_SECRET\",\n });\n }\n return { success: false, text: \"No secrets found in message\" };\n }\n\n // Determine storage context\n const level = extracted.level ?? \"global\";\n const context: SecretContext = {\n level,\n agentId: runtime.agentId,\n worldId: level === \"world\" ? (message.roomId as string) : undefined,\n userId: level === \"user\" ? (message.entityId as string) : undefined,\n requesterId: message.entityId as string,\n };\n\n // Store each extracted secret\n const results: Array<{ key: string; success: boolean; error?: string }> =\n [];\n\n for (const secret of extracted.secrets) {\n // Normalize key to uppercase\n const key = secret.key.toUpperCase().replace(/[^A-Z0-9_]/g, \"_\");\n\n // Infer validation strategy\n const validationMethod = inferValidationStrategy(key);\n\n try {\n const success = await secretsService.set(key, secret.value, context, {\n type: (secret.type as SecretType) ?? \"secret\",\n description: secret.description ?? `Secret set via conversation`,\n validationMethod,\n encrypted: true,\n });\n\n results.push({ key, success });\n\n if (success) {\n logger.info(`[SetSecret] Successfully set secret: ${key}`);\n }\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : \"Unknown error\";\n results.push({ key, success: false, error: errorMessage });\n logger.error(\n `[SetSecret] Failed to set secret ${key}: ${errorMessage}`,\n );\n }\n }\n\n // Generate response\n const successful = results.filter((r) => r.success);\n const failed = results.filter((r) => !r.success);\n\n let responseText: string;\n\n if (successful.length > 0 && failed.length === 0) {\n const keys = successful.map((r) => r.key).join(\", \");\n responseText =\n successful.length === 1\n ? `I've securely stored your ${keys}. It's now available for use.`\n : `I've securely stored ${successful.length} secrets: ${keys}. They're now available for use.`;\n } else if (successful.length === 0 && failed.length > 0) {\n const errors = failed.map((r) => `${r.key}: ${r.error}`).join(\"; \");\n responseText = `I wasn't able to store the secret(s). ${errors}`;\n } else {\n const successKeys = successful.map((r) => r.key).join(\", \");\n const failedKeys = failed.map((r) => r.key).join(\", \");\n responseText = `I stored ${successful.length} secret(s) (${successKeys}), but ${failed.length} failed (${failedKeys}).`;\n }\n\n if (callback) {\n await callback({\n text: responseText,\n action: \"SET_SECRET\",\n });\n }\n\n return { success: successful.length > 0, text: responseText };\n },\n\n examples: [\n [\n {\n name: \"{{user1}}\",\n content: { text: \"Set my OpenAI API key to sk-abc123xyz789\" },\n },\n {\n name: \"{{agent}}\",\n content: {\n text: \"I've securely stored your OPENAI_API_KEY. It's now available for use.\",\n action: \"SET_SECRET\",\n },\n },\n ],\n [\n {\n name: \"{{user1}}\",\n content: { text: \"My Anthropic key is sk-ant-secret123\" },\n },\n {\n name: \"{{agent}}\",\n content: {\n text: \"I've securely stored your ANTHROPIC_API_KEY. It's now available for use.\",\n action: \"SET_SECRET\",\n },\n },\n ],\n [\n {\n name: \"{{user1}}\",\n content: { text: \"Use this Discord bot token: MTIz.abc.xyz\" },\n },\n {\n name: \"{{agent}}\",\n content: {\n text: \"I've securely stored your DISCORD_BOT_TOKEN. It's now available for use.\",\n action: \"SET_SECRET\",\n },\n },\n ],\n ] as ActionExample[][],\n};\n","/**\n * Manage Secret Action\n *\n * Comprehensive action for managing secrets through natural language.\n * Supports get, set, delete, and list operations at different levels.\n */\n\nimport {\n type Action,\n type ActionResult,\n type IAgentRuntime,\n type Memory,\n type State,\n type HandlerCallback,\n type JsonValue,\n ModelType,\n logger,\n composePromptFromState,\n type ActionExample,\n} from \"@elizaos/core\";\nimport { SecretsService, SECRETS_SERVICE_TYPE } from \"../services/secrets.js\";\nimport type { SecretContext, SecretType } from \"../types.js\";\n\n/**\n * Type for secret management operation\n */\ninterface SecretOperation {\n operation: \"get\" | \"set\" | \"delete\" | \"list\" | \"check\";\n key?: string;\n value?: string;\n level?: \"global\" | \"world\" | \"user\";\n description?: string;\n type?: \"api_key\" | \"secret\" | \"credential\" | \"url\" | \"config\";\n}\n\n/**\n * Template for extracting secret management intent\n */\nconst extractOperationTemplate = `You are helping manage secrets for an AI agent.\n\nDetermine what operation the user wants to perform:\n- get: Retrieve a secret value\n- set: Store a new secret\n- delete: Remove a secret\n- list: Show all available secrets (without values)\n- check: Check if a secret exists\n\nCommon patterns:\n- \"What is my OpenAI key?\" -> operation: get, key: OPENAI_API_KEY\n- \"Do I have a Discord token set?\" -> operation: check, key: DISCORD_BOT_TOKEN\n- \"Show me my secrets\" -> operation: list\n- \"Delete my old API key\" -> operation: delete\n- \"Remove TWITTER_API_KEY\" -> operation: delete, key: TWITTER_API_KEY\n- \"Set my key to sk-...\" -> operation: set, key: <infer>, value: sk-...\n\n{{recentMessages}}\n\nExtract the operation, key (if applicable), value (if applicable), and level from the user's message.`;\n\n/**\n * Manage Secret Action\n */\nexport const manageSecretAction: Action = {\n name: \"MANAGE_SECRET\",\n similes: [\n \"SECRET_MANAGEMENT\",\n \"HANDLE_SECRET\",\n \"SECRET_OPERATION\",\n \"GET_SECRET\",\n \"DELETE_SECRET\",\n \"LIST_SECRETS\",\n \"CHECK_SECRET\",\n ],\n description:\n \"Manage secrets - get, set, delete, or list secrets at various levels\",\n\n validate: async (\n runtime: IAgentRuntime,\n message: Memory,\n state?: State,\n ): Promise<boolean> => {\n const text = message.content.text?.toLowerCase() ?? \"\";\n\n // Check for secret management intent\n const patterns = [\n /\\b(get|show|what|retrieve)\\b.*\\b(secret|key|token|credential)/i,\n /\\b(delete|remove|clear)\\b.*\\b(secret|key|token|credential)/i,\n /\\b(list|show)\\b.*\\b(secrets|keys|tokens|credentials)/i,\n /\\bdo i have\\b.*\\b(secret|key|token)/i,\n /\\b(check|is)\\b.*\\b(secret|key|token)\\b.*\\b(set|configured)/i,\n /\\bmy secrets\\b/i,\n /\\bwhat secrets\\b/i,\n ];\n\n const hasIntent = patterns.some((pattern) => pattern.test(text));\n if (!hasIntent) {\n return false;\n }\n\n const secretsService =\n runtime.getService<SecretsService>(SECRETS_SERVICE_TYPE);\n return secretsService !== null;\n },\n\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n state?: State,\n _options?,\n callback?: HandlerCallback,\n ) => {\n logger.info(\"[ManageSecret] Processing secret management request\");\n\n const secretsService =\n runtime.getService<SecretsService>(SECRETS_SERVICE_TYPE);\n if (!secretsService) {\n if (callback) {\n await callback({\n text: \"Secret management is not available.\",\n action: \"MANAGE_SECRET\",\n });\n }\n return { success: false, text: \"Secrets service not available\" };\n }\n\n // Build state for prompt\n const currentState = state ?? (await runtime.composeState(message));\n\n // Extract operation from user message\n let operation: SecretOperation;\n try {\n const prompt = composePromptFromState({\n state: currentState,\n template: extractOperationTemplate,\n });\n\n const result = (await runtime.useModel(ModelType.OBJECT_SMALL, {\n prompt,\n })) as Record<string, JsonValue>;\n\n // Transform and validate result\n operation = {\n operation: (result.operation as SecretOperation[\"operation\"]) || \"list\",\n key: result.key ? String(result.key) : undefined,\n value: result.value ? String(result.value) : undefined,\n level: result.level as SecretOperation[\"level\"],\n description: result.description\n ? String(result.description)\n : undefined,\n type: result.type as SecretOperation[\"type\"],\n };\n } catch (error) {\n const errorMessage =\n error instanceof Error ? error.message : String(error);\n logger.error(\n `[ManageSecret] Failed to extract operation: ${errorMessage}`,\n );\n if (callback) {\n await callback({\n text: \"I had trouble understanding what you want to do with secrets. Could you be more specific?\",\n action: \"MANAGE_SECRET\",\n });\n }\n return {\n success: false,\n text: \"Failed to extract operation from message\",\n };\n }\n\n // Determine storage context\n const level = operation.level ?? \"global\";\n const context: SecretContext = {\n level,\n agentId: runtime.agentId,\n worldId: level === \"world\" ? (message.roomId as string) : undefined,\n userId: level === \"user\" ? (message.entityId as string) : undefined,\n requesterId: message.entityId as string,\n };\n\n // Execute the operation\n let responseText: string;\n\n switch (operation.operation) {\n case \"get\": {\n if (!operation.key) {\n responseText = \"Please specify which secret you want to retrieve.\";\n break;\n }\n\n const key = operation.key.toUpperCase().replace(/[^A-Z0-9_]/g, \"_\");\n const value = await secretsService.get(key, context);\n\n if (value) {\n // Never reveal full secret values - show partial\n const maskedValue = maskSecretValue(value);\n responseText = `Your ${key} is set to: ${maskedValue}`;\n } else {\n responseText = `I don't have a ${key} stored. Would you like to set one?`;\n }\n break;\n }\n\n case \"set\": {\n if (!operation.key || !operation.value) {\n responseText = \"Please provide both a key and value to set a secret.\";\n break;\n }\n\n const key = operation.key.toUpperCase().replace(/[^A-Z0-9_]/g, \"_\");\n\n try {\n const success = await secretsService.set(\n key,\n operation.value,\n context,\n {\n type: (operation.type as SecretType) ?? \"secret\",\n description: operation.description ?? \"Set via conversation\",\n encrypted: true,\n },\n );\n\n if (success) {\n responseText = `I've securely stored your ${key}.`;\n } else {\n responseText = `Failed to store ${key}. Please try again.`;\n }\n } catch (error) {\n responseText = `Error storing ${key}: ${error instanceof Error ? error.message : \"Unknown error\"}`;\n }\n break;\n }\n\n case \"delete\": {\n if (!operation.key) {\n responseText = \"Please specify which secret you want to delete.\";\n break;\n }\n\n const key = operation.key.toUpperCase().replace(/[^A-Z0-9_]/g, \"_\");\n const deleted = await secretsService.delete(key, context);\n\n if (deleted) {\n responseText = `I've deleted your ${key}.`;\n } else {\n responseText = `I couldn't find a ${key} to delete.`;\n }\n break;\n }\n\n case \"list\": {\n const metadata = await secretsService.list(context);\n const keys = Object.keys(metadata);\n\n if (keys.length === 0) {\n responseText = `You don't have any ${level} secrets stored yet.`;\n } else {\n const secretList = keys\n .map((key) => {\n const config = metadata[key];\n const status = config.status === \"valid\" ? \"✓\" : \"⚠\";\n return `• ${key} ${status}`;\n })\n .join(\"\\n\");\n\n responseText = `Here are your ${level} secrets:\\n${secretList}`;\n }\n break;\n }\n\n case \"check\": {\n if (!operation.key) {\n responseText = \"Please specify which secret you want to check.\";\n break;\n }\n\n const key = operation.key.toUpperCase().replace(/[^A-Z0-9_]/g, \"_\");\n const exists = await secretsService.exists(key, context);\n\n if (exists) {\n const config = await secretsService.getConfig(key, context);\n const status =\n config?.status === \"valid\"\n ? \"valid\"\n : (config?.status ?? \"unknown\");\n responseText = `Yes, ${key} is set and its status is: ${status}.`;\n } else {\n responseText = `No, ${key} is not set. Would you like to configure it?`;\n }\n break;\n }\n\n default:\n responseText =\n \"I'm not sure what operation you want to perform. You can get, set, delete, list, or check secrets.\";\n }\n\n if (callback) {\n await callback({\n text: responseText,\n action: \"MANAGE_SECRET\",\n });\n }\n\n return { success: true, text: responseText };\n },\n\n examples: [\n [\n {\n name: \"{{user1}}\",\n content: { text: \"What secrets do I have?\" },\n },\n {\n name: \"{{agent}}\",\n content: {\n text: \"Here are your global secrets:\\n• OPENAI_API_KEY ✓\\n• ANTHROPIC_API_KEY ✓\",\n action: \"MANAGE_SECRET\",\n },\n },\n ],\n [\n {\n name: \"{{user1}}\",\n content: { text: \"Do I have a Discord token set?\" },\n },\n {\n name: \"{{agent}}\",\n content: {\n text: \"No, DISCORD_BOT_TOKEN is not set. Would you like to configure it?\",\n action: \"MANAGE_SECRET\",\n },\n },\n ],\n [\n {\n name: \"{{user1}}\",\n content: { text: \"Delete my old Twitter API key\" },\n },\n {\n name: \"{{agent}}\",\n content: {\n text: \"I've deleted your TWITTER_API_KEY.\",\n action: \"MANAGE_SECRET\",\n },\n },\n ],\n ] as ActionExample[][],\n};\n\n/**\n * Mask a secret value for display\n */\nfunction maskSecretValue(value: string): string {\n if (value.length <= 8) {\n return \"****\";\n }\n\n const visibleStart = value.slice(0, 4);\n const visibleEnd = value.slice(-4);\n const maskedLength = Math.min(value.length - 8, 20);\n const mask = \"*\".repeat(maskedLength);\n\n return `${visibleStart}${mask}${visibleEnd}`;\n}\n","/**\n * Secrets Status Provider\n *\n * Provides context about the agent's secret configuration status\n * to help the LLM understand what capabilities are available.\n */\n\nimport {\n type Provider,\n type ProviderResult,\n type IAgentRuntime,\n type Memory,\n type State,\n logger,\n} from \"@elizaos/core\";\nimport { SecretsService, SECRETS_SERVICE_TYPE } from \"../services/secrets.js\";\nimport {\n PluginActivatorService,\n PLUGIN_ACTIVATOR_SERVICE_TYPE,\n} from \"../services/plugin-activator.js\";\n\n/**\n * Secrets Status Provider\n *\n * Adds information about configured secrets to the agent's context,\n * without exposing actual secret values.\n */\nexport const secretsStatusProvider: Provider = {\n name: \"SECRETS_STATUS\",\n description: \"Provides information about configured secrets and their status\",\n\n get: async (\n runtime: IAgentRuntime,\n message: Memory,\n state?: State,\n ): Promise<ProviderResult> => {\n const secretsService =\n runtime.getService<SecretsService>(SECRETS_SERVICE_TYPE);\n if (!secretsService) {\n return { text: \"\" };\n }\n\n try {\n // Get global secrets status\n const globalSecrets = await secretsService.list({\n level: \"global\",\n agentId: runtime.agentId,\n });\n\n const secretKeys = Object.keys(globalSecrets);\n\n if (secretKeys.length === 0) {\n return {\n text: `[Secrets Status]\nNo secrets are currently configured. The agent may need API keys or other credentials to access certain services.`,\n };\n }\n\n // Categorize secrets by status\n const valid: string[] = [];\n const missing: string[] = [];\n const invalid: string[] = [];\n\n for (const [key, config] of Object.entries(globalSecrets)) {\n switch (config.status) {\n case \"valid\":\n valid.push(key);\n break;\n case \"missing\":\n missing.push(key);\n break;\n case \"invalid\":\n case \"expired\":\n case \"revoked\":\n invalid.push(key);\n break;\n default:\n valid.push(key);\n }\n }\n\n // Build status message\n const lines: string[] = [\"[Secrets Status]\"];\n\n if (valid.length > 0) {\n lines.push(`Configured secrets: ${valid.join(\", \")}`);\n }\n\n if (invalid.length > 0) {\n lines.push(`Invalid/expired secrets: ${invalid.join(\", \")}`);\n }\n\n if (missing.length > 0) {\n lines.push(`Missing required secrets: ${missing.join(\", \")}`);\n }\n\n // Check plugin activator for pending plugins\n const activatorService = runtime.getService<PluginActivatorService>(\n PLUGIN_ACTIVATOR_SERVICE_TYPE,\n );\n if (activatorService) {\n const pendingPlugins = activatorService.getPendingPlugins();\n if (pendingPlugins.length > 0) {\n lines.push(\n `Plugins waiting for secrets: ${pendingPlugins.join(\", \")}`,\n );\n\n const requiredSecrets = activatorService.getRequiredSecrets();\n if (requiredSecrets.size > 0) {\n lines.push(\n `Secrets needed for pending plugins: ${Array.from(requiredSecrets).join(\", \")}`,\n );\n }\n }\n }\n\n return { text: lines.join(\"\\n\") };\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n logger.error(\n `[SecretsStatusProvider] Error getting secrets status: ${errorMsg}`,\n );\n return { text: \"\" };\n }\n },\n};\n\n/**\n * Secrets Info Provider\n *\n * Provides detailed information about specific secrets when relevant\n * to the current conversation context.\n */\nexport const secretsInfoProvider: Provider = {\n name: \"SECRETS_INFO\",\n description:\n \"Provides detailed secret information based on conversation context\",\n\n get: async (\n runtime: IAgentRuntime,\n message: Memory,\n state?: State,\n ): Promise<ProviderResult> => {\n const secretsService =\n runtime.getService<SecretsService>(SECRETS_SERVICE_TYPE);\n if (!secretsService) {\n return { text: \"\" };\n }\n\n const text = message.content.text?.toLowerCase() ?? \"\";\n\n // Check if message is about secrets\n const isAboutSecrets =\n /\\b(secret|key|token|credential|api|password|configure)\\b/i.test(text);\n if (!isAboutSecrets) {\n return { text: \"\" };\n }\n\n try {\n const globalSecrets = await secretsService.list({\n level: \"global\",\n agentId: runtime.agentId,\n });\n\n const secretCount = Object.keys(globalSecrets).length;\n if (secretCount === 0) {\n return {\n text: `[Secrets Info]\nNo secrets configured. User can set secrets by saying things like \"Set my OPENAI_API_KEY to sk-...\"`,\n };\n }\n\n // Build detailed info\n const lines: string[] = [\"[Secrets Info]\"];\n lines.push(`Total configured secrets: ${secretCount}`);\n\n // Group by type\n const byType: Record<string, string[]> = {};\n for (const [key, config] of Object.entries(globalSecrets)) {\n const type = config.type ?? \"secret\";\n if (!byType[type]) {\n byType[type] = [];\n }\n byType[type].push(key);\n }\n\n for (const [type, keys] of Object.entries(byType)) {\n lines.push(`${type}: ${keys.join(\", \")}`);\n }\n\n // Check for common missing secrets that might be relevant\n const commonSecrets = [\n \"OPENAI_API_KEY\",\n \"ANTHROPIC_API_KEY\",\n \"DISCORD_BOT_TOKEN\",\n \"TELEGRAM_BOT_TOKEN\",\n \"TWITTER_API_KEY\",\n ];\n\n const missingCommon = commonSecrets.filter((key) => !globalSecrets[key]);\n if (\n missingCommon.length > 0 &&\n missingCommon.length < commonSecrets.length\n ) {\n lines.push(`Common secrets not set: ${missingCommon.join(\", \")}`);\n }\n\n return { text: lines.join(\"\\n\") };\n } catch (error) {\n const errorMsg = error instanceof Error ? error.message : String(error);\n logger.error(`[SecretsInfoProvider] Error: ${errorMsg}`);\n return { text: \"\" };\n }\n },\n};\n","/**\n * Onboarding configuration types and utilities.\n *\n * Provides the structure for defining secret requirements per agent/plugin,\n * supporting both conversational and form-based collection flows.\n */\n\nimport type { SecretType, SecretConfig, SecretLevel } from \"../types\";\n\n/**\n * Setting definition for onboarding.\n * Compatible with the-org OnboardingConfig format.\n */\nexport interface OnboardingSetting {\n /** Display name */\n name: string;\n /** Description for LLM context */\n description: string;\n /** Prompt shown when asking user for this setting */\n usageDescription?: string;\n /** Whether this is a secret (should be encrypted) */\n secret: boolean;\n /** Whether this should be visible in non-onboarding contexts */\n public: boolean;\n /** Whether this setting is required */\n required: boolean;\n /** Settings that must be configured first */\n dependsOn: string[];\n /** Validation function */\n validation?: (value: string) => boolean;\n /** Validation method name (openai, anthropic, url, etc.) */\n validationMethod?: string;\n /** Secret type */\n type?: SecretType;\n /** Environment variable to sync to */\n envVar?: string;\n /** Default value if not set */\n defaultValue?: string;\n /** Current value (set during onboarding) */\n value?: string | null;\n /** Conditional visibility based on other settings */\n visibleIf?: (settings: Record<string, OnboardingSetting>) => boolean;\n /** Callback when value is set */\n onSetAction?: (value: string | boolean) => string | void;\n}\n\n/**\n * Onboarding configuration for an agent or plugin.\n */\nexport interface OnboardingConfig {\n /** Setting definitions */\n settings: Record<string, OnboardingSetting>;\n /** Optional platform-specific messages */\n messages?: {\n welcome?: string[];\n askSetting?: string;\n settingUpdated?: string;\n allComplete?: string;\n error?: string;\n };\n /** Onboarding flow mode */\n mode?: \"conversational\" | \"form\" | \"hybrid\";\n}\n\n/**\n * Default onboarding messages.\n */\nexport const DEFAULT_ONBOARDING_MESSAGES = {\n welcome: [\n \"Hi! I need to collect some information to get set up. Is now a good time?\",\n \"Hey there! I need to configure a few things. Do you have a moment?\",\n \"Hello! Could we take a few minutes to get everything set up?\",\n ],\n askSetting: \"I need your {{settingName}}. {{usageDescription}}\",\n settingUpdated: \"Got it! I've saved your {{settingName}}.\",\n allComplete:\n \"Great! All required settings have been configured. You're all set!\",\n error: \"I had trouble understanding that. Could you try again?\",\n};\n\n/**\n * Common API key settings for quick setup.\n */\nexport const COMMON_API_KEY_SETTINGS: Record<\n string,\n Partial<OnboardingSetting>\n> = {\n OPENAI_API_KEY: {\n name: \"OpenAI API Key\",\n description: \"API key for OpenAI services (GPT models)\",\n usageDescription: 'Your OpenAI API key starts with \"sk-\"',\n secret: true,\n public: false,\n required: false,\n dependsOn: [],\n validationMethod: \"openai\",\n type: \"api_key\",\n envVar: \"OPENAI_API_KEY\",\n },\n ANTHROPIC_API_KEY: {\n name: \"Anthropic API Key\",\n description: \"API key for Anthropic services (Claude models)\",\n usageDescription: 'Your Anthropic API key starts with \"sk-ant-\"',\n secret: true,\n public: false,\n required: false,\n dependsOn: [],\n validationMethod: \"anthropic\",\n type: \"api_key\",\n envVar: \"ANTHROPIC_API_KEY\",\n },\n GROQ_API_KEY: {\n name: \"Groq API Key\",\n description: \"API key for Groq inference services\",\n usageDescription: 'Your Groq API key starts with \"gsk_\"',\n secret: true,\n public: false,\n required: false,\n dependsOn: [],\n validationMethod: \"groq\",\n type: \"api_key\",\n envVar: \"GROQ_API_KEY\",\n },\n GOOGLE_API_KEY: {\n name: \"Google API Key\",\n description: \"API key for Google AI services (Gemini)\",\n usageDescription: \"Your Google API key for Gemini models\",\n secret: true,\n public: false,\n required: false,\n dependsOn: [],\n validationMethod: \"google\",\n type: \"api_key\",\n envVar: \"GOOGLE_API_KEY\",\n },\n DISCORD_TOKEN: {\n name: \"Discord Bot Token\",\n description: \"Bot token for Discord integration\",\n usageDescription: \"Your Discord bot token from the developer portal\",\n secret: true,\n public: false,\n required: false,\n dependsOn: [],\n validationMethod: \"discord\",\n type: \"token\",\n envVar: \"DISCORD_TOKEN\",\n },\n TELEGRAM_BOT_TOKEN: {\n name: \"Telegram Bot Token\",\n description: \"Bot token for Telegram integration\",\n usageDescription: \"Your Telegram bot token from @BotFather\",\n secret: true,\n public: false,\n required: false,\n dependsOn: [],\n validationMethod: \"telegram\",\n type: \"token\",\n envVar: \"TELEGRAM_BOT_TOKEN\",\n },\n TWITTER_USERNAME: {\n name: \"Twitter Username\",\n description: \"Twitter/X username for posting\",\n usageDescription: \"The Twitter username (without @)\",\n secret: false,\n public: true,\n required: false,\n dependsOn: [],\n type: \"credential\",\n },\n TWITTER_PASSWORD: {\n name: \"Twitter Password\",\n description: \"Twitter/X account password\",\n usageDescription: \"The password for your Twitter account\",\n secret: true,\n public: false,\n required: false,\n dependsOn: [\"TWITTER_USERNAME\"],\n type: \"credential\",\n },\n TWITTER_EMAIL: {\n name: \"Twitter Email\",\n description: \"Email associated with Twitter account\",\n usageDescription: \"The email address linked to your Twitter account\",\n secret: false,\n public: false,\n required: false,\n dependsOn: [\"TWITTER_USERNAME\"],\n type: \"credential\",\n validation: (value: string) => /^[^\\s@]+@[^\\s@]+\\.[^\\s@]+$/.test(value),\n },\n TWITTER_2FA_SECRET: {\n name: \"Twitter 2FA Secret\",\n description: \"2FA secret for Twitter account\",\n usageDescription: \"The 2FA/TOTP secret (if 2FA is enabled)\",\n secret: true,\n public: false,\n required: false,\n dependsOn: [\"TWITTER_USERNAME\", \"TWITTER_PASSWORD\"],\n type: \"credential\",\n },\n};\n\n/**\n * Create an onboarding config from a list of required secret keys.\n */\nexport function createOnboardingConfig(\n requiredKeys: string[],\n optionalKeys: string[] = [],\n customSettings: Record<string, Partial<OnboardingSetting>> = {},\n): OnboardingConfig {\n const settings: Record<string, OnboardingSetting> = {};\n\n for (const key of requiredKeys) {\n const common = COMMON_API_KEY_SETTINGS[key] || {};\n const custom = customSettings[key] || {};\n settings[key] = {\n name: custom.name || common.name || key,\n description:\n custom.description || common.description || `Configure ${key}`,\n usageDescription: custom.usageDescription || common.usageDescription,\n secret: custom.secret ?? common.secret ?? true,\n public: custom.public ?? common.public ?? false,\n required: true,\n dependsOn: custom.dependsOn || common.dependsOn || [],\n validationMethod: custom.validationMethod || common.validationMethod,\n type: custom.type || common.type || \"api_key\",\n envVar: custom.envVar || common.envVar || key,\n value: null,\n ...custom,\n };\n }\n\n for (const key of optionalKeys) {\n const common = COMMON_API_KEY_SETTINGS[key] || {};\n const custom = customSettings[key] || {};\n settings[key] = {\n name: custom.name || common.name || key,\n description:\n custom.description || common.description || `Configure ${key}`,\n usageDescription: custom.usageDescription || common.usageDescription,\n secret: custom.secret ?? common.secret ?? true,\n public: custom.public ?? common.public ?? false,\n required: false,\n dependsOn: custom.dependsOn || common.dependsOn || [],\n validationMethod: custom.validationMethod || common.validationMethod,\n type: custom.type || common.type || \"api_key\",\n envVar: custom.envVar || common.envVar || key,\n value: null,\n ...custom,\n };\n }\n\n return { settings };\n}\n\n/**\n * Get unconfigured required settings from an onboarding config.\n */\nexport function getUnconfiguredRequired(\n config: OnboardingConfig,\n): Array<[string, OnboardingSetting]> {\n return Object.entries(config.settings).filter(\n ([_, setting]) => setting.required && setting.value === null,\n );\n}\n\n/**\n * Get unconfigured optional settings from an onboarding config.\n */\nexport function getUnconfiguredOptional(\n config: OnboardingConfig,\n): Array<[string, OnboardingSetting]> {\n return Object.entries(config.settings).filter(\n ([_, setting]) => !setting.required && setting.value === null,\n );\n}\n\n/**\n * Check if all required settings are configured.\n */\nexport function isOnboardingComplete(config: OnboardingConfig): boolean {\n return getUnconfiguredRequired(config).length === 0;\n}\n\n/**\n * Get the next setting to configure (respects dependencies).\n */\nexport function getNextSetting(\n config: OnboardingConfig,\n): [string, OnboardingSetting] | null {\n const unconfigured = getUnconfiguredRequired(config);\n\n for (const [key, setting] of unconfigured) {\n // Check if dependencies are met\n const dependenciesMet = setting.dependsOn.every((dep) => {\n const depSetting = config.settings[dep];\n return depSetting && depSetting.value !== null;\n });\n\n // Check visibility condition\n const isVisible = !setting.visibleIf || setting.visibleIf(config.settings);\n\n if (dependenciesMet && isVisible) {\n return [key, setting];\n }\n }\n\n // If no required settings, try optional\n const optionalUnconfigured = getUnconfiguredOptional(config);\n for (const [key, setting] of optionalUnconfigured) {\n const dependenciesMet = setting.dependsOn.every((dep) => {\n const depSetting = config.settings[dep];\n return depSetting && depSetting.value !== null;\n });\n const isVisible = !setting.visibleIf || setting.visibleIf(config.settings);\n\n if (dependenciesMet && isVisible) {\n return [key, setting];\n }\n }\n\n return null;\n}\n\n/**\n * Generate a prompt for the LLM to ask for a specific setting.\n */\nexport function generateSettingPrompt(\n key: string,\n setting: OnboardingSetting,\n agentName: string,\n): string {\n const required = setting.required ? \"(Required)\" : \"(Optional)\";\n const usage = setting.usageDescription || setting.description;\n\n return (\n `${agentName} needs to collect the ${setting.name} ${required}.\\n` +\n `Description: ${usage}\\n` +\n `Ask the user for their ${setting.name} in a natural, conversational way.`\n );\n}\n","/**\n * Onboarding Service\n *\n * Manages the secrets onboarding flow across platforms (Discord, Telegram, etc.)\n * Supports both conversational and form-based collection modes.\n */\n\nimport type {\n IAgentRuntime,\n UUID,\n World,\n WorldMetadata,\n Memory,\n Room,\n} from \"@elizaos/core\";\nimport { Service, ServiceTypeName, ChannelType, logger } from \"@elizaos/core\";\nimport type { SecretContext } from \"../types\";\nimport type { SecretsService } from \"../services/secrets\";\nimport {\n type OnboardingConfig,\n type OnboardingSetting,\n DEFAULT_ONBOARDING_MESSAGES,\n getUnconfiguredRequired,\n getNextSetting,\n isOnboardingComplete,\n} from \"./config\";\n\nexport const ONBOARDING_SERVICE_TYPE = \"SECRETS_ONBOARDING\" as ServiceTypeName;\n\n/**\n * Extended WorldMetadata for onboarding\n */\ninterface OnboardingWorldMetadata extends WorldMetadata {\n onboardingConfig?: OnboardingConfig;\n}\n\n/**\n * Onboarding session state.\n */\ninterface OnboardingSession {\n worldId: UUID;\n userId: UUID;\n roomId: UUID;\n config: OnboardingConfig;\n currentSettingKey: string | null;\n startedAt: number;\n lastActivityAt: number;\n platform: \"discord\" | \"telegram\" | \"other\";\n mode: \"conversational\" | \"form\" | \"hybrid\";\n}\n\n/**\n * Onboarding Service for secrets collection.\n */\nexport class OnboardingService extends Service {\n static serviceType: ServiceTypeName = ONBOARDING_SERVICE_TYPE;\n capabilityDescription = \"Manage secrets onboarding across chat platforms\";\n\n private secretsService: SecretsService | null = null;\n private sessions: Map<UUID, OnboardingSession> = new Map();\n\n constructor(runtime?: IAgentRuntime) {\n super(runtime);\n }\n\n /**\n * Start the service\n */\n static async start(runtime: IAgentRuntime): Promise<OnboardingService> {\n const service = new OnboardingService(runtime);\n await service.initialize();\n return service;\n }\n\n /**\n * Initialize the service\n */\n private async initialize(): Promise<void> {\n logger.info(\"[OnboardingService] Starting\");\n\n // Get secrets service\n this.secretsService = this.runtime.getService(\"SECRETS\") as SecretsService;\n\n // Register platform events\n this.registerEvents();\n\n logger.info(\"[OnboardingService] Started\");\n }\n\n async stop(): Promise<void> {\n logger.info(\"[OnboardingService] Stopping\");\n this.sessions.clear();\n logger.info(\"[OnboardingService] Stopped\");\n }\n\n /**\n * Register platform-specific event handlers.\n */\n private registerEvents(): void {\n // Discord: Bot joins a server\n this.runtime.registerEvent(\"DISCORD_WORLD_JOINED\", async (params) => {\n const server = (params as { server?: { id: string } }).server;\n if (server) {\n logger.info(`[OnboardingService] Discord world joined: ${server.id}`);\n }\n // Onboarding will be triggered when owner sends DM\n });\n\n // Discord: Server connected (bot already in server)\n this.runtime.registerEvent(\"DISCORD_SERVER_CONNECTED\", async (params) => {\n const server = (params as { server?: { id: string } }).server;\n if (server) {\n logger.info(\n `[OnboardingService] Discord server connected: ${server.id}`,\n );\n }\n });\n\n // Telegram: Bot joins a group\n this.runtime.registerEvent(\"TELEGRAM_WORLD_JOINED\", async (params) => {\n const typedParams = params as {\n world?: World;\n entities?: Array<{\n metadata?: {\n telegram?: { id: string; username: string; adminTitle?: string };\n };\n }>;\n chat?: { id: string | number };\n botUsername?: string;\n };\n if (\n typedParams.world &&\n typedParams.chat &&\n typedParams.entities &&\n typedParams.botUsername\n ) {\n logger.info(\n `[OnboardingService] Telegram world joined: ${typedParams.world.id}`,\n );\n await this.startTelegramOnboarding(\n typedParams.world,\n typedParams.chat,\n typedParams.entities,\n typedParams.botUsername,\n );\n }\n });\n }\n\n /**\n * Initialize onboarding for a world with the given config.\n */\n async initializeOnboarding(\n world: World,\n config: OnboardingConfig,\n ): Promise<void> {\n logger.info(\n `[OnboardingService] Initializing onboarding for world: ${world.id}`,\n );\n\n // Store config in world metadata\n if (!world.metadata) {\n world.metadata = {} as OnboardingWorldMetadata;\n }\n\n // Initialize settings state from config\n const settingsState: Record<string, OnboardingSetting> = {};\n for (const [key, setting] of Object.entries(config.settings)) {\n settingsState[key] = {\n ...setting,\n value: null,\n };\n }\n\n // Store settings using dynamic property access\n const metadata = world.metadata as OnboardingWorldMetadata;\n (metadata as Record<string, unknown>)[\"settings\"] = settingsState;\n metadata.onboardingConfig = config;\n\n await this.runtime.updateWorld(world);\n logger.info(\n `[OnboardingService] Onboarding initialized for world: ${world.id}`,\n );\n }\n\n /**\n * Start onboarding via DM (Discord).\n */\n async startDiscordOnboardingDM(\n serverId: string,\n ownerId: string,\n worldId: UUID,\n config: OnboardingConfig,\n ): Promise<void> {\n const messages =\n config.messages?.welcome || DEFAULT_ONBOARDING_MESSAGES.welcome;\n const _randomMessage =\n messages[Math.floor(Math.random() * messages.length)];\n\n // This would be called by the Discord plugin after it sends the DM\n // The actual DM sending is done by the Discord plugin\n logger.info(\n `[OnboardingService] Discord DM onboarding started - server: ${serverId}, owner: ${ownerId}, world: ${worldId}`,\n );\n }\n\n /**\n * Start onboarding via deep link (Telegram).\n */\n async startTelegramOnboarding(\n world: World,\n chat: { id: string | number },\n entities: Array<{\n metadata?: {\n telegram?: { id: string; username: string; adminTitle?: string };\n };\n }>,\n botUsername: string,\n ): Promise<void> {\n // Find the owner\n let ownerId: string | null = null;\n let ownerUsername: string | null = null;\n\n for (const entity of entities) {\n if (entity.metadata?.telegram?.adminTitle === \"Owner\") {\n ownerId = entity.metadata.telegram.id;\n ownerUsername = entity.metadata.telegram.username;\n break;\n }\n }\n\n if (!ownerId) {\n logger.warn(\"[OnboardingService] No owner found for Telegram group\");\n return;\n }\n\n // Send deep link message to group\n const telegramService = this.runtime.getService(\"telegram\") as {\n messageManager: {\n sendMessage: (\n chatId: string | number,\n msg: { text: string },\n ) => Promise<void>;\n };\n } | null;\n\n if (telegramService?.messageManager) {\n const deepLinkMessage = [\n `Hello @${ownerUsername}! Could we take a few minutes to get everything set up?`,\n `Please click this link to start chatting with me: https://t.me/${botUsername}?start=onboarding`,\n ].join(\" \");\n\n await telegramService.messageManager.sendMessage(chat.id, {\n text: deepLinkMessage,\n });\n logger.info(\n `[OnboardingService] Sent Telegram deep link - chatId: ${chat.id}, ownerId: ${ownerId}`,\n );\n }\n }\n\n /**\n * Start a new onboarding session.\n */\n async startSession(\n worldId: UUID,\n userId: UUID,\n roomId: UUID,\n config: OnboardingConfig,\n platform: \"discord\" | \"telegram\" | \"other\" = \"other\",\n mode: \"conversational\" | \"form\" | \"hybrid\" = \"conversational\",\n ): Promise<OnboardingSession> {\n const session: OnboardingSession = {\n worldId,\n userId,\n roomId,\n config,\n currentSettingKey: null,\n startedAt: Date.now(),\n lastActivityAt: Date.now(),\n platform,\n mode,\n };\n\n this.sessions.set(roomId, session);\n logger.info(\n `[OnboardingService] Session started - roomId: ${roomId}, worldId: ${worldId}, userId: ${userId}`,\n );\n\n return session;\n }\n\n /**\n * Get an active session by room ID.\n */\n getSession(roomId: UUID): OnboardingSession | null {\n return this.sessions.get(roomId) || null;\n }\n\n /**\n * Process a user message during onboarding.\n */\n async processMessage(\n roomId: UUID,\n message: Memory,\n ): Promise<{\n shouldRespond: boolean;\n response?: string;\n updatedKey?: string;\n complete?: boolean;\n }> {\n const session = this.sessions.get(roomId);\n if (!session) {\n return { shouldRespond: false };\n }\n\n session.lastActivityAt = Date.now();\n\n // Get current state\n const unconfigured = getUnconfiguredRequired(session.config);\n\n if (unconfigured.length === 0) {\n // All required settings configured\n return {\n shouldRespond: true,\n response:\n session.config.messages?.allComplete ||\n DEFAULT_ONBOARDING_MESSAGES.allComplete,\n complete: true,\n };\n }\n\n // Try to extract a setting value from the message\n const text = message.content?.text || \"\";\n const currentSetting = session.currentSettingKey\n ? session.config.settings[session.currentSettingKey]\n : null;\n\n // If we have a current setting being asked, try to match the response\n if (currentSetting && text.trim()) {\n const value = text.trim();\n\n // Validate if validation exists\n if (currentSetting.validation && !currentSetting.validation(value)) {\n return {\n shouldRespond: true,\n response: `That doesn't look like a valid ${currentSetting.name}. ${currentSetting.usageDescription || \"Please try again.\"}`,\n };\n }\n\n // Store the value\n if (this.secretsService) {\n const context: SecretContext = {\n level: \"world\",\n agentId: this.runtime.agentId,\n worldId: session.worldId,\n userId: session.userId,\n };\n\n await this.secretsService.set(\n session.currentSettingKey!,\n value,\n context,\n {\n description: currentSetting.description,\n type: currentSetting.type,\n encrypted: currentSetting.secret,\n },\n );\n }\n\n // Update local state\n session.config.settings[session.currentSettingKey!].value = value;\n\n // Check if complete\n if (isOnboardingComplete(session.config)) {\n this.sessions.delete(roomId);\n return {\n shouldRespond: true,\n response:\n session.config.messages?.allComplete ||\n DEFAULT_ONBOARDING_MESSAGES.allComplete,\n updatedKey: session.currentSettingKey!,\n complete: true,\n };\n }\n\n // Get next setting\n const next = getNextSetting(session.config);\n if (next) {\n const [nextKey, nextSetting] = next;\n session.currentSettingKey = nextKey;\n\n const askMessage = (\n session.config.messages?.askSetting ||\n DEFAULT_ONBOARDING_MESSAGES.askSetting\n )\n .replace(\"{{settingName}}\", nextSetting.name)\n .replace(\n \"{{usageDescription}}\",\n nextSetting.usageDescription || nextSetting.description,\n );\n\n return {\n shouldRespond: true,\n response: `${session.config.messages?.settingUpdated || DEFAULT_ONBOARDING_MESSAGES.settingUpdated.replace(\"{{settingName}}\", currentSetting.name)}\\n\\n${askMessage}`,\n updatedKey: session.currentSettingKey,\n };\n }\n }\n\n // Start asking for the first/next setting\n const next = getNextSetting(session.config);\n if (next) {\n const [nextKey, nextSetting] = next;\n session.currentSettingKey = nextKey;\n\n const askMessage = (\n session.config.messages?.askSetting ||\n DEFAULT_ONBOARDING_MESSAGES.askSetting\n )\n .replace(\"{{settingName}}\", nextSetting.name)\n .replace(\n \"{{usageDescription}}\",\n nextSetting.usageDescription || nextSetting.description,\n );\n\n return {\n shouldRespond: true,\n response: askMessage,\n };\n }\n\n return { shouldRespond: false };\n }\n\n /**\n * End an onboarding session.\n */\n endSession(roomId: UUID): void {\n this.sessions.delete(roomId);\n logger.info(`[OnboardingService] Session ended - roomId: ${roomId}`);\n }\n\n /**\n * Get the onboarding status for a world.\n */\n async getOnboardingStatus(worldId: UUID): Promise<{\n initialized: boolean;\n complete: boolean;\n configuredCount: number;\n requiredCount: number;\n missingRequired: string[];\n }> {\n const world = await this.runtime.getWorld(worldId);\n\n if (!world?.metadata?.settings) {\n return {\n initialized: false,\n complete: false,\n configuredCount: 0,\n requiredCount: 0,\n missingRequired: [],\n };\n }\n\n const settings = world.metadata.settings as Record<\n string,\n OnboardingSetting\n >;\n const entries = Object.entries(settings);\n\n const required = entries.filter(([_, s]) => s.required);\n const configured = required.filter(([_, s]) => s.value !== null);\n const missing = required\n .filter(([_, s]) => s.value === null)\n .map(([k, _]) => k);\n\n return {\n initialized: true,\n complete: missing.length === 0,\n configuredCount: configured.length,\n requiredCount: required.length,\n missingRequired: missing,\n };\n }\n\n /**\n * Generate the SETTINGS provider context for LLM.\n */\n generateSettingsContext(\n config: OnboardingConfig,\n isOnboarding: boolean,\n agentName: string,\n ): string {\n const entries = Object.entries(config.settings);\n const unconfigured = getUnconfiguredRequired(config);\n\n const settingsList = entries\n .map(([key, setting]) => {\n const status = setting.value !== null ? \"Configured\" : \"Not set\";\n const required = setting.required ? \"(Required)\" : \"(Optional)\";\n const value =\n setting.secret && setting.value\n ? \"****************\"\n : setting.value || \"Not set\";\n\n return `${key}: ${value} ${required}\\n(${setting.name}) ${setting.usageDescription || setting.description}`;\n })\n .join(\"\\n\\n\");\n\n const validKeys = `Valid setting keys: ${entries.map(([k, _]) => k).join(\", \")}`;\n\n if (isOnboarding && unconfigured.length > 0) {\n return `# PRIORITY TASK: Onboarding\n\n${agentName} needs to help the user configure ${unconfigured.length} required settings:\n\n${settingsList}\n\n${validKeys}\n\nInstructions for ${agentName}:\n- Only update settings if the user is clearly responding to a setting you are currently asking about.\n- If the user's reply clearly maps to a setting and a valid value, you **must** call the UPDATE_SETTINGS action.\n- Never hallucinate settings or respond with values not listed above.\n- Prioritize configuring required settings before optional ones.`;\n }\n\n return `## Current Configuration\n${unconfigured.length > 0 ? `IMPORTANT: ${unconfigured.length} required settings still need configuration.\\n\\n` : \"All required settings are configured.\\n\\n\"}${settingsList}`;\n }\n}\n","/**\n * Onboarding Provider\n *\n * Provides onboarding status and context to the LLM during secret collection.\n * Injects prompts about required settings into the agent's context.\n */\n\nimport type {\n IAgentRuntime,\n Memory,\n Provider,\n ProviderResult,\n State,\n World,\n} from \"@elizaos/core\";\nimport { ChannelType, logger } from \"@elizaos/core\";\nimport type { OnboardingSetting } from \"./config\";\nimport {\n getUnconfiguredRequired,\n getUnconfiguredOptional,\n getNextSetting,\n DEFAULT_ONBOARDING_MESSAGES,\n} from \"./config\";\nimport { OnboardingService } from \"./service\";\n\n/**\n * Format a setting value for display, respecting privacy flags.\n */\nfunction formatSettingValue(\n setting: OnboardingSetting,\n isOnboarding: boolean,\n): string {\n if (setting.value === null || setting.value === undefined) {\n return \"Not set\";\n }\n if (setting.secret && !isOnboarding) {\n return \"****************\";\n }\n return String(setting.value);\n}\n\n/**\n * Generate status message based on settings state.\n */\nfunction generateStatusMessage(\n settings: Record<string, OnboardingSetting>,\n isOnboarding: boolean,\n agentName: string,\n senderName?: string,\n): string {\n const entries = Object.entries(settings);\n\n // Format settings for display\n const formattedSettings = entries\n .map(([key, setting]) => {\n // Skip settings that should be hidden based on visibility function\n if (setting.visibleIf && !setting.visibleIf(settings)) {\n return null;\n }\n\n return {\n key,\n name: setting.name,\n value: formatSettingValue(setting, isOnboarding),\n description: setting.description,\n usageDescription: setting.usageDescription || setting.description,\n required: setting.required,\n configured: setting.value !== null,\n };\n })\n .filter(Boolean);\n\n // Count required unconfigured\n const requiredUnconfigured = formattedSettings.filter(\n (s) => s?.required && !s.configured,\n ).length;\n\n // Generate appropriate message\n if (isOnboarding) {\n const settingsList = formattedSettings\n .map((s) => {\n if (!s) return \"\";\n const label = s.required ? \"(Required)\" : \"(Optional)\";\n return `${s.key}: ${s.value} ${label}\\n(${s.name}) ${s.usageDescription}`;\n })\n .filter(Boolean)\n .join(\"\\n\\n\");\n\n const validKeys = `Valid setting keys: ${entries.map(([k]) => k).join(\", \")}`;\n\n const instructions = `Instructions for ${agentName}:\n- Only update settings if the user is clearly responding to a setting you are currently asking about.\n- If the user's reply clearly maps to a setting and a valid value, you **must** call the UPDATE_SETTINGS action with the correct key and value.\n- Never hallucinate settings or respond with values not listed above.\n- Do not call UPDATE_SETTINGS just because onboarding started. Only update when the user provides a specific value.\n- Answer setting-related questions using only the name, description, and value from the list.`;\n\n if (requiredUnconfigured > 0) {\n const name = senderName || \"user\";\n return `# PRIORITY TASK: Onboarding with ${name}\n\n${agentName} needs to help the user configure ${requiredUnconfigured} required settings:\n\n${settingsList}\n\n${validKeys}\n\n${instructions}\n\n- Prioritize configuring required settings before optional ones.`;\n }\n\n return `All required settings have been configured. Here's the current configuration:\n\n${settingsList}\n\n${validKeys}\n\n${instructions}`;\n }\n\n // Non-onboarding context\n return `## Current Configuration\n\n${\n requiredUnconfigured > 0\n ? `IMPORTANT!: ${requiredUnconfigured} required settings still need configuration. ${agentName} should get onboarded with the OWNER as soon as possible.\\n\\n`\n : \"All required settings are configured.\\n\\n\"\n}${formattedSettings\n .map((s) => {\n if (!s) return \"\";\n return `### ${s.name}\\n**Value:** ${s.value}\\n**Description:** ${s.description}`;\n })\n .filter(Boolean)\n .join(\"\\n\\n\")}`;\n}\n\n/**\n * Onboarding settings provider - injects onboarding context into LLM prompts.\n */\nexport const onboardingSettingsProvider: Provider = {\n name: \"ONBOARDING_SETTINGS\",\n description: \"Current onboarding settings status for secrets collection\",\n\n get: async (\n runtime: IAgentRuntime,\n message: Memory,\n state?: State,\n ): Promise<ProviderResult> => {\n // Get room to determine if we're in DM (onboarding mode)\n const room = await runtime.getRoom(message.roomId);\n if (!room) {\n logger.debug(\"[OnboardingSettingsProvider] No room found\");\n return {\n data: { settings: [] },\n values: { settings: \"Error: Room not found\" },\n text: \"Error: Room not found\",\n };\n }\n\n if (!room.worldId) {\n logger.debug(\"[OnboardingSettingsProvider] No world ID for room\");\n return {\n data: { settings: [] },\n values: { settings: \"Room has no associated world.\" },\n text: \"Room has no associated world.\",\n };\n }\n\n const isOnboarding = room.type === ChannelType.DM;\n\n // Get the world\n const world = await runtime.getWorld(room.worldId);\n if (!world) {\n logger.debug(\"[OnboardingSettingsProvider] No world found\");\n return {\n data: { settings: [] },\n values: { settings: \"Error: World not found\" },\n text: \"Error: World not found\",\n };\n }\n\n // Check for settings in world metadata\n const worldSettings = world.metadata?.settings as\n | Record<string, OnboardingSetting>\n | undefined;\n if (!worldSettings) {\n // No onboarding configured for this world\n if (isOnboarding) {\n return {\n data: { settings: [] },\n values: {\n settings:\n \"No settings configured for this world. Use initializeOnboarding to set up.\",\n },\n text: \"No settings configured for this world.\",\n };\n }\n return {\n data: { settings: [] },\n values: { settings: \"\" },\n text: \"\",\n };\n }\n\n // Generate status message\n const agentName = runtime.character.name ?? \"Agent\";\n const senderName = state?.senderName as string | undefined;\n\n const output = generateStatusMessage(\n worldSettings,\n isOnboarding,\n agentName,\n senderName,\n );\n\n return {\n data: { settings: worldSettings },\n values: { settings: output },\n text: output,\n };\n },\n};\n\n/**\n * Provider that shows what secrets are still needed.\n */\nexport const missingSecretsProvider: Provider = {\n name: \"MISSING_SECRETS\",\n description: \"Lists secrets that still need to be configured\",\n\n get: async (\n runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n ): Promise<ProviderResult> => {\n const room = await runtime.getRoom(message.roomId);\n if (!room?.worldId) {\n return {\n data: { missing: [] },\n values: { missingSecrets: \"\" },\n text: \"\",\n };\n }\n\n const world = await runtime.getWorld(room.worldId);\n if (!world?.metadata?.settings) {\n return {\n data: { missing: [] },\n values: { missingSecrets: \"\" },\n text: \"\",\n };\n }\n\n const settings = world.metadata.settings as Record<\n string,\n OnboardingSetting\n >;\n const entries = Object.entries(settings);\n\n const missingRequired = entries\n .filter(([_, s]) => s.required && s.value === null)\n .map(([key, setting]) => ({\n key,\n name: setting.name,\n description: setting.usageDescription || setting.description,\n }));\n\n const missingOptional = entries\n .filter(([_, s]) => !s.required && s.value === null)\n .map(([key, setting]) => ({\n key,\n name: setting.name,\n description: setting.usageDescription || setting.description,\n }));\n\n if (missingRequired.length === 0 && missingOptional.length === 0) {\n return {\n data: { missing: [] },\n values: { missingSecrets: \"All secrets are configured.\" },\n text: \"All secrets are configured.\",\n };\n }\n\n let output = \"\";\n if (missingRequired.length > 0) {\n output += `Missing required secrets:\\n${missingRequired.map((s) => `- ${s.key}: ${s.description}`).join(\"\\n\")}\\n\\n`;\n }\n if (missingOptional.length > 0) {\n output += `Missing optional secrets:\\n${missingOptional.map((s) => `- ${s.key}: ${s.description}`).join(\"\\n\")}`;\n }\n\n return {\n data: {\n missing: [...missingRequired, ...missingOptional],\n missingRequired,\n missingOptional,\n },\n values: { missingSecrets: output.trim() },\n text: output.trim(),\n };\n },\n};\n","/**\n * Update Settings Action\n *\n * Extracts and saves setting values from natural language user messages.\n * Uses LLM to parse user responses and map them to settings.\n */\n\nimport type {\n Action,\n ActionExample,\n ActionResult,\n Content,\n HandlerCallback,\n HandlerOptions,\n IAgentRuntime,\n Memory,\n State,\n UUID,\n World,\n} from \"@elizaos/core\";\nimport { ChannelType, ModelType, logger } from \"@elizaos/core\";\nimport type { OnboardingSetting } from \"./config\";\nimport type { SecretsService } from \"../services/secrets\";\nimport type { SecretContext } from \"../types\";\nimport { validateSecret } from \"../validation\";\n\n/**\n * Setting update extracted from user message.\n */\ninterface SettingUpdate {\n key: string;\n value: string | boolean;\n}\n\n/**\n * Extract setting values from user message using LLM.\n */\nasync function extractSettingValues(\n runtime: IAgentRuntime,\n message: Memory,\n state: State,\n settings: Record<string, OnboardingSetting>,\n): Promise<SettingUpdate[]> {\n // Find unconfigured settings\n const unconfigured = Object.entries(settings).filter(\n ([_, s]) => s.value === null,\n );\n\n if (unconfigured.length === 0) {\n return [];\n }\n\n // Build context for LLM\n const settingsContext = unconfigured\n .map(([key, setting]) => {\n const requiredStr = setting.required ? \"Required.\" : \"Optional.\";\n return `${key}: ${setting.description} ${requiredStr}`;\n })\n .join(\"\\n\");\n\n const prompt = `I need to extract settings values from the user's message.\n\nAvailable settings:\n${settingsContext}\n\nUser message: ${state.text || message.content?.text || \"\"}\n\nFor each setting mentioned in the user's message, extract the value.\n\nOnly return settings that are clearly mentioned in the user's message.\nIf a setting is mentioned but no clear value is provided, do not include it.`;\n\n // Use LLM to extract settings\n const result = await runtime.useModel<\n typeof ModelType.OBJECT_LARGE,\n SettingUpdate[]\n >(ModelType.OBJECT_LARGE, {\n prompt,\n output: \"array\",\n schema: {\n type: \"array\",\n items: {\n type: \"object\",\n properties: {\n key: { type: \"string\" },\n value: { type: \"string\" },\n },\n required: [\"key\", \"value\"],\n },\n },\n });\n\n if (!result) {\n return [];\n }\n\n // Validate extracted settings exist in our config\n const validUpdates: SettingUpdate[] = [];\n\n const extractFromResult = (obj: unknown): void => {\n if (Array.isArray(obj)) {\n for (const item of obj) {\n extractFromResult(item);\n }\n } else if (typeof obj === \"object\" && obj !== null) {\n for (const [key, value] of Object.entries(obj)) {\n if (settings[key] && typeof value !== \"object\") {\n validUpdates.push({ key, value: value as string });\n } else {\n extractFromResult(value);\n }\n }\n }\n };\n\n extractFromResult(result);\n return validUpdates;\n}\n\n/**\n * Process setting updates and save to storage.\n */\nasync function processSettingUpdates(\n runtime: IAgentRuntime,\n world: World,\n settings: Record<string, OnboardingSetting>,\n updates: SettingUpdate[],\n secretsService: SecretsService | null,\n): Promise<{ updatedAny: boolean; messages: string[] }> {\n if (!updates.length) {\n return { updatedAny: false, messages: [] };\n }\n\n const messages: string[] = [];\n let updatedAny = false;\n const updatedSettings = { ...settings };\n\n for (const update of updates) {\n const setting = updatedSettings[update.key];\n if (!setting) continue;\n\n // Check dependencies\n if (setting.dependsOn?.length) {\n const dependenciesMet = setting.dependsOn.every((dep) => {\n const depSetting = updatedSettings[dep];\n return depSetting && depSetting.value !== null;\n });\n if (!dependenciesMet) {\n messages.push(`Cannot update ${setting.name} - dependencies not met`);\n continue;\n }\n }\n\n // Validate\n const valueStr = String(update.value);\n if (setting.validation && !setting.validation(valueStr)) {\n messages.push(`Invalid value for ${setting.name}`);\n continue;\n }\n\n if (setting.validationMethod) {\n const validation = await validateSecret(\n update.key,\n valueStr,\n setting.validationMethod,\n );\n if (!validation.isValid) {\n messages.push(\n `Validation failed for ${setting.name}: ${validation.error}`,\n );\n continue;\n }\n }\n\n // Update local state\n updatedSettings[update.key] = {\n ...setting,\n value: valueStr,\n };\n\n // Store in secrets service if available\n if (secretsService) {\n const context: SecretContext = {\n level: \"world\",\n agentId: runtime.agentId,\n worldId: world.id,\n };\n\n await secretsService.set(update.key, valueStr, context, {\n description: setting.description,\n type: setting.type,\n encrypted: setting.secret,\n });\n }\n\n messages.push(`Updated ${setting.name} successfully`);\n updatedAny = true;\n\n // Execute onSetAction if defined\n if (setting.onSetAction) {\n const actionMessage = setting.onSetAction(update.value);\n if (actionMessage) {\n messages.push(actionMessage);\n }\n }\n }\n\n // Save updated settings to world metadata\n if (updatedAny) {\n if (!world.metadata) {\n (world as { metadata?: unknown }).metadata = {};\n }\n // Cast to allow storing our extended settings type\n (world.metadata as Record<string, unknown>)[\"settings\"] = updatedSettings;\n await runtime.updateWorld(world);\n }\n\n return { updatedAny, messages };\n}\n\n/**\n * Get the next setting to configure.\n */\nfunction getNextRequiredSetting(\n settings: Record<string, OnboardingSetting>,\n): [string, OnboardingSetting] | null {\n const entries = Object.entries(settings);\n\n // Find unconfigured required settings\n for (const [key, setting] of entries) {\n if (!setting.required || setting.value !== null) continue;\n\n // Check dependencies\n const dependenciesMet = (setting.dependsOn || []).every((dep) => {\n const depSetting = settings[dep];\n return depSetting && depSetting.value !== null;\n });\n\n if (dependenciesMet) {\n return [key, setting];\n }\n }\n\n return null;\n}\n\n/**\n * Count unconfigured required settings.\n */\nfunction countUnconfiguredRequired(\n settings: Record<string, OnboardingSetting>,\n): number {\n return Object.values(settings).filter((s) => s.required && s.value === null)\n .length;\n}\n\n/**\n * UPDATE_SETTINGS Action - extracts and saves settings from natural language.\n */\nexport const updateSettingsAction: Action = {\n name: \"UPDATE_SETTINGS\",\n similes: [\"UPDATE_SETTING\", \"SAVE_SETTING\", \"SET_CONFIGURATION\", \"CONFIGURE\"],\n description:\n \"Saves a configuration setting during the onboarding process. Use when onboarding with a world owner or admin.\",\n\n validate: async (\n runtime: IAgentRuntime,\n message: Memory,\n _state?: State,\n ): Promise<boolean> => {\n // Only validate in DM context\n if (message.content.channelType !== ChannelType.DM) {\n return false;\n }\n\n // Check if there's a world with settings\n const room = await runtime.getRoom(message.roomId);\n if (!room?.worldId) return false;\n\n const world = await runtime.getWorld(room.worldId);\n if (!world?.metadata?.settings) return false;\n\n const settings = world.metadata.settings as Record<\n string,\n OnboardingSetting\n >;\n const hasUnconfigured = Object.values(settings).some(\n (s) => s.value === null,\n );\n\n return hasUnconfigured;\n },\n\n handler: async (\n runtime: IAgentRuntime,\n message: Memory,\n state?: State,\n _options?: HandlerOptions,\n callback?: HandlerCallback,\n ): Promise<ActionResult> => {\n if (!state || !callback) {\n return {\n text: \"State and callback required\",\n values: { success: false },\n data: { actionName: \"UPDATE_SETTINGS\" },\n success: false,\n };\n }\n\n // Get room and world\n const room = await runtime.getRoom(message.roomId);\n if (!room?.worldId) {\n await callback({ text: \"Unable to find room configuration.\" });\n return {\n text: \"Room not found\",\n values: { success: false },\n data: { actionName: \"UPDATE_SETTINGS\" },\n success: false,\n };\n }\n\n const world = await runtime.getWorld(room.worldId);\n if (!world?.metadata?.settings) {\n await callback({ text: \"No settings configured for this world.\" });\n return {\n text: \"No settings found\",\n values: { success: false },\n data: { actionName: \"UPDATE_SETTINGS\" },\n success: false,\n };\n }\n\n const settings = world.metadata.settings as Record<\n string,\n OnboardingSetting\n >;\n\n // Get secrets service\n const secretsService = runtime.getService(\n \"SECRETS\",\n ) as SecretsService | null;\n\n // Extract settings from message\n logger.info(\"[UpdateSettings] Extracting settings from message\");\n const extractedSettings = await extractSettingValues(\n runtime,\n message,\n state,\n settings,\n );\n logger.info(\n `[UpdateSettings] Extracted ${extractedSettings.length} settings`,\n );\n\n // Process updates\n const results = await processSettingUpdates(\n runtime,\n world,\n settings,\n extractedSettings,\n secretsService,\n );\n\n // Get updated settings\n const updatedWorld = await runtime.getWorld(room.worldId);\n const updatedSettings = updatedWorld?.metadata?.settings as Record<\n string,\n OnboardingSetting\n >;\n\n if (results.updatedAny) {\n const remaining = countUnconfiguredRequired(updatedSettings || settings);\n\n if (remaining === 0) {\n // All required settings configured\n await callback({\n text: `${results.messages.join(\"\\n\")}\\n\\nAll required settings have been configured! You're all set.`,\n actions: [\"ONBOARDING_COMPLETE\"],\n });\n\n return {\n text: \"Onboarding complete\",\n values: { success: true, onboardingComplete: true },\n data: {\n actionName: \"UPDATE_SETTINGS\",\n action: \"ONBOARDING_COMPLETE\",\n },\n success: true,\n };\n }\n\n // More settings needed\n const next = getNextRequiredSetting(updatedSettings || settings);\n const nextPrompt = next\n ? `\\n\\nNext, I need your ${next[1].name}. ${next[1].usageDescription || next[1].description}`\n : \"\";\n\n await callback({\n text: `${results.messages.join(\"\\n\")}${nextPrompt}`,\n actions: [\"SETTING_UPDATED\"],\n });\n\n return {\n text: \"Settings updated\",\n values: { success: true, remainingRequired: remaining },\n data: {\n actionName: \"UPDATE_SETTINGS\",\n action: \"SETTING_UPDATED\",\n updated: extractedSettings.map((s) => s.key),\n },\n success: true,\n };\n }\n\n // No settings extracted\n const next = getNextRequiredSetting(settings);\n const prompt = next\n ? `I couldn't understand that. I need your ${next[1].name}. ${next[1].usageDescription || next[1].description}`\n : \"I couldn't extract any settings from your message. Could you try again?\";\n\n await callback({\n text: prompt,\n actions: [\"SETTING_UPDATE_FAILED\"],\n });\n\n return {\n text: \"No settings updated\",\n values: { success: false },\n data: { actionName: \"UPDATE_SETTINGS\", action: \"SETTING_UPDATE_FAILED\" },\n success: false,\n };\n },\n\n examples: [\n [\n {\n name: \"{{name1}}\",\n content: {\n text: \"My OpenAI key is sk-abc123def456\",\n source: \"discord\",\n },\n },\n {\n name: \"{{name2}}\",\n content: {\n text: \"Got it! I've saved your OpenAI API Key. Next, I need your Anthropic API Key.\",\n actions: [\"SETTING_UPDATED\"],\n source: \"discord\",\n },\n },\n ],\n [\n {\n name: \"{{name1}}\",\n content: {\n text: \"Here's my Twitter login: @myhandle with password secret123\",\n source: \"discord\",\n },\n },\n {\n name: \"{{name2}}\",\n content: {\n text: \"Perfect! I've updated your Twitter Username and Twitter Password. We're all set!\",\n actions: [\"ONBOARDING_COMPLETE\"],\n source: \"discord\",\n },\n },\n ],\n ] as ActionExample[][],\n};\n"],"mappings":"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","names":["logger","logger","logger","logger","logger","logger","logger","logger","Service","logger","DEFAULT_CONFIG","Service","logger","logger","logger","ModelType","logger","composePromptFromState","logger","composePromptFromState","ModelType","logger","logger","Service","logger","Service","logger","next","ChannelType","logger","ChannelType","ModelType","logger","ModelType","ChannelType","logger","next","logger"]}
|