diff options
-rw-r--r-- | .gitignore | 2 | ||||
-rw-r--r-- | continuedev/src/continuedev/core/abstract_sdk.py | 85 | ||||
-rw-r--r-- | continuedev/src/continuedev/core/policy.py | 4 | ||||
-rw-r--r-- | continuedev/src/continuedev/core/sdk.py | 14 | ||||
-rw-r--r-- | continuedev/src/continuedev/libs/util/telemetry.py | 2 | ||||
-rw-r--r-- | continuedev/src/continuedev/steps/main.py | 15 | ||||
-rw-r--r-- | docs/docs/concepts/continue-json.md | 4 | ||||
-rw-r--r-- | docs/docs/concepts/policy.md | 2 | ||||
-rw-r--r-- | docs/docs/telemetry.md | 4 |
9 files changed, 120 insertions, 12 deletions
@@ -136,3 +136,5 @@ notes.txt cached_embeddings.pkl .ruff_cache codeql + +**/.continue
\ No newline at end of file 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 diff --git a/docs/docs/concepts/continue-json.md b/docs/docs/concepts/continue-json.md index 7227f660..f176bdff 100644 --- a/docs/docs/concepts/continue-json.md +++ b/docs/docs/concepts/continue-json.md @@ -1,3 +1,3 @@ -# continue.json
+# config.json
-**TODO: Need to explain this**
\ No newline at end of file +**TODO: Need to explain this**
diff --git a/docs/docs/concepts/policy.md b/docs/docs/concepts/policy.md index ea515673..3c40115d 100644 --- a/docs/docs/concepts/policy.md +++ b/docs/docs/concepts/policy.md @@ -8,7 +8,7 @@ A **policy** is decides what step to run next and is associated with a [autopilo ## Details
-A relic of my original plan that ended up being the place to define slash commands, the command run on startup, and other weird stuff that you might want to inject after certain other steps. This may be the place where "hooks" turn out to be implemented. Much of this may be configurable through `continue.json/yaml` config file (this is where steps that run on GUI opening are currently configured.). Simply takes the history and returns a single step to run next. Can return None if no step to take next. Then user input will kick it off again eventually. Autopilot has a single policy that it follows, so definitely a global/user-configurable type of thing.
+A relic of my original plan that ended up being the place to define slash commands, the command run on startup, and other weird stuff that you might want to inject after certain other steps. This may be the place where "hooks" turn out to be implemented. Much of this may be configurable through `.continue/config.json/yaml` config file (this is where steps that run on GUI opening are currently configured.). Simply takes the history and returns a single step to run next. Can return None if no step to take next. Then user input will kick it off again eventually. Autopilot has a single policy that it follows, so definitely a global/user-configurable type of thing.
- The Policy is where slash commands are defined
- The Policy is a global thing, so probably something we'll want to make user-configurable if we don't significantly change it
diff --git a/docs/docs/telemetry.md b/docs/docs/telemetry.md index 47f5a171..ca1fb641 100644 --- a/docs/docs/telemetry.md +++ b/docs/docs/telemetry.md @@ -14,10 +14,10 @@ We track the following... **TODO: Define where the root of your workspace**
-Create a `continue.json` file in the root of your workspace and add the following:
+Create a `.continue/config.json` file in the root of your workspace and add the following:
```json
{
"allow_anonymous_telemetry": false
}
-```
\ No newline at end of file +```
|