Profiles~
diff --git a/interpreter/terminal_interface/profiles.yaml b/interpreter/terminal_interface/profiles.yaml
new file mode 100644
index 000000000..aff44a2f9
--- /dev/null
+++ b/interpreter/terminal_interface/profiles.yaml
@@ -0,0 +1,13 @@
+default:
+  llm.model: "gpt-4-1106-preview"
+  llm.context_window: 128000
+  llm.max_tokens: 4096
+  llm.supports_functions: True
+
+local:
+  offline: True
+  llm.model: "openai/x"  # "openai/" tells Lit
+  llm.api_base: "http://localhost:1234/v1"
+  llm.max_tokens: 1000
+  llm.context_window: 3000
+  llm.api_key: "x"
\ No newline at end of file
diff --git a/interpreter/terminal_interface/start_terminal_interface.py b/interpreter/terminal_interface/start_terminal_interface.py
index 2a24c6c47..376888100 100644
--- a/interpreter/terminal_interface/start_terminal_interface.py
+++ b/interpreter/terminal_interface/start_terminal_interface.py
@@ -13,6 +13,7 @@
 from .utils.check_for_update import check_for_update
 from .utils.display_markdown_message import display_markdown_message
 from .utils.get_config import get_config_path
+from .utils.profiles import apply_profile, get_profile_path
 from .validate_llm_settings import validate_llm_settings
 
 
@@ -23,13 +24,14 @@ def start_terminal_interface(interpreter):
 
     arguments = [
         # Profiles coming soon— after we seperate core from TUI
-        # {
-        #     "name": "profile",
-        #     "nickname": "p",
-        #     "help_text": "profile (from your config file) to use. sets multiple settings at once",
-        #     "type": str,
-        #     "default": "default",
-        # },
+        {
+            "name": "profile",
+            "nickname": "p",
+            "help_text": "profile (from your config file) to use. sets multiple settings at once",
+            "type": str,
+            "default": "default",
+            "attribute": {"object": interpreter, "attr_name": "profile"},
+        },
         {
             "name": "custom_instructions",
             "nickname": "ci",
@@ -181,7 +183,6 @@ def start_terminal_interface(interpreter):
             "type": str,
             "attribute": {"object": interpreter, "attr_name": "config_file"},
         },
-        # Profiles
         {
             "name": "fast",
             "nickname": "f",
@@ -628,6 +629,13 @@ def start_terminal_interface(interpreter):
         # Apply default config file
         interpreter = apply_config(interpreter)
 
+    if args.profile:
+        # We can add custom profile path, I'll leave it out for first PR
+        print(vars(args).get("profile"))
+        interpreter.profile = vars(args).get("profile")
+        user_profile = get_profile_path()
+        interpreter = apply_profile(interpreter, user_profile)
+
     # Set attributes on interpreter
     for argument_name, argument_value in vars(args).items():
         if argument_value != None:
diff --git a/interpreter/terminal_interface/utils/get_config.py b/interpreter/terminal_interface/utils/get_config.py
index 8d2807560..f2e374283 100644
--- a/interpreter/terminal_interface/utils/get_config.py
+++ b/interpreter/terminal_interface/utils/get_config.py
@@ -55,7 +55,7 @@ def get_config(path=user_config_path):
     config = None
 
     try:
-        with open(path, "r", encoding='utf-8') as file:
+        with open(path, "r", encoding="utf-8") as file:
             config = yaml.safe_load(file)
             if config is not None:
                 return config
diff --git a/interpreter/terminal_interface/utils/profiles.py b/interpreter/terminal_interface/utils/profiles.py
new file mode 100644
index 000000000..17271102c
--- /dev/null
+++ b/interpreter/terminal_interface/utils/profiles.py
@@ -0,0 +1,93 @@
+import logging
+import os
+import shutil
+
+import yaml
+
+from .local_storage_path import get_storage_path
+
+# Constants for file paths
+PROFILE_FILENAME = "profiles.yaml"
+USER_PROFILE_PATH = os.path.join(get_storage_path(), PROFILE_FILENAME)
+
+
+def get_profile_path(path=USER_PROFILE_PATH):
+    """
+    Retrieve the path to the profile. If the path does not exist, create a new profile.
+    :param path: The path or filename for the profile.
+    :return: The full path to the profile.
+    """
+    # Constructing full paths for various locations
+    profile_dir = get_storage_path()
+    current_dir = os.getcwd()
+
+    # Check if path exists, or if it's in profile or current directory
+    if not os.path.exists(path):
+        if os.path.exists(os.path.join(profile_dir, path)):
+            path = os.path.join(profile_dir, path)
+        elif os.path.exists(os.path.join(current_dir, path)):
+            path = os.path.join(current_dir, path)
+        else:
+            # Create directory if it doesn't exist
+            directory = os.path.dirname(path)
+            if directory and not os.path.exists(directory):
+                os.makedirs(directory, exist_ok=True)
+            else:
+                os.makedirs(profile_dir, exist_ok=True)
+                path = os.path.join(profile_dir, path)
+
+            # Copy default profile
+            default_profile_path = os.path.join(
+                os.path.dirname(os.path.dirname(__file__)), PROFILE_FILENAME
+            )
+            shutil.copy(default_profile_path, path)
+
+    return path
+
+
+def get_profile(path=USER_PROFILE_PATH):
+    """
+    Load and return the user profile from the given path.
+    :param path: The path to the profile file.
+    :return: A dictionary containing the profile data.
+    """
+    path = get_profile_path(path)
+    try:
+        with open(path, "r", encoding="utf-8") as file:
+            profile = yaml.safe_load(file)
+            return profile if profile else {}
+    except UnicodeDecodeError:
+        logging.warning(
+            "Profile file can't be read due to a Unicode decoding error. "
+            "Ensure it is saved in UTF-8 format. Run `interpreter --reset_profile` to reset it."
+        )
+    except Exception as e:
+        logging.warning(f"An error occurred while reading the profile file: {e}.")
+    return {}
+
+
+def apply_profile(self, profile_path=None):
+    """
+    Apply the user profile settings from the specified path.
+    If profile_path is None, the default path is used.
+    The method uses self.profile to access the current profile name.
+    :param profile_path: The path to the profile file.
+    """
+    if profile_path is None:
+        profile_path = get_profile_path()
+
+    profile = get_profile(profile_path)
+
+    # Retrieve the specific profile based on the current profile name
+    selected_profile = profile.get(self.profile, {})
+
+    # Apply settings from the selected profile
+    for key, value in selected_profile.items():
+        if key.startswith("llm."):
+            setattr(self.llm, key[4:], value)  # For 'llm.' prefixed keys
+        elif key.startswith("computer."):
+            setattr(self.computer, key[9:], value)  # For 'computer.' prefixed keys
+        else:
+            setattr(self, key, value)  # For other keys
+
+    return self

### Describe the changes you have made:

### Reference any relevant issues (e.g. "Fixes #000"):

### Pre-Submission Checklist (optional but appreciated):

- [ ] I have included relevant documentation updates (stored in /docs)
- [x] I have read `docs/CONTRIBUTING.md`
- [ ] I have read `docs/ROADMAP.md`

### OS Tests (optional but appreciated):

- [x] Tested on Windows
- [ ] Tested on MacOS
- [ ] Tested on Linux
