feat: soft disable LOCAL code interpreter driver in production (#16647)
## Summary Instead of throwing an error at server startup when LOCAL code interpreter is configured in production, we now return a DisabledDriver that only throws when the code interpreter is actually used. ## Changes - Created `DisabledDriver` class that implements `CodeInterpreterDriver` but throws an error only when `execute()` is called - Added `DISABLED` to the `CodeInterpreterDriverType` enum - Updated the factory to return a `DISABLED` driver config instead of throwing when LOCAL is used in production - Updated the module to handle the new `DISABLED` driver type ## Motivation Many users don't need the code interpreter feature and want to deploy to production without configuring E2B. Previously, the server would crash at startup if `CODE_INTERPRETER_TYPE=LOCAL` was set in production. **Before:** Server crashes at startup in production if `CODE_INTERPRETER_TYPE=LOCAL` **After:** Server starts fine. The error only occurs if someone actually tries to **use** the code interpreter feature, at which point they get a clear error message explaining how to configure E2B.
This commit is contained in:
+16
-3
@@ -18,9 +18,13 @@ export const codeInterpreterModuleFactory = async (
|
||||
const nodeEnv = twentyConfigService.get('NODE_ENV');
|
||||
|
||||
if (nodeEnv === NodeEnvironment.PRODUCTION) {
|
||||
throw new Error(
|
||||
'LOCAL code interpreter driver is not allowed in production. Use E2B driver instead by setting CODE_INTERPRETER_TYPE=E2B and providing E2B_API_KEY.',
|
||||
);
|
||||
return {
|
||||
type: CodeInterpreterDriverType.DISABLED,
|
||||
options: {
|
||||
reason:
|
||||
'LOCAL code interpreter driver is not allowed in production. Use E2B driver instead by setting CODE_INTERPRETER_TYPE=E2B and providing E2B_API_KEY.',
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
return {
|
||||
@@ -45,6 +49,15 @@ export const codeInterpreterModuleFactory = async (
|
||||
},
|
||||
};
|
||||
}
|
||||
case CodeInterpreterDriverType.DISABLED: {
|
||||
return {
|
||||
type: CodeInterpreterDriverType.DISABLED,
|
||||
options: {
|
||||
reason:
|
||||
'Code interpreter is disabled. Set CODE_INTERPRETER_TYPE to LOCAL (development only) or E2B to enable it.',
|
||||
},
|
||||
};
|
||||
}
|
||||
default:
|
||||
throw new Error(
|
||||
`Invalid code interpreter driver type (${driverType}), check your .env file`,
|
||||
|
||||
+8
-1
@@ -6,6 +6,7 @@ import { type LocalDriverOptions } from './drivers/local.driver';
|
||||
export enum CodeInterpreterDriverType {
|
||||
LOCAL = 'LOCAL',
|
||||
E_2_B = 'E_2_B',
|
||||
DISABLED = 'DISABLED',
|
||||
}
|
||||
|
||||
export type LocalDriverFactoryOptions = {
|
||||
@@ -18,9 +19,15 @@ export type E2BDriverFactoryOptions = {
|
||||
options: E2BDriverOptions;
|
||||
};
|
||||
|
||||
export type DisabledDriverFactoryOptions = {
|
||||
type: CodeInterpreterDriverType.DISABLED;
|
||||
options: { reason: string };
|
||||
};
|
||||
|
||||
export type CodeInterpreterModuleOptions =
|
||||
| LocalDriverFactoryOptions
|
||||
| E2BDriverFactoryOptions;
|
||||
| E2BDriverFactoryOptions
|
||||
| DisabledDriverFactoryOptions;
|
||||
|
||||
export type CodeInterpreterModuleAsyncOptions = {
|
||||
useFactory: (
|
||||
|
||||
+9
-3
@@ -7,6 +7,7 @@ import {
|
||||
} from './code-interpreter.interface';
|
||||
import { CodeInterpreterService } from './code-interpreter.service';
|
||||
|
||||
import { DisabledDriver } from './drivers/disabled.driver';
|
||||
import { E2BDriver } from './drivers/e2b.driver';
|
||||
import { LocalDriver } from './drivers/local.driver';
|
||||
|
||||
@@ -20,9 +21,14 @@ export class CodeInterpreterModule {
|
||||
useFactory: async (...args: unknown[]) => {
|
||||
const config = await options.useFactory(...args);
|
||||
|
||||
return config.type === CodeInterpreterDriverType.LOCAL
|
||||
? new LocalDriver(config.options)
|
||||
: new E2BDriver(config.options);
|
||||
switch (config.type) {
|
||||
case CodeInterpreterDriverType.LOCAL:
|
||||
return new LocalDriver(config.options);
|
||||
case CodeInterpreterDriverType.E_2_B:
|
||||
return new E2BDriver(config.options);
|
||||
case CodeInterpreterDriverType.DISABLED:
|
||||
return new DisabledDriver(config.options.reason);
|
||||
}
|
||||
},
|
||||
inject: options.inject ?? [],
|
||||
};
|
||||
|
||||
+20
@@ -0,0 +1,20 @@
|
||||
import {
|
||||
type CodeExecutionResult,
|
||||
type CodeInterpreterDriver,
|
||||
type ExecutionContext,
|
||||
type InputFile,
|
||||
type StreamCallbacks,
|
||||
} from './interfaces/code-interpreter-driver.interface';
|
||||
|
||||
export class DisabledDriver implements CodeInterpreterDriver {
|
||||
constructor(private reason: string) {}
|
||||
|
||||
async execute(
|
||||
_code: string,
|
||||
_files?: InputFile[],
|
||||
_context?: ExecutionContext,
|
||||
_callbacks?: StreamCallbacks,
|
||||
): Promise<CodeExecutionResult> {
|
||||
throw new Error(this.reason);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user