From e4a40479cc1aacb1d91481e047ba2790c41ec16c Mon Sep 17 00:00:00 2001
From: Nate Sesti <sestinj@gmail.com>
Date: Sun, 4 Jun 2023 00:34:05 -0400
Subject: .continue/config.json

---
 continuedev/src/continuedev/core/abstract_sdk.py   | 85 ++++++++++++++++++++++
 continuedev/src/continuedev/core/policy.py         |  4 +-
 continuedev/src/continuedev/core/sdk.py            | 14 +++-
 continuedev/src/continuedev/libs/util/telemetry.py |  2 +-
 continuedev/src/continuedev/steps/main.py          | 15 ++++
 5 files changed, 113 insertions(+), 7 deletions(-)
 create mode 100644 continuedev/src/continuedev/core/abstract_sdk.py

(limited to 'continuedev/src')

diff --git a/continuedev/src/continuedev/core/abstract_sdk.py b/continuedev/src/continuedev/core/abstract_sdk.py
new file mode 100644
index 00000000..9278f873
--- /dev/null
+++ b/continuedev/src/continuedev/core/abstract_sdk.py
@@ -0,0 +1,85 @@
+from abc import ABC, abstractmethod
+from typing import Coroutine, List
+
+from .config import ContinueConfig
+from ..models.filesystem_edit import FileSystemEdit
+from .observation import Observation
+from .main import History, Step
+
+
+"""
+[[Generate]]
+[Prompt]
+Write an abstract class AbstractContinueSDK(ABC) that has all of the same methods as the ContinueSDK class, but without any implementation.
+All methods should be documented with the same docstrings as the ContinueSDK class and have the same types.
+[Context]
+./sdk.py:ContinueSDK
+"""
+
+
+class AbstractContinueSDK(ABC):
+    """The SDK provided as parameters to a step"""
+
+    @property
+    def history(self) -> History:
+        return self.__autopilot.history
+
+    @abstractmethod
+    async def _ensure_absolute_path(self, path: str) -> str:
+        pass
+
+    @abstractmethod
+    async def run_step(self, step: Step) -> Coroutine[Observation, None, None]:
+        pass
+
+    @abstractmethod
+    async def apply_filesystem_edit(self, edit: FileSystemEdit):
+        pass
+
+    @abstractmethod
+    async def wait_for_user_input(self) -> str:
+        pass
+
+    @abstractmethod
+    async def wait_for_user_confirmation(self, prompt: str):
+        pass
+
+    @abstractmethod
+    async def run(self, commands: List[str] | str, cwd: str = None):
+        pass
+
+    @abstractmethod
+    async def edit_file(self, filename: str, prompt: str):
+        pass
+
+    @abstractmethod
+    async def append_to_file(self, filename: str, content: str):
+        pass
+
+    @abstractmethod
+    async def add_file(self, filename: str, content: str | None):
+        pass
+
+    @abstractmethod
+    async def delete_file(self, filename: str):
+        pass
+
+    @abstractmethod
+    async def add_directory(self, path: str):
+        pass
+
+    @abstractmethod
+    async def delete_directory(self, path: str):
+        pass
+
+    @abstractmethod
+    async def get_user_secret(self, env_var: str, prompt: str) -> str:
+        pass
+
+    @abstractmethod
+    async def get_config(self) -> ContinueConfig:
+        pass
+
+    @abstractmethod
+    def set_loading_message(self, message: str):
+        pass
diff --git a/continuedev/src/continuedev/core/policy.py b/continuedev/src/continuedev/core/policy.py
index dc71cfa9..a946200e 100644
--- a/continuedev/src/continuedev/core/policy.py
+++ b/continuedev/src/continuedev/core/policy.py
@@ -4,7 +4,7 @@ from ..steps.steps_on_startup import StepsOnStartupStep
 from ..recipes.CreatePipelineRecipe.main import CreatePipelineRecipe
 from .main import Step, Validator, History, Policy
 from .observation import Observation, TracebackObservation, UserInputObservation
-from ..steps.main import EditHighlightedCodeStep, SolveTracebackStep, RunCodeStep, FasterEditHighlightedCodeStep, StarCoderEditHighlightedCodeStep, MessageStep, EmptyStep
+from ..steps.main import EditHighlightedCodeStep, SolveTracebackStep, RunCodeStep, FasterEditHighlightedCodeStep, StarCoderEditHighlightedCodeStep, MessageStep, EmptyStep, SetupContinueWorkspaceStep
 from ..recipes.WritePytestsRecipe.main import WritePytestsRecipe
 # from ..libs.steps.chroma import AnswerQuestionChroma, EditFileChroma
 from ..recipes.ContinueRecipeRecipe.main import ContinueStepStep
@@ -17,7 +17,7 @@ class DemoPolicy(Policy):
     def next(self, history: History) -> Step:
         # At the very start, run initial Steps spcecified in the config
         if history.get_current() is None:
-            return MessageStep(message="Welcome to Continue!") >> StepsOnStartupStep()
+            return MessageStep(message="Welcome to Continue!") >> SetupContinueWorkspaceStep() >> StepsOnStartupStep()
 
         observation = history.get_current().observation
         if observation is not None and isinstance(observation, UserInputObservation):
diff --git a/continuedev/src/continuedev/core/sdk.py b/continuedev/src/continuedev/core/sdk.py
index 5ae471c4..de14ee3c 100644
--- a/continuedev/src/continuedev/core/sdk.py
+++ b/continuedev/src/continuedev/core/sdk.py
@@ -1,6 +1,8 @@
-import os
+from abc import ABC, abstractmethod
 from typing import Coroutine, Union
+import os
 
+from .abstract_sdk import AbstractContinueSDK
 from .config import ContinueConfig, load_config
 from ..models.filesystem_edit import FileEdit, FileSystemEdit, AddFile, DeleteFile, AddDirectory, DeleteDirectory
 from ..models.filesystem import RangeInFile
@@ -37,7 +39,7 @@ class Models:
         return OpenAI(api_key=api_key, default_model="gpt-3.5-turbo")
 
 
-class ContinueSDK:
+class ContinueSDK(AbstractContinueSDK):
     """The SDK provided as parameters to a step"""
     ide: AbstractIdeProtocolServer
     steps: ContinueSDKSteps
@@ -92,15 +94,19 @@ class ContinueSDK:
         await self.ide.applyFileSystemEdit(file_edit)
 
     async def add_file(self, filename: str, content: str | None):
+        filepath = await self._ensure_absolute_path(filename)
         return await self.run_step(FileSystemEditStep(edit=AddFile(filename=filename, content=content)))
 
     async def delete_file(self, filename: str):
+        filepath = await self._ensure_absolute_path(filename)
         return await self.run_step(FileSystemEditStep(edit=DeleteFile(filepath=filename)))
 
     async def add_directory(self, path: str):
+        filepath = await self._ensure_absolute_path(path)
         return await self.run_step(FileSystemEditStep(edit=AddDirectory(path=path)))
 
     async def delete_directory(self, path: str):
+        filepath = await self._ensure_absolute_path(path)
         return await self.run_step(FileSystemEditStep(edit=DeleteDirectory(path=path)))
 
     async def get_user_secret(self, env_var: str, prompt: str) -> str:
@@ -108,8 +114,8 @@ class ContinueSDK:
 
     async def get_config(self) -> ContinueConfig:
         dir = await self.ide.getWorkspaceDirectory()
-        yaml_path = os.path.join(dir, 'continue.yaml')
-        json_path = os.path.join(dir, 'continue.json')
+        yaml_path = os.path.join(dir, '.continue', 'config.yaml')
+        json_path = os.path.join(dir, '.continue', 'config.json')
         if os.path.exists(yaml_path):
             return load_config(yaml_path)
         elif os.path.exists(json_path):
diff --git a/continuedev/src/continuedev/libs/util/telemetry.py b/continuedev/src/continuedev/libs/util/telemetry.py
index 4bff3970..d6345c25 100644
--- a/continuedev/src/continuedev/libs/util/telemetry.py
+++ b/continuedev/src/continuedev/libs/util/telemetry.py
@@ -7,6 +7,6 @@ posthog = Posthog('phc_JS6XFROuNbhJtVCEdTSYk6gl5ArRrTNMpCcguAXlSPs',
 
 
 def capture_event(event_name, event_properties):
-    config = load_config('~/.continue/continue.json')
+    config = load_config('.continue/config.json')
     if config.allow_anonymous_telemetry:
         posthog.capture("not distinct :(", event_name, event_properties)
diff --git a/continuedev/src/continuedev/steps/main.py b/continuedev/src/continuedev/steps/main.py
index dfb4f3be..da0fc8d2 100644
--- a/continuedev/src/continuedev/steps/main.py
+++ b/continuedev/src/continuedev/steps/main.py
@@ -1,3 +1,4 @@
+import os
 from typing import Coroutine, List, Union
 
 from pydantic import BaseModel
@@ -17,6 +18,20 @@ import subprocess
 from .core.core import EditCodeStep
 
 
+class SetupContinueWorkspaceStep(Step):
+    async def describe(self, models: Models) -> Coroutine[str, None, None]:
+        return "Set up Continue workspace by adding a .continue directory"
+
+    async def run(self, sdk: ContinueSDK) -> Coroutine[Observation, None, None]:
+        if not os.path.exists(os.path.join(await sdk.ide.getWorkspaceDirectory(), ".continue")):
+            await sdk.add_directory(".continue")
+            if not os.path.exists(os.path.join(await sdk.ide.getWorkspaceDirectory(), ".continue", "config.json")):
+                await sdk.add_file(".continue/config.json", dedent("""\
+                    {
+                        "allow_anonymous_telemetry": true
+                    }"""))
+
+
 class RunCodeStep(Step):
     cmd: str
 
-- 
cgit v1.2.3-70-g09d2