summaryrefslogtreecommitdiff
path: root/server/continuedev/libs/util/edit_config.py
diff options
context:
space:
mode:
authorNate Sesti <33237525+sestinj@users.noreply.github.com>2023-10-09 18:37:27 -0700
committerGitHub <noreply@github.com>2023-10-09 18:37:27 -0700
commitf09150617ed2454f3074bcf93f53aae5ae637d40 (patch)
tree5cfe614a64d921dfe58b049f426d67a8b832c71f /server/continuedev/libs/util/edit_config.py
parent985304a213f620cdff3f8f65f74ed7e3b79be29d (diff)
downloadsncontinue-f09150617ed2454f3074bcf93f53aae5ae637d40.tar.gz
sncontinue-f09150617ed2454f3074bcf93f53aae5ae637d40.tar.bz2
sncontinue-f09150617ed2454f3074bcf93f53aae5ae637d40.zip
Preview (#541)
* Strong typing (#533) * refactor: :recycle: get rid of continuedev.src.continuedev structure * refactor: :recycle: switching back to server folder * feat: :sparkles: make config.py imports shorter * feat: :bookmark: publish as pre-release vscode extension * refactor: :recycle: refactor and add more completion params to ui * build: :building_construction: download from preview S3 * fix: :bug: fix paths * fix: :green_heart: package:pre-release * ci: :green_heart: more time for tests * fix: :green_heart: fix build scripts * fix: :bug: fix import in run.py * fix: :bookmark: update version to try again * ci: 💚 Update package.json version [skip ci] * refactor: :fire: don't check for old extensions version * fix: :bug: small bug fixes * fix: :bug: fix config.py import paths * ci: 💚 Update package.json version [skip ci] * ci: :green_heart: platform-specific builds test #1 * feat: :green_heart: ship with binary * fix: :green_heart: fix copy statement to include.exe for windows * fix: :green_heart: cd extension before packaging * chore: :loud_sound: count tokens generated * fix: :green_heart: remove npm_config_arch * fix: :green_heart: publish as pre-release! * chore: :bookmark: update version * perf: :green_heart: hardcode distro paths * fix: :bug: fix yaml syntax error * chore: :bookmark: update version * fix: :green_heart: update permissions and version * feat: :bug: kill old server if needed * feat: :lipstick: update marketplace icon for pre-release * ci: 💚 Update package.json version [skip ci] * feat: :sparkles: auto-reload for config.py * feat: :wrench: update default config.py imports * feat: :sparkles: codelens in config.py * feat: :sparkles: select model param count from UI * ci: 💚 Update package.json version [skip ci] * feat: :sparkles: more model options, ollama error handling * perf: :zap: don't show server loading immediately * fix: :bug: fixing small UI details * ci: 💚 Update package.json version [skip ci] * feat: :rocket: headers param on LLM class * fix: :bug: fix headers for openai.;y * feat: :sparkles: highlight code on cmd+shift+L * ci: 💚 Update package.json version [skip ci] * feat: :lipstick: sticky top bar in gui.tsx * fix: :loud_sound: websocket logging and horizontal scrollbar * ci: 💚 Update package.json version [skip ci] * feat: :sparkles: allow AzureOpenAI Service through GGML * ci: 💚 Update package.json version [skip ci] * fix: :bug: fix automigration * ci: 💚 Update package.json version [skip ci] * ci: :green_heart: upload binaries in ci, download apple silicon * chore: :fire: remove notes * fix: :green_heart: use curl to download binary * fix: :green_heart: set permissions on apple silicon binary * fix: :green_heart: testing * fix: :green_heart: cleanup file * fix: :green_heart: fix preview.yaml * fix: :green_heart: only upload once per binary * fix: :green_heart: install rosetta * ci: :green_heart: download binary after tests * ci: 💚 Update package.json version [skip ci] * ci: :green_heart: prepare ci for merge to main --------- Co-authored-by: GitHub Action <action@github.com>
Diffstat (limited to 'server/continuedev/libs/util/edit_config.py')
-rw-r--r--server/continuedev/libs/util/edit_config.py149
1 files changed, 149 insertions, 0 deletions
diff --git a/server/continuedev/libs/util/edit_config.py b/server/continuedev/libs/util/edit_config.py
new file mode 100644
index 00000000..4dc427d2
--- /dev/null
+++ b/server/continuedev/libs/util/edit_config.py
@@ -0,0 +1,149 @@
+import threading
+from typing import Any, Dict, List
+
+import redbaron
+
+from .paths import getConfigFilePath
+
+
+def get_config_source():
+ config_file_path = getConfigFilePath()
+ with open(config_file_path, "r") as file:
+ source_code = file.read()
+ return source_code
+
+
+def load_red():
+ source_code = get_config_source()
+
+ red = redbaron.RedBaron(source_code)
+ return red
+
+
+def get_config_node(red):
+ for node in red:
+ if node.type == "assignment" and node.target.value == "config":
+ return node
+ else:
+ raise Exception("Config file appears to be improperly formatted")
+
+
+def edit_property(
+ args: redbaron.RedBaron, key_path: List[str], value: redbaron.RedBaron
+):
+ for i in range(len(args)):
+ node = args[i]
+ if node.type != "call_argument":
+ continue
+
+ if node.target.value == key_path[0]:
+ if len(key_path) > 1:
+ edit_property(node.value.value[1].value, key_path[1:], value)
+ else:
+ args[i].value = value
+ return
+
+
+edit_lock = threading.Lock()
+
+
+def edit_config_property(key_path: List[str], value: redbaron.RedBaron):
+ with edit_lock:
+ red = load_red()
+ config = get_config_node(red)
+ config_args = config.value.value[1].value
+ edit_property(config_args, key_path, value)
+
+ with open(getConfigFilePath(), "w") as file:
+ file.write(red.dumps())
+
+
+def add_config_import(line: str):
+ # check if the import already exists
+ source = get_config_source()
+ if line in source:
+ return
+
+ with edit_lock:
+ red = load_red()
+ # if it doesn't exist, add it
+ red.insert(1, line)
+
+ with open(getConfigFilePath(), "w") as file:
+ file.write(red.dumps())
+
+
+filtered_attrs = {
+ "class_name",
+ "name",
+ "llm",
+}
+
+filtered_attrs_when_new = {"timeout", "prompt_templates"}
+
+
+def escape_string(string: str) -> str:
+ return string.replace('"', '\\"').replace("'", "\\'")
+
+
+def display_val(v: Any, k: str = None):
+ if k == "template_messages":
+ return v
+
+ if isinstance(v, str):
+ return f'"{escape_string(v)}"'
+ return str(v)
+
+
+def is_default(llm, k, v):
+ if k == "template_messages" and llm.__fields__[k].default is not None:
+ return llm.__fields__[k].default.__name__ == v
+ return v == llm.__fields__[k].default
+
+
+def display_llm_class(llm, new: bool = False):
+ sep = ",\n\t\t\t"
+ args = sep.join(
+ [
+ f"{k}={display_val(v, k)}"
+ for k, v in llm.dict().items()
+ if k not in filtered_attrs and v is not None and not is_default(llm, k, v)
+ ]
+ )
+ return f"{llm.__class__.__name__}(\n\t\t\t{args}\n\t\t)"
+
+
+def create_obj_node(
+ class_name: str, args: Dict[str, str], tabs: int = 1
+) -> redbaron.RedBaron:
+ args = [f"{key}={value}" for key, value in args.items()]
+ t = "\t" * tabs
+ new_line = "\n\t" + t
+ sep = "," + new_line
+
+ return redbaron.RedBaron(f"{class_name}({new_line}{sep.join(args)}\n{t})")[0]
+
+
+def create_string_node(string: str) -> redbaron.RedBaron:
+ string = escape_string(string)
+ if "\n" in string:
+ return redbaron.RedBaron(f'"""{string}"""')[0]
+ return redbaron.RedBaron(f'"{string}"')[0]
+
+
+def create_literal_node(literal: str) -> redbaron.RedBaron:
+ return redbaron.RedBaron(literal)[0]
+
+
+def create_float_node(float: float) -> redbaron.RedBaron:
+ return redbaron.RedBaron(f"{float}")[0]
+
+
+# Example:
+# edit_config_property(
+# [
+# "models",
+# "default",
+# ],
+# create_obj_node("OpenAI", {"api_key": '""', "model": '"gpt-4"'}),
+# )