summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNate Sesti <33237525+sestinj@users.noreply.github.com>2023-09-16 22:08:01 -0700
committerGitHub <noreply@github.com>2023-09-16 22:08:01 -0700
commit7a86f6a41b16d94f676bf327d35fb768854becb4 (patch)
treed28d3fd8cc994452447ef19d23e5167ffc2c12c5
parentdfbae3f6add30b47d2bd0ba34be89af60d9ab660 (diff)
downloadsncontinue-7a86f6a41b16d94f676bf327d35fb768854becb4.tar.gz
sncontinue-7a86f6a41b16d94f676bf327d35fb768854becb4.tar.bz2
sncontinue-7a86f6a41b16d94f676bf327d35fb768854becb4.zip
Refactor helper (#481)
* feat: :sparkles: add stop_tokens option to LLM * work on refactoring in headless mode * feat: :sparkles: headless mode refactors * chore: :fire: remove test.py
-rw-r--r--continuedev/src/continuedev/__main__.py31
-rw-r--r--continuedev/src/continuedev/core/lsp.py137
-rw-r--r--continuedev/src/continuedev/headless/__init__.py19
-rw-r--r--continuedev/src/continuedev/libs/llm/__init__.py10
-rw-r--r--continuedev/src/continuedev/libs/llm/prompts/edit.py8
-rw-r--r--continuedev/src/continuedev/libs/util/strings.py13
-rw-r--r--continuedev/src/continuedev/models/filesystem.py3
-rw-r--r--continuedev/src/continuedev/models/main.py11
-rw-r--r--continuedev/src/continuedev/plugins/context_providers/file.py3
-rw-r--r--continuedev/src/continuedev/plugins/steps/refactor.py106
-rw-r--r--continuedev/src/continuedev/plugins/steps/steps_on_startup.py5
-rw-r--r--continuedev/src/continuedev/server/meilisearch_server.py19
-rw-r--r--docs/docs/reference/Models/anthropic.md1
-rw-r--r--docs/docs/reference/Models/ggml.md1
-rw-r--r--docs/docs/reference/Models/hf_inference_api.md1
-rw-r--r--docs/docs/reference/Models/hf_tgi.md1
-rw-r--r--docs/docs/reference/Models/llamacpp.md1
-rw-r--r--docs/docs/reference/Models/maybe_proxy_openai.md1
-rw-r--r--docs/docs/reference/Models/ollama.md1
-rw-r--r--docs/docs/reference/Models/openai.md1
-rw-r--r--docs/docs/reference/Models/queued.md1
-rw-r--r--docs/docs/reference/Models/replicate.md1
-rw-r--r--docs/docs/reference/Models/text_gen_interface.md1
-rw-r--r--docs/docs/reference/Models/together.md1
-rw-r--r--docs/docs/reference/config.md2
-rw-r--r--docs/docs/walkthroughs/headless-mode.md37
26 files changed, 339 insertions, 77 deletions
diff --git a/continuedev/src/continuedev/__main__.py b/continuedev/src/continuedev/__main__.py
index 6dd03046..efd62d64 100644
--- a/continuedev/src/continuedev/__main__.py
+++ b/continuedev/src/continuedev/__main__.py
@@ -1,16 +1,31 @@
-import argparse
+import asyncio
+from typing import Optional
+import typer
+
+from .headless import start_headless_session
from .server.main import run_server
+app = typer.Typer()
-def main():
- parser = argparse.ArgumentParser()
- parser.add_argument("-p", "--port", help="server port", type=int, default=65432)
- parser.add_argument("--host", help="server host", type=str, default="127.0.0.1")
- args = parser.parse_args()
- run_server(port=args.port, host=args.host)
+@app.command()
+def main(
+ port: int = typer.Option(65432, help="server port"),
+ host: str = typer.Option("127.0.0.1", help="server host"),
+ config: Optional[str] = typer.Option(
+ None, help="The path to the configuration file"
+ ),
+ headless: bool = typer.Option(False, help="Run in headless mode"),
+):
+ if headless:
+ loop = asyncio.get_event_loop()
+ loop.run_until_complete(start_headless_session(config=config))
+ tasks = asyncio.all_tasks(loop)
+ loop.run_until_complete(asyncio.gather(*tasks))
+ else:
+ run_server(port=port, host=host)
if __name__ == "__main__":
- main()
+ app()
diff --git a/continuedev/src/continuedev/core/lsp.py b/continuedev/src/continuedev/core/lsp.py
index 181eea2e..0c906b22 100644
--- a/continuedev/src/continuedev/core/lsp.py
+++ b/continuedev/src/continuedev/core/lsp.py
@@ -1,6 +1,6 @@
import asyncio
import threading
-from typing import List, Optional
+from typing import List, Literal, Optional
import aiohttp
from pydantic import BaseModel
@@ -9,6 +9,7 @@ from pylsp.python_lsp import PythonLSPServer, start_ws_lang_server
from ..libs.util.logging import logger
from ..models.filesystem import RangeInFile
from ..models.main import Position, Range
+from ..server.meilisearch_server import kill_proc
def filepath_to_uri(filename: str) -> str:
@@ -17,7 +18,7 @@ def filepath_to_uri(filename: str) -> str:
def uri_to_filepath(uri: str) -> str:
if uri.startswith("file://"):
- return uri.lstrip("file://")
+ return uri[7:]
else:
return uri
@@ -26,6 +27,9 @@ PORT = 8099
class LSPClient:
+ ready: bool = False
+ lock: asyncio.Lock = asyncio.Lock()
+
def __init__(self, host: str, port: int, workspace_paths: List[str]):
self.host = host
self.port = port
@@ -37,12 +41,18 @@ class LSPClient:
print("Connecting")
self.ws = await self.session.ws_connect(f"ws://{self.host}:{self.port}/")
print("Connected")
+ self.ready = True
async def send(self, data):
await self.ws.send_json(data)
async def recv(self):
- return await self.ws.receive_json()
+ await self.lock.acquire()
+
+ try:
+ return await self.ws.receive_json()
+ finally:
+ self.lock.release()
async def close(self):
await self.ws.close()
@@ -237,9 +247,27 @@ class LSPClient:
textDocument={"uri": filepath_to_uri(filepath)},
)
+ async def find_references(
+ self, filepath: str, position: Position, include_declaration: bool = False
+ ):
+ return await self.call_method(
+ "textDocument/references",
+ textDocument={"uri": filepath_to_uri(filepath)},
+ position=position.dict(),
+ context={"includeDeclaration": include_declaration},
+ )
+
+ async def folding_range(self, filepath: str):
+ response = await self.call_method(
+ "textDocument/foldingRange",
+ textDocument={"uri": filepath_to_uri(filepath)},
+ )
+ return response["result"]
+
async def start_language_server() -> threading.Thread:
try:
+ kill_proc(PORT)
thread = threading.Thread(
target=start_ws_lang_server,
args=(PORT, False, PythonLSPServer),
@@ -262,12 +290,23 @@ class DocumentSymbol(BaseModel):
location: RangeInFile
+class FoldingRange(BaseModel):
+ range: Range
+ kind: Optional[Literal["comment", "imports", "region"]] = None
+
+
class ContinueLSPClient(BaseModel):
workspace_dir: str
lsp_client: LSPClient = None
lsp_thread: Optional[threading.Thread] = None
+ @property
+ def ready(self):
+ if self.lsp_client is None:
+ return False
+ return self.lsp_client.ready
+
class Config:
arbitrary_types_allowed = True
@@ -287,6 +326,17 @@ class ContinueLSPClient(BaseModel):
if self.lsp_thread:
self.lsp_thread.join()
+ def location_to_range_in_file(self, location):
+ return RangeInFile(
+ filepath=uri_to_filepath(location["uri"]),
+ range=Range.from_shorthand(
+ location["range"]["start"]["line"],
+ location["range"]["start"]["character"],
+ location["range"]["end"]["line"],
+ location["range"]["end"]["character"],
+ ),
+ )
+
async def goto_definition(
self, position: Position, filename: str
) -> List[RangeInFile]:
@@ -294,18 +344,17 @@ class ContinueLSPClient(BaseModel):
filename,
position,
)
- return [
- RangeInFile(
- filepath=uri_to_filepath(x.uri),
- range=Range.from_shorthand(
- x.range.start.line,
- x.range.start.character,
- x.range.end.line,
- x.range.end.character,
- ),
- )
- for x in response
- ]
+ return [self.location_to_range_in_file(x) for x in response]
+
+ async def find_references(
+ self, position: Position, filename: str, include_declaration: bool = False
+ ) -> List[RangeInFile]:
+ response = await self.lsp_client.find_references(
+ filename,
+ position,
+ include_declaration=include_declaration,
+ )
+ return [self.location_to_range_in_file(x) for x in response["result"]]
async def document_symbol(self, filepath: str) -> List:
response = await self.lsp_client.document_symbol(filepath)
@@ -314,15 +363,55 @@ class ContinueLSPClient(BaseModel):
name=x["name"],
containerName=x["containerName"],
kind=x["kind"],
- location=RangeInFile(
- filepath=uri_to_filepath(x["location"]["uri"]),
- range=Range.from_shorthand(
- x["location"]["range"]["start"]["line"],
- x["location"]["range"]["start"]["character"],
- x["location"]["range"]["end"]["line"],
- x["location"]["range"]["end"]["character"],
- ),
- ),
+ location=self.location_to_range_in_file(x["location"]),
)
for x in response["result"]
]
+
+ async def folding_range(self, filepath: str) -> List[FoldingRange]:
+ response = await self.lsp_client.folding_range(filepath)
+
+ return [
+ FoldingRange(
+ range=Range.from_shorthand(
+ x["startLine"],
+ x.get("startCharacter", 0),
+ x["endLine"] if "endCharacter" in x else x["endLine"] + 1,
+ x.get("endCharacter", 0),
+ ),
+ kind=x.get("kind"),
+ )
+ for x in response
+ ]
+
+ async def get_enclosing_folding_range_of_position(
+ self, position: Position, filepath: str
+ ) -> Optional[FoldingRange]:
+ ranges = await self.folding_range(filepath)
+
+ max_start_position = Position(line=0, character=0)
+ max_range = None
+ for r in ranges:
+ if r.range.contains(position):
+ if r.range.start > max_start_position:
+ max_start_position = r.range.start
+ max_range = r
+
+ return max_range
+
+ async def get_enclosing_folding_range(
+ self, range_in_file: RangeInFile
+ ) -> Optional[FoldingRange]:
+ ranges = await self.folding_range(range_in_file.filepath)
+
+ max_start_position = Position(line=0, character=0)
+ max_range = None
+ for r in ranges:
+ if r.range.contains(range_in_file.range.start) and r.range.contains(
+ range_in_file.range.end
+ ):
+ if r.range.start > max_start_position:
+ max_start_position = r.range.start
+ max_range = r
+
+ return max_range
diff --git a/continuedev/src/continuedev/headless/__init__.py b/continuedev/src/continuedev/headless/__init__.py
index 4e46409a..27722ee7 100644
--- a/continuedev/src/continuedev/headless/__init__.py
+++ b/continuedev/src/continuedev/headless/__init__.py
@@ -4,6 +4,7 @@ from typing import Optional, Union
import typer
from ..core.config import ContinueConfig
+from ..core.main import Step
from ..server.session_manager import Session, session_manager
from .headless_ide import LocalIdeProtocol
@@ -21,21 +22,11 @@ async def start_headless_session(
return await session_manager.new_session(ide, config=config)
-async def async_main(config: Optional[str] = None):
- await start_headless_session(config=config)
+def run_step_headless(step: Step):
+ config = ContinueConfig()
+ config.steps_on_startup = [step]
-
-@app.command()
-def main(
- config: Optional[str] = typer.Option(
- None, help="The path to the configuration file"
- )
-):
loop = asyncio.get_event_loop()
- loop.run_until_complete(async_main(config))
+ loop.run_until_complete(start_headless_session(config=config))
tasks = asyncio.all_tasks(loop)
loop.run_until_complete(asyncio.gather(*tasks))
-
-
-if __name__ == "__main__":
- app()
diff --git a/continuedev/src/continuedev/libs/llm/__init__.py b/continuedev/src/continuedev/libs/llm/__init__.py
index baeb9d1a..b2eecab6 100644
--- a/continuedev/src/continuedev/libs/llm/__init__.py
+++ b/continuedev/src/continuedev/libs/llm/__init__.py
@@ -68,6 +68,10 @@ class LLM(ContinueBaseModel):
..., description="The name of the model to be used (e.g. gpt-4, codellama)"
)
+ stop_tokens: Optional[List[str]] = Field(
+ None, description="Tokens that will stop the completion."
+ )
+
timeout: Optional[int] = Field(
300,
description="Set the timeout for each request to the LLM. If you are running a local LLM that takes a while to respond, you might want to set this to avoid timeouts.",
@@ -204,7 +208,7 @@ class LLM(ContinueBaseModel):
top_k=top_k,
presence_penalty=presence_penalty,
frequency_penalty=frequency_penalty,
- stop=stop,
+ stop=stop or self.stop_tokens,
max_tokens=max_tokens,
functions=functions,
)
@@ -251,7 +255,7 @@ class LLM(ContinueBaseModel):
top_k=top_k,
presence_penalty=presence_penalty,
frequency_penalty=frequency_penalty,
- stop=stop,
+ stop=stop or self.stop_tokens,
max_tokens=max_tokens,
functions=functions,
)
@@ -296,7 +300,7 @@ class LLM(ContinueBaseModel):
top_k=top_k,
presence_penalty=presence_penalty,
frequency_penalty=frequency_penalty,
- stop=stop,
+ stop=stop or self.stop_tokens,
max_tokens=max_tokens,
functions=functions,
)
diff --git a/continuedev/src/continuedev/libs/llm/prompts/edit.py b/continuedev/src/continuedev/libs/llm/prompts/edit.py
index 7da5a192..eaa694c5 100644
--- a/continuedev/src/continuedev/libs/llm/prompts/edit.py
+++ b/continuedev/src/continuedev/libs/llm/prompts/edit.py
@@ -4,10 +4,10 @@ simplified_edit_prompt = dedent(
"""\
Consider the following code:
```
- {{code_to_edit}}
+ {{{code_to_edit}}}
```
Edit the code to perfectly satisfy the following user request:
- {{user_input}}
+ {{{user_input}}}
Output nothing except for the code. No code block, no English explanation, no start/end tags."""
)
@@ -15,11 +15,11 @@ simplest_edit_prompt = dedent(
"""\
Here is the code before editing:
```
- {{code_to_edit}}
+ {{{code_to_edit}}}
```
Here is the edit requested:
- "{{user_input}}"
+ "{{{user_input}}}"
Here is the code after editing:"""
)
diff --git a/continuedev/src/continuedev/libs/util/strings.py b/continuedev/src/continuedev/libs/util/strings.py
index d33c46c4..f2b6035f 100644
--- a/continuedev/src/continuedev/libs/util/strings.py
+++ b/continuedev/src/continuedev/libs/util/strings.py
@@ -25,6 +25,19 @@ def dedent_and_get_common_whitespace(s: str) -> Tuple[str, str]:
return "\n".join(map(lambda x: x.lstrip(lcp), lines)), lcp
+def strip_code_block(s: str) -> str:
+ """
+ Strips the code block from a string, if it has one.
+ """
+ if s.startswith("```\n") and s.endswith("\n```"):
+ return s[4:-4]
+ elif s.startswith("```") and s.endswith("```"):
+ return s[3:-3]
+ elif s.startswith("`") and s.endswith("`"):
+ return s[1:-1]
+ return s
+
+
def remove_quotes_and_escapes(output: str) -> str:
"""
Clean up the output of the completion API, removing unnecessary escapes and quotes
diff --git a/continuedev/src/continuedev/models/filesystem.py b/continuedev/src/continuedev/models/filesystem.py
index 3b056a2f..27244c4b 100644
--- a/continuedev/src/continuedev/models/filesystem.py
+++ b/continuedev/src/continuedev/models/filesystem.py
@@ -31,6 +31,9 @@ class RangeInFile(BaseModel):
range = Range.from_entire_file(content)
return RangeInFile(filepath=filepath, range=range)
+ def translated(self, lines: int):
+ return RangeInFile(filepath=self.filepath, range=self.range.translated(lines))
+
class RangeInFileWithContents(RangeInFile):
"""A range in a file with the contents of the range."""
diff --git a/continuedev/src/continuedev/models/main.py b/continuedev/src/continuedev/models/main.py
index 880fbfef..34c557e0 100644
--- a/continuedev/src/continuedev/models/main.py
+++ b/continuedev/src/continuedev/models/main.py
@@ -105,6 +105,17 @@ class Range(BaseModel):
end=Position(line=self.end.line + 1, character=0),
)
+ def translated(self, lines: int):
+ return Range(
+ start=Position(
+ line=self.start.line + lines, character=self.start.character
+ ),
+ end=Position(line=self.end.line + lines, character=self.end.character),
+ )
+
+ def contains(self, position: Position) -> bool:
+ return self.start <= position and position <= self.end
+
@staticmethod
def from_indices(string: str, start_index: int, end_index: int) -> "Range":
return Range(
diff --git a/continuedev/src/continuedev/plugins/context_providers/file.py b/continuedev/src/continuedev/plugins/context_providers/file.py
index c4a61193..f4fbaf03 100644
--- a/continuedev/src/continuedev/plugins/context_providers/file.py
+++ b/continuedev/src/continuedev/plugins/context_providers/file.py
@@ -14,8 +14,7 @@ MAX_SIZE_IN_CHARS = 50_000
async def get_file_contents(filepath: str, sdk: ContinueSDK) -> str:
try:
return (await sdk.ide.readFile(filepath))[:MAX_SIZE_IN_CHARS]
- except Exception as e:
- print(f"Failed to read file: {e}")
+ except Exception as _:
return None
diff --git a/continuedev/src/continuedev/plugins/steps/refactor.py b/continuedev/src/continuedev/plugins/steps/refactor.py
new file mode 100644
index 00000000..cfbce662
--- /dev/null
+++ b/continuedev/src/continuedev/plugins/steps/refactor.py
@@ -0,0 +1,106 @@
+import asyncio
+from typing import List
+
+from ...core.main import Step
+from ...core.models import Models
+from ...core.sdk import ContinueSDK
+from ...libs.llm.prompts.edit import simplified_edit_prompt
+from ...libs.util.strings import remove_quotes_and_escapes, strip_code_block
+from ...libs.util.templating import render_prompt_template
+from ...models.filesystem import RangeInFile
+from ...models.filesystem_edit import FileEdit
+from ...models.main import PositionInFile, Range
+
+
+class RefactorReferencesStep(Step):
+ name: str = "Refactor references of a symbol"
+ user_input: str
+ symbol_location: PositionInFile
+
+ async def describe(self, models: Models):
+ return f"Renamed all instances of `{self.function_name}` to `{self.new_function_name}` in `{self.filepath}`"
+
+ async def run(self, sdk: ContinueSDK):
+ while sdk.lsp is None or not sdk.lsp.ready:
+ await asyncio.sleep(0.1)
+
+ references = await sdk.lsp.find_references(
+ self.symbol_location.position, self.symbol_location.filepath, False
+ )
+ await sdk.run_step(
+ ParallelEditStep(user_input=self.user_input, range_in_files=references)
+ )
+
+
+class ParallelEditStep(Step):
+ name: str = "Edit multiple ranges in parallel"
+ user_input: str
+ range_in_files: List[RangeInFile]
+
+ hide: bool = True
+
+ async def single_edit(self, sdk: ContinueSDK, range_in_file: RangeInFile):
+ # TODO: Can use folding info to get a more intuitively shaped range
+ expanded_range = await sdk.lsp.get_enclosing_folding_range(range_in_file)
+ if (
+ expanded_range is None
+ or expanded_range.range.start.line != range_in_file.range.start.line
+ ):
+ expanded_range = Range.from_shorthand(
+ range_in_file.range.start.line, 0, range_in_file.range.end.line + 1, 0
+ )
+ else:
+ expanded_range = expanded_range.range
+
+ new_rif = RangeInFile(
+ filepath=range_in_file.filepath,
+ range=expanded_range,
+ )
+ code_to_edit = await sdk.ide.readRangeInFile(range_in_file=new_rif)
+
+ # code_to_edit, common_whitespace = dedent_and_get_common_whitespace(code_to_edit)
+
+ prompt = render_prompt_template(
+ simplified_edit_prompt,
+ history=[],
+ other_data={
+ "code_to_edit": code_to_edit,
+ "user_input": self.user_input,
+ },
+ )
+ print(prompt + "\n\n-------------------\n\n")
+
+ new_code = await sdk.models.edit.complete(prompt=prompt)
+ new_code = strip_code_block(remove_quotes_and_escapes(new_code)) + "\n"
+ # new_code = (
+ # "\n".join([common_whitespace + line for line in new_code.split("\n")])
+ # + "\n"
+ # )
+
+ print(new_code + "\n\n-------------------\n\n")
+
+ await sdk.ide.applyFileSystemEdit(
+ FileEdit(
+ filepath=range_in_file.filepath,
+ range=expanded_range,
+ replacement=new_code,
+ )
+ )
+
+ async def edit_file(self, sdk: ContinueSDK, filepath: str):
+ ranges_in_file = [
+ range_in_file
+ for range_in_file in self.range_in_files
+ if range_in_file.filepath == filepath
+ ]
+ # Sort in reverse order so that we don't mess up the ranges
+ ranges_in_file.sort(key=lambda x: x.range.start.line, reverse=True)
+ for i in range(len(ranges_in_file)):
+ await self.single_edit(sdk=sdk, range_in_file=ranges_in_file[i])
+
+ async def run(self, sdk: ContinueSDK):
+ tasks = []
+ for filepath in set([rif.filepath for rif in self.range_in_files]):
+ tasks.append(self.edit_file(sdk=sdk, filepath=filepath))
+
+ await asyncio.gather(*tasks)
diff --git a/continuedev/src/continuedev/plugins/steps/steps_on_startup.py b/continuedev/src/continuedev/plugins/steps/steps_on_startup.py
index d0058ffc..58d56703 100644
--- a/continuedev/src/continuedev/plugins/steps/steps_on_startup.py
+++ b/continuedev/src/continuedev/plugins/steps/steps_on_startup.py
@@ -12,5 +12,8 @@ class StepsOnStartupStep(Step):
steps_on_startup = sdk.config.steps_on_startup
for step_type in steps_on_startup:
- step = step_type()
+ if isinstance(step_type, Step):
+ step = step_type
+ else:
+ step = step_type()
await sdk.run_step(step)
diff --git a/continuedev/src/continuedev/server/meilisearch_server.py b/continuedev/src/continuedev/server/meilisearch_server.py
index f3734470..40d46b18 100644
--- a/continuedev/src/continuedev/server/meilisearch_server.py
+++ b/continuedev/src/continuedev/server/meilisearch_server.py
@@ -77,14 +77,13 @@ async def ensure_meilisearch_installed() -> bool:
except:
pass
existing_paths.remove(meilisearchPath)
-
+
await download_meilisearch()
# Clear the existing directories
for p in existing_paths:
shutil.rmtree(p, ignore_errors=True)
-
return False
return True
@@ -160,17 +159,25 @@ def stop_meilisearch():
import psutil
+
def kill_proc(port):
for proc in psutil.process_iter():
try:
- for conns in proc.connections(kind='inet'):
+ for conns in proc.connections(kind="inet"):
if conns.laddr.port == port:
- proc.send_signal(psutil.signal.SIGTERM) # or SIGKILL
+ proc.send_signal(psutil.signal.SIGTERM) # or SIGKILL
except psutil.AccessDenied:
- logger.warning(f"Failed to kill process on port {port}")
+ logger.warning(f"Failed to kill process on port {port} (access denied)")
+ return
+ except psutil.ZombieProcess:
+ logger.warning(f"Failed to kill process on port {port} (zombie process)")
+ return
+ except psutil.NoSuchProcess:
+ logger.warning(f"Failed to kill process on port {port} (no such process)")
+ return
async def restart_meilisearch():
stop_meilisearch()
kill_proc(7700)
- await start_meilisearch() \ No newline at end of file
+ await start_meilisearch()
diff --git a/docs/docs/reference/Models/anthropic.md b/docs/docs/reference/Models/anthropic.md
index 3f405d39..e2c6f683 100644
--- a/docs/docs/reference/Models/anthropic.md
+++ b/docs/docs/reference/Models/anthropic.md
@@ -31,6 +31,7 @@ Claude 2 is not yet publicly released. You can request early access [here](https
<ClassPropertyRef name='context_length' details='{&quot;title&quot;: &quot;Context Length&quot;, &quot;description&quot;: &quot;The maximum context length of the LLM in tokens, as counted by count_tokens.&quot;, &quot;default&quot;: 2048, &quot;type&quot;: &quot;integer&quot;}' required={false} default="2048"/>
<ClassPropertyRef name='unique_id' details='{&quot;title&quot;: &quot;Unique Id&quot;, &quot;description&quot;: &quot;The unique ID of the user.&quot;, &quot;type&quot;: &quot;string&quot;}' required={false} default=""/>
<ClassPropertyRef name='model' details='{&quot;title&quot;: &quot;Model&quot;, &quot;description&quot;: &quot;The name of the model to be used (e.g. gpt-4, codellama)&quot;, &quot;default&quot;: &quot;claude-2&quot;, &quot;type&quot;: &quot;string&quot;}' required={false} default="claude-2"/>
+<ClassPropertyRef name='stop_tokens' details='{&quot;title&quot;: &quot;Stop Tokens&quot;, &quot;description&quot;: &quot;Tokens that will stop the completion.&quot;, &quot;type&quot;: &quot;array&quot;, &quot;items&quot;: {&quot;type&quot;: &quot;string&quot;}}' required={false} default=""/>
<ClassPropertyRef name='timeout' details='{&quot;title&quot;: &quot;Timeout&quot;, &quot;description&quot;: &quot;Set the timeout for each request to the LLM. If you are running a local LLM that takes a while to respond, you might want to set this to avoid timeouts.&quot;, &quot;default&quot;: 300, &quot;type&quot;: &quot;integer&quot;}' required={false} default="300"/>
<ClassPropertyRef name='verify_ssl' details='{&quot;title&quot;: &quot;Verify Ssl&quot;, &quot;description&quot;: &quot;Whether to verify SSL certificates for requests.&quot;, &quot;type&quot;: &quot;boolean&quot;}' required={false} default=""/>
<ClassPropertyRef name='ca_bundle_path' details='{&quot;title&quot;: &quot;Ca Bundle Path&quot;, &quot;description&quot;: &quot;Path to a custom CA bundle to use when making the HTTP request&quot;, &quot;type&quot;: &quot;string&quot;}' required={false} default=""/>
diff --git a/docs/docs/reference/Models/ggml.md b/docs/docs/reference/Models/ggml.md
index 3369df6f..d02f6d05 100644
--- a/docs/docs/reference/Models/ggml.md
+++ b/docs/docs/reference/Models/ggml.md
@@ -34,6 +34,7 @@ config = ContinueConfig(
<ClassPropertyRef name='context_length' details='{&quot;title&quot;: &quot;Context Length&quot;, &quot;description&quot;: &quot;The maximum context length of the LLM in tokens, as counted by count_tokens.&quot;, &quot;default&quot;: 2048, &quot;type&quot;: &quot;integer&quot;}' required={false} default="2048"/>
<ClassPropertyRef name='unique_id' details='{&quot;title&quot;: &quot;Unique Id&quot;, &quot;description&quot;: &quot;The unique ID of the user.&quot;, &quot;type&quot;: &quot;string&quot;}' required={false} default=""/>
<ClassPropertyRef name='model' details='{&quot;title&quot;: &quot;Model&quot;, &quot;description&quot;: &quot;The name of the model to use (optional for the GGML class)&quot;, &quot;default&quot;: &quot;ggml&quot;, &quot;type&quot;: &quot;string&quot;}' required={false} default="ggml"/>
+<ClassPropertyRef name='stop_tokens' details='{&quot;title&quot;: &quot;Stop Tokens&quot;, &quot;description&quot;: &quot;Tokens that will stop the completion.&quot;, &quot;type&quot;: &quot;array&quot;, &quot;items&quot;: {&quot;type&quot;: &quot;string&quot;}}' required={false} default=""/>
<ClassPropertyRef name='timeout' details='{&quot;title&quot;: &quot;Timeout&quot;, &quot;description&quot;: &quot;Set the timeout for each request to the LLM. If you are running a local LLM that takes a while to respond, you might want to set this to avoid timeouts.&quot;, &quot;default&quot;: 300, &quot;type&quot;: &quot;integer&quot;}' required={false} default="300"/>
<ClassPropertyRef name='verify_ssl' details='{&quot;title&quot;: &quot;Verify Ssl&quot;, &quot;description&quot;: &quot;Whether to verify SSL certificates for requests.&quot;, &quot;type&quot;: &quot;boolean&quot;}' required={false} default=""/>
<ClassPropertyRef name='ca_bundle_path' details='{&quot;title&quot;: &quot;Ca Bundle Path&quot;, &quot;description&quot;: &quot;Path to a custom CA bundle to use when making the HTTP request&quot;, &quot;type&quot;: &quot;string&quot;}' required={false} default=""/>
diff --git a/docs/docs/reference/Models/hf_inference_api.md b/docs/docs/reference/Models/hf_inference_api.md
index 6e5aeeca..e7857b21 100644
--- a/docs/docs/reference/Models/hf_inference_api.md
+++ b/docs/docs/reference/Models/hf_inference_api.md
@@ -33,6 +33,7 @@ config = ContinueConfig(
<ClassPropertyRef name='context_length' details='{&quot;title&quot;: &quot;Context Length&quot;, &quot;description&quot;: &quot;The maximum context length of the LLM in tokens, as counted by count_tokens.&quot;, &quot;default&quot;: 2048, &quot;type&quot;: &quot;integer&quot;}' required={false} default="2048"/>
<ClassPropertyRef name='unique_id' details='{&quot;title&quot;: &quot;Unique Id&quot;, &quot;description&quot;: &quot;The unique ID of the user.&quot;, &quot;type&quot;: &quot;string&quot;}' required={false} default=""/>
<ClassPropertyRef name='model' details='{&quot;title&quot;: &quot;Model&quot;, &quot;description&quot;: &quot;The name of the model to use (optional for the HuggingFaceInferenceAPI class)&quot;, &quot;default&quot;: &quot;Hugging Face Inference API&quot;, &quot;type&quot;: &quot;string&quot;}' required={false} default="Hugging Face Inference API"/>
+<ClassPropertyRef name='stop_tokens' details='{&quot;title&quot;: &quot;Stop Tokens&quot;, &quot;description&quot;: &quot;Tokens that will stop the completion.&quot;, &quot;type&quot;: &quot;array&quot;, &quot;items&quot;: {&quot;type&quot;: &quot;string&quot;}}' required={false} default=""/>
<ClassPropertyRef name='timeout' details='{&quot;title&quot;: &quot;Timeout&quot;, &quot;description&quot;: &quot;Set the timeout for each request to the LLM. If you are running a local LLM that takes a while to respond, you might want to set this to avoid timeouts.&quot;, &quot;default&quot;: 300, &quot;type&quot;: &quot;integer&quot;}' required={false} default="300"/>
<ClassPropertyRef name='verify_ssl' details='{&quot;title&quot;: &quot;Verify Ssl&quot;, &quot;description&quot;: &quot;Whether to verify SSL certificates for requests.&quot;, &quot;type&quot;: &quot;boolean&quot;}' required={false} default=""/>
<ClassPropertyRef name='ca_bundle_path' details='{&quot;title&quot;: &quot;Ca Bundle Path&quot;, &quot;description&quot;: &quot;Path to a custom CA bundle to use when making the HTTP request&quot;, &quot;type&quot;: &quot;string&quot;}' required={false} default=""/>
diff --git a/docs/docs/reference/Models/hf_tgi.md b/docs/docs/reference/Models/hf_tgi.md
index 3ea28730..ab3f4d61 100644
--- a/docs/docs/reference/Models/hf_tgi.md
+++ b/docs/docs/reference/Models/hf_tgi.md
@@ -18,6 +18,7 @@ import ClassPropertyRef from '@site/src/components/ClassPropertyRef.tsx';
<ClassPropertyRef name='context_length' details='{&quot;title&quot;: &quot;Context Length&quot;, &quot;description&quot;: &quot;The maximum context length of the LLM in tokens, as counted by count_tokens.&quot;, &quot;default&quot;: 2048, &quot;type&quot;: &quot;integer&quot;}' required={false} default="2048"/>
<ClassPropertyRef name='unique_id' details='{&quot;title&quot;: &quot;Unique Id&quot;, &quot;description&quot;: &quot;The unique ID of the user.&quot;, &quot;type&quot;: &quot;string&quot;}' required={false} default=""/>
<ClassPropertyRef name='model' details='{&quot;title&quot;: &quot;Model&quot;, &quot;description&quot;: &quot;The name of the model to be used (e.g. gpt-4, codellama)&quot;, &quot;default&quot;: &quot;huggingface-tgi&quot;, &quot;type&quot;: &quot;string&quot;}' required={false} default="huggingface-tgi"/>
+<ClassPropertyRef name='stop_tokens' details='{&quot;title&quot;: &quot;Stop Tokens&quot;, &quot;description&quot;: &quot;Tokens that will stop the completion.&quot;, &quot;type&quot;: &quot;array&quot;, &quot;items&quot;: {&quot;type&quot;: &quot;string&quot;}}' required={false} default=""/>
<ClassPropertyRef name='timeout' details='{&quot;title&quot;: &quot;Timeout&quot;, &quot;description&quot;: &quot;Set the timeout for each request to the LLM. If you are running a local LLM that takes a while to respond, you might want to set this to avoid timeouts.&quot;, &quot;default&quot;: 300, &quot;type&quot;: &quot;integer&quot;}' required={false} default="300"/>
<ClassPropertyRef name='verify_ssl' details='{&quot;title&quot;: &quot;Verify Ssl&quot;, &quot;description&quot;: &quot;Whether to verify SSL certificates for requests.&quot;, &quot;type&quot;: &quot;boolean&quot;}' required={false} default=""/>
<ClassPropertyRef name='ca_bundle_path' details='{&quot;title&quot;: &quot;Ca Bundle Path&quot;, &quot;description&quot;: &quot;Path to a custom CA bundle to use when making the HTTP request&quot;, &quot;type&quot;: &quot;string&quot;}' required={false} default=""/>
diff --git a/docs/docs/reference/Models/llamacpp.md b/docs/docs/reference/Models/llamacpp.md
index c1c5e4f9..ae4b6e62 100644
--- a/docs/docs/reference/Models/llamacpp.md
+++ b/docs/docs/reference/Models/llamacpp.md
@@ -38,6 +38,7 @@ config = ContinueConfig(
<ClassPropertyRef name='context_length' details='{&quot;title&quot;: &quot;Context Length&quot;, &quot;description&quot;: &quot;The maximum context length of the LLM in tokens, as counted by count_tokens.&quot;, &quot;default&quot;: 2048, &quot;type&quot;: &quot;integer&quot;}' required={false} default="2048"/>
<ClassPropertyRef name='unique_id' details='{&quot;title&quot;: &quot;Unique Id&quot;, &quot;description&quot;: &quot;The unique ID of the user.&quot;, &quot;type&quot;: &quot;string&quot;}' required={false} default=""/>
<ClassPropertyRef name='model' details='{&quot;title&quot;: &quot;Model&quot;, &quot;description&quot;: &quot;The name of the model to be used (e.g. gpt-4, codellama)&quot;, &quot;default&quot;: &quot;llamacpp&quot;, &quot;type&quot;: &quot;string&quot;}' required={false} default="llamacpp"/>
+<ClassPropertyRef name='stop_tokens' details='{&quot;title&quot;: &quot;Stop Tokens&quot;, &quot;description&quot;: &quot;Tokens that will stop the completion.&quot;, &quot;type&quot;: &quot;array&quot;, &quot;items&quot;: {&quot;type&quot;: &quot;string&quot;}}' required={false} default=""/>
<ClassPropertyRef name='timeout' details='{&quot;title&quot;: &quot;Timeout&quot;, &quot;description&quot;: &quot;Set the timeout for each request to the LLM. If you are running a local LLM that takes a while to respond, you might want to set this to avoid timeouts.&quot;, &quot;default&quot;: 300, &quot;type&quot;: &quot;integer&quot;}' required={false} default="300"/>
<ClassPropertyRef name='verify_ssl' details='{&quot;title&quot;: &quot;Verify Ssl&quot;, &quot;description&quot;: &quot;Whether to verify SSL certificates for requests.&quot;, &quot;type&quot;: &quot;boolean&quot;}' required={false} default=""/>
<ClassPropertyRef name='ca_bundle_path' details='{&quot;title&quot;: &quot;Ca Bundle Path&quot;, &quot;description&quot;: &quot;Path to a custom CA bundle to use when making the HTTP request&quot;, &quot;type&quot;: &quot;string&quot;}' required={false} default=""/>
diff --git a/docs/docs/reference/Models/maybe_proxy_openai.md b/docs/docs/reference/Models/maybe_proxy_openai.md
index 651cbdba..c080b54d 100644
--- a/docs/docs/reference/Models/maybe_proxy_openai.md
+++ b/docs/docs/reference/Models/maybe_proxy_openai.md
@@ -39,6 +39,7 @@ These classes support any models available through the OpenAI API, assuming your
<ClassPropertyRef name='system_message' details='{&quot;title&quot;: &quot;System Message&quot;, &quot;description&quot;: &quot;A system message that will always be followed by the LLM&quot;, &quot;type&quot;: &quot;string&quot;}' required={false} default=""/>
<ClassPropertyRef name='context_length' details='{&quot;title&quot;: &quot;Context Length&quot;, &quot;description&quot;: &quot;The maximum context length of the LLM in tokens, as counted by count_tokens.&quot;, &quot;default&quot;: 2048, &quot;type&quot;: &quot;integer&quot;}' required={false} default="2048"/>
<ClassPropertyRef name='unique_id' details='{&quot;title&quot;: &quot;Unique Id&quot;, &quot;description&quot;: &quot;The unique ID of the user.&quot;, &quot;type&quot;: &quot;string&quot;}' required={false} default=""/>
+<ClassPropertyRef name='stop_tokens' details='{&quot;title&quot;: &quot;Stop Tokens&quot;, &quot;description&quot;: &quot;Tokens that will stop the completion.&quot;, &quot;type&quot;: &quot;array&quot;, &quot;items&quot;: {&quot;type&quot;: &quot;string&quot;}}' required={false} default=""/>
<ClassPropertyRef name='timeout' details='{&quot;title&quot;: &quot;Timeout&quot;, &quot;description&quot;: &quot;Set the timeout for each request to the LLM. If you are running a local LLM that takes a while to respond, you might want to set this to avoid timeouts.&quot;, &quot;default&quot;: 300, &quot;type&quot;: &quot;integer&quot;}' required={false} default="300"/>
<ClassPropertyRef name='verify_ssl' details='{&quot;title&quot;: &quot;Verify Ssl&quot;, &quot;description&quot;: &quot;Whether to verify SSL certificates for requests.&quot;, &quot;type&quot;: &quot;boolean&quot;}' required={false} default=""/>
<ClassPropertyRef name='ca_bundle_path' details='{&quot;title&quot;: &quot;Ca Bundle Path&quot;, &quot;description&quot;: &quot;Path to a custom CA bundle to use when making the HTTP request&quot;, &quot;type&quot;: &quot;string&quot;}' required={false} default=""/>
diff --git a/docs/docs/reference/Models/ollama.md b/docs/docs/reference/Models/ollama.md
index 9f92c850..f0370b45 100644
--- a/docs/docs/reference/Models/ollama.md
+++ b/docs/docs/reference/Models/ollama.md
@@ -29,6 +29,7 @@ config = ContinueConfig(
<ClassPropertyRef name='context_length' details='{&quot;title&quot;: &quot;Context Length&quot;, &quot;description&quot;: &quot;The maximum context length of the LLM in tokens, as counted by count_tokens.&quot;, &quot;default&quot;: 2048, &quot;type&quot;: &quot;integer&quot;}' required={false} default="2048"/>
<ClassPropertyRef name='unique_id' details='{&quot;title&quot;: &quot;Unique Id&quot;, &quot;description&quot;: &quot;The unique ID of the user.&quot;, &quot;type&quot;: &quot;string&quot;}' required={false} default=""/>
<ClassPropertyRef name='model' details='{&quot;title&quot;: &quot;Model&quot;, &quot;description&quot;: &quot;The name of the model to be used (e.g. gpt-4, codellama)&quot;, &quot;default&quot;: &quot;llama2&quot;, &quot;type&quot;: &quot;string&quot;}' required={false} default="llama2"/>
+<ClassPropertyRef name='stop_tokens' details='{&quot;title&quot;: &quot;Stop Tokens&quot;, &quot;description&quot;: &quot;Tokens that will stop the completion.&quot;, &quot;type&quot;: &quot;array&quot;, &quot;items&quot;: {&quot;type&quot;: &quot;string&quot;}}' required={false} default=""/>
<ClassPropertyRef name='timeout' details='{&quot;title&quot;: &quot;Timeout&quot;, &quot;description&quot;: &quot;Set the timeout for each request to the LLM. If you are running a local LLM that takes a while to respond, you might want to set this to avoid timeouts.&quot;, &quot;default&quot;: 300, &quot;type&quot;: &quot;integer&quot;}' required={false} default="300"/>
<ClassPropertyRef name='verify_ssl' details='{&quot;title&quot;: &quot;Verify Ssl&quot;, &quot;description&quot;: &quot;Whether to verify SSL certificates for requests.&quot;, &quot;type&quot;: &quot;boolean&quot;}' required={false} default=""/>
<ClassPropertyRef name='ca_bundle_path' details='{&quot;title&quot;: &quot;Ca Bundle Path&quot;, &quot;description&quot;: &quot;Path to a custom CA bundle to use when making the HTTP request&quot;, &quot;type&quot;: &quot;string&quot;}' required={false} default=""/>
diff --git a/docs/docs/reference/Models/openai.md b/docs/docs/reference/Models/openai.md
index d9c440b7..f28e0598 100644
--- a/docs/docs/reference/Models/openai.md
+++ b/docs/docs/reference/Models/openai.md
@@ -47,6 +47,7 @@ Options for serving models locally with an OpenAI-compatible server include:
<ClassPropertyRef name='system_message' details='{&quot;title&quot;: &quot;System Message&quot;, &quot;description&quot;: &quot;A system message that will always be followed by the LLM&quot;, &quot;type&quot;: &quot;string&quot;}' required={false} default=""/>
<ClassPropertyRef name='context_length' details='{&quot;title&quot;: &quot;Context Length&quot;, &quot;description&quot;: &quot;The maximum context length of the LLM in tokens, as counted by count_tokens.&quot;, &quot;default&quot;: 2048, &quot;type&quot;: &quot;integer&quot;}' required={false} default="2048"/>
<ClassPropertyRef name='unique_id' details='{&quot;title&quot;: &quot;Unique Id&quot;, &quot;description&quot;: &quot;The unique ID of the user.&quot;, &quot;type&quot;: &quot;string&quot;}' required={false} default=""/>
+<ClassPropertyRef name='stop_tokens' details='{&quot;title&quot;: &quot;Stop Tokens&quot;, &quot;description&quot;: &quot;Tokens that will stop the completion.&quot;, &quot;type&quot;: &quot;array&quot;, &quot;items&quot;: {&quot;type&quot;: &quot;string&quot;}}' required={false} default=""/>
<ClassPropertyRef name='timeout' details='{&quot;title&quot;: &quot;Timeout&quot;, &quot;description&quot;: &quot;Set the timeout for each request to the LLM. If you are running a local LLM that takes a while to respond, you might want to set this to avoid timeouts.&quot;, &quot;default&quot;: 300, &quot;type&quot;: &quot;integer&quot;}' required={false} default="300"/>
<ClassPropertyRef name='verify_ssl' details='{&quot;title&quot;: &quot;Verify Ssl&quot;, &quot;description&quot;: &quot;Whether to verify SSL certificates for requests.&quot;, &quot;type&quot;: &quot;boolean&quot;}' required={false} default=""/>
<ClassPropertyRef name='ca_bundle_path' details='{&quot;title&quot;: &quot;Ca Bundle Path&quot;, &quot;description&quot;: &quot;Path to a custom CA bundle to use when making the HTTP request&quot;, &quot;type&quot;: &quot;string&quot;}' required={false} default=""/>
diff --git a/docs/docs/reference/Models/queued.md b/docs/docs/reference/Models/queued.md
index 2499e03b..231aa4dc 100644
--- a/docs/docs/reference/Models/queued.md
+++ b/docs/docs/reference/Models/queued.md
@@ -31,6 +31,7 @@ config = ContinueConfig(
<ClassPropertyRef name='context_length' details='{&quot;title&quot;: &quot;Context Length&quot;, &quot;description&quot;: &quot;The maximum context length of the LLM in tokens, as counted by count_tokens.&quot;, &quot;default&quot;: 2048, &quot;type&quot;: &quot;integer&quot;}' required={false} default="2048"/>
<ClassPropertyRef name='unique_id' details='{&quot;title&quot;: &quot;Unique Id&quot;, &quot;description&quot;: &quot;The unique ID of the user.&quot;, &quot;type&quot;: &quot;string&quot;}' required={false} default=""/>
<ClassPropertyRef name='model' details='{&quot;title&quot;: &quot;Model&quot;, &quot;description&quot;: &quot;The name of the model to be used (e.g. gpt-4, codellama)&quot;, &quot;default&quot;: &quot;queued&quot;, &quot;type&quot;: &quot;string&quot;}' required={false} default="queued"/>
+<ClassPropertyRef name='stop_tokens' details='{&quot;title&quot;: &quot;Stop Tokens&quot;, &quot;description&quot;: &quot;Tokens that will stop the completion.&quot;, &quot;type&quot;: &quot;array&quot;, &quot;items&quot;: {&quot;type&quot;: &quot;string&quot;}}' required={false} default=""/>
<ClassPropertyRef name='timeout' details='{&quot;title&quot;: &quot;Timeout&quot;, &quot;description&quot;: &quot;Set the timeout for each request to the LLM. If you are running a local LLM that takes a while to respond, you might want to set this to avoid timeouts.&quot;, &quot;default&quot;: 300, &quot;type&quot;: &quot;integer&quot;}' required={false} default="300"/>
<ClassPropertyRef name='verify_ssl' details='{&quot;title&quot;: &quot;Verify Ssl&quot;, &quot;description&quot;: &quot;Whether to verify SSL certificates for requests.&quot;, &quot;type&quot;: &quot;boolean&quot;}' required={false} default=""/>
<ClassPropertyRef name='ca_bundle_path' details='{&quot;title&quot;: &quot;Ca Bundle Path&quot;, &quot;description&quot;: &quot;Path to a custom CA bundle to use when making the HTTP request&quot;, &quot;type&quot;: &quot;string&quot;}' required={false} default=""/>
diff --git a/docs/docs/reference/Models/replicate.md b/docs/docs/reference/Models/replicate.md
index 041f4c2b..83bfd383 100644
--- a/docs/docs/reference/Models/replicate.md
+++ b/docs/docs/reference/Models/replicate.md
@@ -34,6 +34,7 @@ If you don't specify the `model` parameter, it will default to `replicate/llama-
<ClassPropertyRef name='context_length' details='{&quot;title&quot;: &quot;Context Length&quot;, &quot;description&quot;: &quot;The maximum context length of the LLM in tokens, as counted by count_tokens.&quot;, &quot;default&quot;: 2048, &quot;type&quot;: &quot;integer&quot;}' required={false} default="2048"/>
<ClassPropertyRef name='unique_id' details='{&quot;title&quot;: &quot;Unique Id&quot;, &quot;description&quot;: &quot;The unique ID of the user.&quot;, &quot;type&quot;: &quot;string&quot;}' required={false} default=""/>
<ClassPropertyRef name='model' details='{&quot;title&quot;: &quot;Model&quot;, &quot;description&quot;: &quot;The name of the model to be used (e.g. gpt-4, codellama)&quot;, &quot;default&quot;: &quot;replicate/llama-2-70b-chat:58d078176e02c219e11eb4da5a02a7830a283b14cf8f94537af893ccff5ee781&quot;, &quot;type&quot;: &quot;string&quot;}' required={false} default="replicate/llama-2-70b-chat:58d078176e02c219e11eb4da5a02a7830a283b14cf8f94537af893ccff5ee781"/>
+<ClassPropertyRef name='stop_tokens' details='{&quot;title&quot;: &quot;Stop Tokens&quot;, &quot;description&quot;: &quot;Tokens that will stop the completion.&quot;, &quot;type&quot;: &quot;array&quot;, &quot;items&quot;: {&quot;type&quot;: &quot;string&quot;}}' required={false} default=""/>
<ClassPropertyRef name='timeout' details='{&quot;title&quot;: &quot;Timeout&quot;, &quot;description&quot;: &quot;Set the timeout for each request to the LLM. If you are running a local LLM that takes a while to respond, you might want to set this to avoid timeouts.&quot;, &quot;default&quot;: 300, &quot;type&quot;: &quot;integer&quot;}' required={false} default="300"/>
<ClassPropertyRef name='verify_ssl' details='{&quot;title&quot;: &quot;Verify Ssl&quot;, &quot;description&quot;: &quot;Whether to verify SSL certificates for requests.&quot;, &quot;type&quot;: &quot;boolean&quot;}' required={false} default=""/>
<ClassPropertyRef name='ca_bundle_path' details='{&quot;title&quot;: &quot;Ca Bundle Path&quot;, &quot;description&quot;: &quot;Path to a custom CA bundle to use when making the HTTP request&quot;, &quot;type&quot;: &quot;string&quot;}' required={false} default=""/>
diff --git a/docs/docs/reference/Models/text_gen_interface.md b/docs/docs/reference/Models/text_gen_interface.md
index 7ca38b36..d910bee2 100644
--- a/docs/docs/reference/Models/text_gen_interface.md
+++ b/docs/docs/reference/Models/text_gen_interface.md
@@ -32,6 +32,7 @@ config = ContinueConfig(
<ClassPropertyRef name='context_length' details='{&quot;title&quot;: &quot;Context Length&quot;, &quot;description&quot;: &quot;The maximum context length of the LLM in tokens, as counted by count_tokens.&quot;, &quot;default&quot;: 2048, &quot;type&quot;: &quot;integer&quot;}' required={false} default="2048"/>
<ClassPropertyRef name='unique_id' details='{&quot;title&quot;: &quot;Unique Id&quot;, &quot;description&quot;: &quot;The unique ID of the user.&quot;, &quot;type&quot;: &quot;string&quot;}' required={false} default=""/>
<ClassPropertyRef name='model' details='{&quot;title&quot;: &quot;Model&quot;, &quot;description&quot;: &quot;The name of the model to be used (e.g. gpt-4, codellama)&quot;, &quot;default&quot;: &quot;text-gen-ui&quot;, &quot;type&quot;: &quot;string&quot;}' required={false} default="text-gen-ui"/>
+<ClassPropertyRef name='stop_tokens' details='{&quot;title&quot;: &quot;Stop Tokens&quot;, &quot;description&quot;: &quot;Tokens that will stop the completion.&quot;, &quot;type&quot;: &quot;array&quot;, &quot;items&quot;: {&quot;type&quot;: &quot;string&quot;}}' required={false} default=""/>
<ClassPropertyRef name='timeout' details='{&quot;title&quot;: &quot;Timeout&quot;, &quot;description&quot;: &quot;Set the timeout for each request to the LLM. If you are running a local LLM that takes a while to respond, you might want to set this to avoid timeouts.&quot;, &quot;default&quot;: 300, &quot;type&quot;: &quot;integer&quot;}' required={false} default="300"/>
<ClassPropertyRef name='verify_ssl' details='{&quot;title&quot;: &quot;Verify Ssl&quot;, &quot;description&quot;: &quot;Whether to verify SSL certificates for requests.&quot;, &quot;type&quot;: &quot;boolean&quot;}' required={false} default=""/>
<ClassPropertyRef name='ca_bundle_path' details='{&quot;title&quot;: &quot;Ca Bundle Path&quot;, &quot;description&quot;: &quot;Path to a custom CA bundle to use when making the HTTP request&quot;, &quot;type&quot;: &quot;string&quot;}' required={false} default=""/>
diff --git a/docs/docs/reference/Models/together.md b/docs/docs/reference/Models/together.md
index 1a13cbbc..6838ba36 100644
--- a/docs/docs/reference/Models/together.md
+++ b/docs/docs/reference/Models/together.md
@@ -34,6 +34,7 @@ config = ContinueConfig(
<ClassPropertyRef name='context_length' details='{&quot;title&quot;: &quot;Context Length&quot;, &quot;description&quot;: &quot;The maximum context length of the LLM in tokens, as counted by count_tokens.&quot;, &quot;default&quot;: 2048, &quot;type&quot;: &quot;integer&quot;}' required={false} default="2048"/>
<ClassPropertyRef name='unique_id' details='{&quot;title&quot;: &quot;Unique Id&quot;, &quot;description&quot;: &quot;The unique ID of the user.&quot;, &quot;type&quot;: &quot;string&quot;}' required={false} default=""/>
<ClassPropertyRef name='model' details='{&quot;title&quot;: &quot;Model&quot;, &quot;description&quot;: &quot;The name of the model to be used (e.g. gpt-4, codellama)&quot;, &quot;default&quot;: &quot;togethercomputer/RedPajama-INCITE-7B-Instruct&quot;, &quot;type&quot;: &quot;string&quot;}' required={false} default="togethercomputer/RedPajama-INCITE-7B-Instruct"/>
+<ClassPropertyRef name='stop_tokens' details='{&quot;title&quot;: &quot;Stop Tokens&quot;, &quot;description&quot;: &quot;Tokens that will stop the completion.&quot;, &quot;type&quot;: &quot;array&quot;, &quot;items&quot;: {&quot;type&quot;: &quot;string&quot;}}' required={false} default=""/>
<ClassPropertyRef name='timeout' details='{&quot;title&quot;: &quot;Timeout&quot;, &quot;description&quot;: &quot;Set the timeout for each request to the LLM. If you are running a local LLM that takes a while to respond, you might want to set this to avoid timeouts.&quot;, &quot;default&quot;: 300, &quot;type&quot;: &quot;integer&quot;}' required={false} default="300"/>
<ClassPropertyRef name='verify_ssl' details='{&quot;title&quot;: &quot;Verify Ssl&quot;, &quot;description&quot;: &quot;Whether to verify SSL certificates for requests.&quot;, &quot;type&quot;: &quot;boolean&quot;}' required={false} default=""/>
<ClassPropertyRef name='ca_bundle_path' details='{&quot;title&quot;: &quot;Ca Bundle Path&quot;, &quot;description&quot;: &quot;Path to a custom CA bundle to use when making the HTTP request&quot;, &quot;type&quot;: &quot;string&quot;}' required={false} default=""/>
diff --git a/docs/docs/reference/config.md b/docs/docs/reference/config.md
index a96dc2ac..f867ee1e 100644
--- a/docs/docs/reference/config.md
+++ b/docs/docs/reference/config.md
@@ -11,7 +11,7 @@ Continue can be deeply customized by editing the `ContinueConfig` object in `~/.
<ClassPropertyRef name='steps_on_startup' details='{&quot;title&quot;: &quot;Steps On Startup&quot;, &quot;description&quot;: &quot;Steps that will be automatically run at the beginning of a new session&quot;, &quot;default&quot;: [], &quot;type&quot;: &quot;array&quot;, &quot;items&quot;: {&quot;$ref&quot;: &quot;#/definitions/Step&quot;}}' required={false} default="[]"/>
<ClassPropertyRef name='disallowed_steps' details='{&quot;title&quot;: &quot;Disallowed Steps&quot;, &quot;description&quot;: &quot;Steps that are not allowed to be run, and will be skipped if attempted&quot;, &quot;default&quot;: [], &quot;type&quot;: &quot;array&quot;, &quot;items&quot;: {&quot;type&quot;: &quot;string&quot;}}' required={false} default="[]"/>
<ClassPropertyRef name='allow_anonymous_telemetry' details='{&quot;title&quot;: &quot;Allow Anonymous Telemetry&quot;, &quot;description&quot;: &quot;If this field is set to True, we will collect anonymous telemetry as described in the documentation page on telemetry. If set to False, we will not collect any data.&quot;, &quot;default&quot;: true, &quot;type&quot;: &quot;boolean&quot;}' required={false} default="True"/>
-<ClassPropertyRef name='models' details='{&quot;title&quot;: &quot;Models&quot;, &quot;description&quot;: &quot;Configuration for the models used by Continue. Read more about how to configure models in the documentation.&quot;, &quot;default&quot;: {&quot;default&quot;: {&quot;title&quot;: null, &quot;system_message&quot;: null, &quot;context_length&quot;: 2048, &quot;model&quot;: &quot;gpt-4&quot;, &quot;timeout&quot;: 300, &quot;verify_ssl&quot;: null, &quot;ca_bundle_path&quot;: null, &quot;prompt_templates&quot;: {}, &quot;api_key&quot;: null, &quot;llm&quot;: null, &quot;class_name&quot;: &quot;MaybeProxyOpenAI&quot;}, &quot;small&quot;: null, &quot;medium&quot;: {&quot;title&quot;: null, &quot;system_message&quot;: null, &quot;context_length&quot;: 2048, &quot;model&quot;: &quot;gpt-3.5-turbo&quot;, &quot;timeout&quot;: 300, &quot;verify_ssl&quot;: null, &quot;ca_bundle_path&quot;: null, &quot;prompt_templates&quot;: {}, &quot;api_key&quot;: null, &quot;llm&quot;: null, &quot;class_name&quot;: &quot;MaybeProxyOpenAI&quot;}, &quot;large&quot;: null, &quot;edit&quot;: null, &quot;chat&quot;: null, &quot;unused&quot;: []}, &quot;allOf&quot;: [{&quot;$ref&quot;: &quot;#/definitions/Models&quot;}]}' required={false} default="{&#x27;default&#x27;: {&#x27;title&#x27;: None, &#x27;system_message&#x27;: None, &#x27;context_length&#x27;: 2048, &#x27;model&#x27;: &#x27;gpt-4&#x27;, &#x27;timeout&#x27;: 300, &#x27;verify_ssl&#x27;: None, &#x27;ca_bundle_path&#x27;: None, &#x27;prompt_templates&#x27;: {}, &#x27;api_key&#x27;: None, &#x27;llm&#x27;: None, &#x27;class_name&#x27;: &#x27;MaybeProxyOpenAI&#x27;}, &#x27;small&#x27;: None, &#x27;medium&#x27;: {&#x27;title&#x27;: None, &#x27;system_message&#x27;: None, &#x27;context_length&#x27;: 2048, &#x27;model&#x27;: &#x27;gpt-3.5-turbo&#x27;, &#x27;timeout&#x27;: 300, &#x27;verify_ssl&#x27;: None, &#x27;ca_bundle_path&#x27;: None, &#x27;prompt_templates&#x27;: {}, &#x27;api_key&#x27;: None, &#x27;llm&#x27;: None, &#x27;class_name&#x27;: &#x27;MaybeProxyOpenAI&#x27;}, &#x27;large&#x27;: None, &#x27;edit&#x27;: None, &#x27;chat&#x27;: None, &#x27;unused&#x27;: []}"/>
+<ClassPropertyRef name='models' details='{&quot;title&quot;: &quot;Models&quot;, &quot;description&quot;: &quot;Configuration for the models used by Continue. Read more about how to configure models in the documentation.&quot;, &quot;default&quot;: {&quot;default&quot;: {&quot;title&quot;: null, &quot;system_message&quot;: null, &quot;context_length&quot;: 2048, &quot;model&quot;: &quot;gpt-4&quot;, &quot;stop_tokens&quot;: null, &quot;timeout&quot;: 300, &quot;verify_ssl&quot;: null, &quot;ca_bundle_path&quot;: null, &quot;prompt_templates&quot;: {}, &quot;api_key&quot;: null, &quot;llm&quot;: null, &quot;class_name&quot;: &quot;MaybeProxyOpenAI&quot;}, &quot;small&quot;: null, &quot;medium&quot;: {&quot;title&quot;: null, &quot;system_message&quot;: null, &quot;context_length&quot;: 2048, &quot;model&quot;: &quot;gpt-3.5-turbo&quot;, &quot;stop_tokens&quot;: null, &quot;timeout&quot;: 300, &quot;verify_ssl&quot;: null, &quot;ca_bundle_path&quot;: null, &quot;prompt_templates&quot;: {}, &quot;api_key&quot;: null, &quot;llm&quot;: null, &quot;class_name&quot;: &quot;MaybeProxyOpenAI&quot;}, &quot;large&quot;: null, &quot;edit&quot;: null, &quot;chat&quot;: null, &quot;unused&quot;: []}, &quot;allOf&quot;: [{&quot;$ref&quot;: &quot;#/definitions/Models&quot;}]}' required={false} default="{&#x27;default&#x27;: {&#x27;title&#x27;: None, &#x27;system_message&#x27;: None, &#x27;context_length&#x27;: 2048, &#x27;model&#x27;: &#x27;gpt-4&#x27;, &#x27;stop_tokens&#x27;: None, &#x27;timeout&#x27;: 300, &#x27;verify_ssl&#x27;: None, &#x27;ca_bundle_path&#x27;: None, &#x27;prompt_templates&#x27;: {}, &#x27;api_key&#x27;: None, &#x27;llm&#x27;: None, &#x27;class_name&#x27;: &#x27;MaybeProxyOpenAI&#x27;}, &#x27;small&#x27;: None, &#x27;medium&#x27;: {&#x27;title&#x27;: None, &#x27;system_message&#x27;: None, &#x27;context_length&#x27;: 2048, &#x27;model&#x27;: &#x27;gpt-3.5-turbo&#x27;, &#x27;stop_tokens&#x27;: None, &#x27;timeout&#x27;: 300, &#x27;verify_ssl&#x27;: None, &#x27;ca_bundle_path&#x27;: None, &#x27;prompt_templates&#x27;: {}, &#x27;api_key&#x27;: None, &#x27;llm&#x27;: None, &#x27;class_name&#x27;: &#x27;MaybeProxyOpenAI&#x27;}, &#x27;large&#x27;: None, &#x27;edit&#x27;: None, &#x27;chat&#x27;: None, &#x27;unused&#x27;: []}"/>
<ClassPropertyRef name='temperature' details='{&quot;title&quot;: &quot;Temperature&quot;, &quot;description&quot;: &quot;The temperature parameter for sampling from the LLM. Higher temperatures will result in more random output, while lower temperatures will result in more predictable output. This value ranges from 0 to 1.&quot;, &quot;default&quot;: 0.5, &quot;type&quot;: &quot;number&quot;}' required={false} default="0.5"/>
<ClassPropertyRef name='custom_commands' details='{&quot;title&quot;: &quot;Custom Commands&quot;, &quot;description&quot;: &quot;An array of custom commands that allow you to reuse prompts. Each has name, description, and prompt properties. When you enter /&lt;name&gt; in the text input, it will act as a shortcut to the prompt.&quot;, &quot;default&quot;: [{&quot;name&quot;: &quot;test&quot;, &quot;prompt&quot;: &quot;Write a comprehensive set of unit tests for the selected code. It should setup, run tests that check for correctness including important edge cases, and teardown. Ensure that the tests are complete and sophisticated. Give the tests just as chat output, don&#x27;t edit any file.&quot;, &quot;description&quot;: &quot;This is an example custom command. Use /config to edit it and create more&quot;}], &quot;type&quot;: &quot;array&quot;, &quot;items&quot;: {&quot;$ref&quot;: &quot;#/definitions/CustomCommand&quot;}}' required={false} default="[{&#x27;name&#x27;: &#x27;test&#x27;, &#x27;prompt&#x27;: &quot;Write a comprehensive set of unit tests for the selected code. It should setup, run tests that check for correctness including important edge cases, and teardown. Ensure that the tests are complete and sophisticated. Give the tests just as chat output, don&#x27;t edit any file.&quot;, &#x27;description&#x27;: &#x27;This is an example custom command. Use /config to edit it and create more&#x27;}]"/>
<ClassPropertyRef name='slash_commands' details='{&quot;title&quot;: &quot;Slash Commands&quot;, &quot;description&quot;: &quot;An array of slash commands that let you map custom Steps to a shortcut.&quot;, &quot;default&quot;: [], &quot;type&quot;: &quot;array&quot;, &quot;items&quot;: {&quot;$ref&quot;: &quot;#/definitions/SlashCommand&quot;}}' required={false} default="[]"/>
diff --git a/docs/docs/walkthroughs/headless-mode.md b/docs/docs/walkthroughs/headless-mode.md
index 92382d77..d4f90264 100644
--- a/docs/docs/walkthroughs/headless-mode.md
+++ b/docs/docs/walkthroughs/headless-mode.md
@@ -5,23 +5,32 @@
To use headless mode:
1. `pip install continuedev` (using a virtual environment is recommended)
-2. Create a config file (see the [`ContinueConfig` Reference](../reference/config.md) for all options) that includes the [Policy](../customization/other-configuration.md#custom-policies) you want to run
-3. Import `continuedev` and call `start_headless_session` with either the path to your config file, or an instance of `ContinueConfig`
+2. Import `continuedev` and call `run_step_headless` with the `Step` you would like to run
Example:
+Say you have the following file (`/path/to/file.py`):
+
```python
-from continuedev.headless import start_headless_session
-from continuedev.core.config import ContinueConfig
-from continuedev.core.models import Models
-import asyncio
-
-config = ContinueConfig(
- models=Models(...),
- override_policy=MyPolicy()
-)
-asyncio.run(start_headless_session(config))
+def say_hello(name: str):
+ print(f"Hello, {name}")
+```
+
+and this function is imported and used in multiple places throughout your codebase. But the name parameter is new, and you need to change the function call everywhere it is used. You can use the script below to edit all usages of the function in your codebase:
-# Alternatively, pass the path to a config file
-asyncio.run(start_headless_session("/path/to/config.py"))
+```python
+from continuedev.headless import run_step_headless
+from continuedev.models.main import Position, PositionInFile
+from continuedev.plugins.steps.refactor import RefactorReferencesStep
+
+step = RefactorReferencesStep(
+ user_input="",
+ symbol_location=PositionInFile(
+ filepath="/path/to/file.py",
+ position=Position(line=0, character=5),
+ ),
+)
+run_step_headless(step=step)
```
+
+Here we use Continue's built-in `RefactorReferencesStep`. By passing it the location (filepath and position) of the symbol (function, variable, etc.) that we want to update, Continue will automatically find all references to that symbol and prompt an LLM to make the edit requested in the `user_input` field.