diff --git a/agent/src/index.ts b/agent/src/index.ts index f3ae5f04b3..683a7bcf2c 100644 --- a/agent/src/index.ts +++ b/agent/src/index.ts @@ -371,12 +371,7 @@ export async function createAgent( character.name ); - nodePlugin ??= ( - getSecret(character, "AWS_ACCESS_KEY_ID") && - getSecret(character, "AWS_SECRET_ACCESS_KEY") && - getSecret(character, "AWS_REGION") && - getSecret(character, "AWS_S3_BUCKET") - ) ? createNodePlugin() : undefined; + nodePlugin ??= createNodePlugin(); const teeMode = getSecret(character, "TEE_MODE") || "OFF"; const walletSecretSalt = getSecret(character, "WALLET_SECRET_SALT"); diff --git a/packages/plugin-node/src/environment.ts b/packages/plugin-node/src/environment.ts index 5d30bb93ed..ef524d03a3 100644 --- a/packages/plugin-node/src/environment.ts +++ b/packages/plugin-node/src/environment.ts @@ -71,6 +71,15 @@ export async function validateNodeConfig( // VITS settings VITS_VOICE: voiceSettings?.model || process.env.VITS_VOICE, VITS_MODEL: process.env.VITS_MODEL, + + // AWS settings (only include if present) + ...(runtime.getSetting("AWS_ACCESS_KEY_ID") && { + AWS_ACCESS_KEY_ID: runtime.getSetting("AWS_ACCESS_KEY_ID"), + AWS_SECRET_ACCESS_KEY: runtime.getSetting("AWS_SECRET_ACCESS_KEY"), + AWS_REGION: runtime.getSetting("AWS_REGION"), + AWS_S3_BUCKET: runtime.getSetting("AWS_S3_BUCKET"), + AWS_S3_UPLOAD_PATH: runtime.getSetting("AWS_S3_UPLOAD_PATH"), + }), }; return nodeEnvSchema.parse(config); diff --git a/packages/plugin-node/src/services/awsS3.ts b/packages/plugin-node/src/services/awsS3.ts index 16a50e13a3..57600ada5b 100644 --- a/packages/plugin-node/src/services/awsS3.ts +++ b/packages/plugin-node/src/services/awsS3.ts @@ -26,32 +26,28 @@ interface JsonUploadResult extends UploadResult { export class AwsS3Service extends Service implements IAwsS3Service { static serviceType: ServiceType = ServiceType.AWS_S3; - private s3Client: S3Client; - private bucket: string; - private fileUploadPath: string; - getInstance(): IAwsS3Service { - return AwsS3Service.getInstance(); - } + private s3Client: S3Client | null = null; + private bucket: string = ''; + private fileUploadPath: string = ''; private runtime: IAgentRuntime | null = null; async initialize(runtime: IAgentRuntime): Promise { console.log("Initializing AwsS3Service"); this.runtime = runtime; - const AWS_ACCESS_KEY_ID = runtime.getSetting("AWS_ACCESS_KEY_ID"); - const AWS_SECRET_ACCESS_KEY = runtime.getSetting( - "AWS_SECRET_ACCESS_KEY" - ); - const AWS_REGION = runtime.getSetting("AWS_REGION"); - const AWS_S3_BUCKET = runtime.getSetting("AWS_S3_BUCKET"); - if ( - !AWS_ACCESS_KEY_ID || - !AWS_SECRET_ACCESS_KEY || - !AWS_REGION || - !AWS_S3_BUCKET - ) { - throw new Error( - "Missing required AWS credentials in environment variables" - ); + this.fileUploadPath = runtime.getSetting("AWS_S3_UPLOAD_PATH") ?? ""; + } + + private async initializeS3Client(): Promise { + if (this.s3Client) return true; + if (!this.runtime) return false; + + const AWS_ACCESS_KEY_ID = this.runtime.getSetting("AWS_ACCESS_KEY_ID"); + const AWS_SECRET_ACCESS_KEY = this.runtime.getSetting("AWS_SECRET_ACCESS_KEY"); + const AWS_REGION = this.runtime.getSetting("AWS_REGION"); + const AWS_S3_BUCKET = this.runtime.getSetting("AWS_S3_BUCKET"); + + if (!AWS_ACCESS_KEY_ID || !AWS_SECRET_ACCESS_KEY || !AWS_REGION || !AWS_S3_BUCKET) { + return false; } this.s3Client = new S3Client({ @@ -61,8 +57,8 @@ export class AwsS3Service extends Service implements IAwsS3Service { secretAccessKey: AWS_SECRET_ACCESS_KEY, }, }); - this.fileUploadPath = runtime.getSetting("AWS_S3_UPLOAD_PATH") ?? ""; this.bucket = AWS_S3_BUCKET; + return true; } async uploadFile( @@ -71,6 +67,13 @@ export class AwsS3Service extends Service implements IAwsS3Service { expiresIn: number = 900 ): Promise { try { + if (!await this.initializeS3Client()) { + return { + success: false, + error: "AWS S3 credentials not configured", + }; + } + if (!fs.existsSync(filePath)) { return { success: false, @@ -120,10 +123,7 @@ export class AwsS3Service extends Service implements IAwsS3Service { } catch (error) { return { success: false, - error: - error instanceof Error - ? error.message - : "Unknown error occurred", + error: error instanceof Error ? error.message : "Unknown error occurred", }; } } @@ -135,6 +135,10 @@ export class AwsS3Service extends Service implements IAwsS3Service { fileName: string, expiresIn: number = 900 ): Promise { + if (!await this.initializeS3Client()) { + throw new Error("AWS S3 credentials not configured"); + } + const command = new GetObjectCommand({ Bucket: this.bucket, Key: fileName, @@ -171,6 +175,13 @@ export class AwsS3Service extends Service implements IAwsS3Service { expiresIn: number = 900 ): Promise { try { + if (!await this.initializeS3Client()) { + return { + success: false, + error: "AWS S3 credentials not configured", + }; + } + // Validate input if (!jsonData) { return {