config.py 2.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596
  1. import copy
  2. import os
  3. import argparse
  4. import toml
  5. from dotenv import load_dotenv
  6. from opendevin.schema import ConfigType
  7. load_dotenv()
  8. DEFAULT_CONFIG: dict = {
  9. ConfigType.LLM_API_KEY: None,
  10. ConfigType.LLM_BASE_URL: None,
  11. ConfigType.WORKSPACE_BASE: os.getcwd(),
  12. ConfigType.WORKSPACE_MOUNT_PATH: None,
  13. ConfigType.WORKSPACE_MOUNT_REWRITE: None,
  14. ConfigType.LLM_MODEL: 'gpt-3.5-turbo-1106',
  15. ConfigType.SANDBOX_CONTAINER_IMAGE: 'ghcr.io/opendevin/sandbox',
  16. ConfigType.RUN_AS_DEVIN: 'true',
  17. ConfigType.LLM_EMBEDDING_MODEL: 'local',
  18. ConfigType.LLM_DEPLOYMENT_NAME: None,
  19. ConfigType.LLM_API_VERSION: None,
  20. ConfigType.LLM_NUM_RETRIES: 6,
  21. ConfigType.LLM_COOLDOWN_TIME: 1,
  22. ConfigType.MAX_ITERATIONS: 100,
  23. # GPT-4 pricing is $10 per 1M input tokens. Since tokenization happens on LLM side,
  24. # we cannot easily count number of tokens, but we can count characters.
  25. # Assuming 5 characters per token, 5 million is a reasonable default limit.
  26. ConfigType.MAX_CHARS: 5_000_000,
  27. ConfigType.AGENT: 'MonologueAgent',
  28. ConfigType.SANDBOX_TYPE: 'ssh',
  29. ConfigType.USE_HOST_NETWORK: 'false',
  30. ConfigType.SSH_HOSTNAME: 'localhost',
  31. ConfigType.DISABLE_COLOR: 'false',
  32. }
  33. config_str = ''
  34. if os.path.exists('config.toml'):
  35. with open('config.toml', 'rb') as f:
  36. config_str = f.read().decode('utf-8')
  37. tomlConfig = toml.loads(config_str)
  38. config = DEFAULT_CONFIG.copy()
  39. for k, v in config.items():
  40. if k in os.environ:
  41. config[k] = os.environ[k]
  42. elif k in tomlConfig:
  43. config[k] = tomlConfig[k]
  44. def parse_arguments():
  45. parser = argparse.ArgumentParser(
  46. description='Run an agent with a specific task')
  47. parser.add_argument(
  48. '-d',
  49. '--directory',
  50. type=str,
  51. help='The working directory for the agent',
  52. )
  53. args, _ = parser.parse_known_args()
  54. if args.directory:
  55. config[ConfigType.WORKSPACE_BASE] = os.path.abspath(args.directory)
  56. print(f"Setting workspace base to {config[ConfigType.WORKSPACE_BASE]}")
  57. parse_arguments()
  58. def finalize_config():
  59. if config.get(ConfigType.WORKSPACE_MOUNT_REWRITE) and not config.get(ConfigType.WORKSPACE_MOUNT_PATH):
  60. base = config.get(ConfigType.WORKSPACE_BASE) or os.getcwd()
  61. parts = config[ConfigType.WORKSPACE_MOUNT_REWRITE].split(':')
  62. config[ConfigType.WORKSPACE_MOUNT_PATH] = base.replace(parts[0], parts[1])
  63. finalize_config()
  64. def get(key: str, required: bool = False):
  65. """
  66. Get a key from the environment variables or config.toml or default configs.
  67. """
  68. value = config.get(key)
  69. if not value and required:
  70. raise KeyError(f"Please set '{key}' in `config.toml` or `.env`.")
  71. return value
  72. def get_fe_config() -> dict:
  73. """
  74. Get all the frontend configuration values by performing a deep copy.
  75. """
  76. fe_config = copy.deepcopy(config)
  77. del fe_config['LLM_API_KEY']
  78. return fe_config