Skip to content

Commit 5145645

Browse files
Finished functionality to add wrkspace system prompt
1 parent 9c2bb6f commit 5145645

File tree

11 files changed

+147
-83
lines changed

11 files changed

+147
-83
lines changed

migrations/versions/a692c8b52308_add_workspace_system_prompt.py

+3-4
Original file line numberDiff line numberDiff line change
@@ -5,15 +5,14 @@
55
Create Date: 2025-01-17 16:33:58.464223
66
77
"""
8+
89
from typing import Sequence, Union
910

1011
from alembic import op
11-
import sqlalchemy as sa
12-
1312

1413
# revision identifiers, used by Alembic.
15-
revision: str = 'a692c8b52308'
16-
down_revision: Union[str, None] = '5c2f3eee5f90'
14+
revision: str = "a692c8b52308"
15+
down_revision: Union[str, None] = "5c2f3eee5f90"
1716
branch_labels: Union[str, Sequence[str], None] = None
1817
depends_on: Union[str, Sequence[str], None] = None
1918

src/codegate/api/v1.py

+6-3
Original file line numberDiff line numberDiff line change
@@ -59,9 +59,12 @@ async def create_workspace(request: v1_models.CreateWorkspaceRequest):
5959
except AlreadyExistsError:
6060
raise HTTPException(status_code=409, detail="Workspace already exists")
6161
except ValidationError:
62-
raise HTTPException(status_code=400,
63-
detail=("Invalid workspace name. "
64-
"Please use only alphanumeric characters and dashes"))
62+
raise HTTPException(
63+
status_code=400,
64+
detail=(
65+
"Invalid workspace name. " "Please use only alphanumeric characters and dashes"
66+
),
67+
)
6568
except Exception:
6669
raise HTTPException(status_code=500, detail="Internal server error")
6770

src/codegate/dashboard/dashboard.py

+9-8
Original file line numberDiff line numberDiff line change
@@ -20,23 +20,23 @@
2020
dashboard_router = APIRouter(tags=["Dashboard"])
2121
db_reader = None
2222

23+
2324
def get_db_reader():
2425
global db_reader
2526
if db_reader is None:
2627
db_reader = DbReader()
2728
return db_reader
2829

30+
2931
def fetch_latest_version() -> str:
3032
url = "https://api.github.com/repos/stacklok/codegate/releases/latest"
31-
headers = {
32-
"Accept": "application/vnd.github+json",
33-
"X-GitHub-Api-Version": "2022-11-28"
34-
}
33+
headers = {"Accept": "application/vnd.github+json", "X-GitHub-Api-Version": "2022-11-28"}
3534
response = requests.get(url, headers=headers, timeout=5)
3635
response.raise_for_status()
3736
data = response.json()
3837
return data.get("tag_name", "unknown")
3938

39+
4040
@dashboard_router.get("/dashboard/messages")
4141
def get_messages(db_reader: DbReader = Depends(get_db_reader)) -> List[Conversation]:
4242
"""
@@ -72,14 +72,15 @@ async def stream_sse():
7272
"""
7373
return StreamingResponse(generate_sse_events(), media_type="text/event-stream")
7474

75+
7576
@dashboard_router.get("/dashboard/version")
7677
def version_check():
7778
try:
7879
latest_version = fetch_latest_version()
7980

8081
# normalize the versions as github will return them with a 'v' prefix
81-
current_version = __version__.lstrip('v')
82-
latest_version_stripped = latest_version.lstrip('v')
82+
current_version = __version__.lstrip("v")
83+
latest_version_stripped = latest_version.lstrip("v")
8384

8485
is_latest: bool = latest_version_stripped == current_version
8586

@@ -95,15 +96,15 @@ def version_check():
9596
"current_version": __version__,
9697
"latest_version": "unknown",
9798
"is_latest": None,
98-
"error": "An error occurred while fetching the latest version"
99+
"error": "An error occurred while fetching the latest version",
99100
}
100101
except Exception as e:
101102
logger.error(f"Unexpected error: {str(e)}")
102103
return {
103104
"current_version": __version__,
104105
"latest_version": "unknown",
105106
"is_latest": None,
106-
"error": "An unexpected error occurred"
107+
"error": "An unexpected error occurred",
107108
}
108109

109110

src/codegate/db/connection.py

+5-2
Original file line numberDiff line numberDiff line change
@@ -30,9 +30,11 @@
3030
alert_queue = asyncio.Queue()
3131
fim_cache = FimCache()
3232

33+
3334
class AlreadyExistsError(Exception):
3435
pass
3536

37+
3638
class DbCodeGate:
3739
_instance = None
3840

@@ -266,7 +268,8 @@ async def add_workspace(self, workspace_name: str) -> Optional[Workspace]:
266268

267269
try:
268270
added_workspace = await self._execute_update_pydantic_model(
269-
workspace, sql, should_raise=True)
271+
workspace, sql, should_raise=True
272+
)
270273
except IntegrityError as e:
271274
logger.debug(f"Exception type: {type(e)}")
272275
raise AlreadyExistsError(f"Workspace {workspace_name} already exists.")
@@ -424,7 +427,7 @@ async def get_active_workspace(self) -> Optional[ActiveWorkspace]:
424427
sql = text(
425428
"""
426429
SELECT
427-
w.id, w.name, s.id as session_id, s.last_update
430+
w.id, w.name, w.system_prompt, s.id as session_id, s.last_update
428431
FROM sessions s
429432
INNER JOIN workspaces w ON w.id = s.active_workspace_id
430433
"""

src/codegate/db/models.py

+1-5
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,6 @@ class Workspace(BaseModel):
5050
def validate_name(cls, value):
5151
if not re.match(r"^[a-zA-Z0-9_-]+$", value):
5252
raise ValueError("name must be alphanumeric and can only contain _ and -")
53-
# Avoid workspace names that are the same as commands that way we can do stuff like
54-
# `codegate workspace list` and
55-
# `codegate workspace my-ws system-prompt` without any conflicts
56-
elif value in ["list", "add", "activate", "system-prompt"]:
57-
raise ValueError("name cannot be the same as a command")
5853
return value
5954

6055

@@ -104,5 +99,6 @@ class WorkspaceActive(BaseModel):
10499
class ActiveWorkspace(BaseModel):
105100
id: str
106101
name: str
102+
system_prompt: Optional[str]
107103
session_id: str
108104
last_update: datetime.datetime

src/codegate/pipeline/cli/commands.py

+45-27
Original file line numberDiff line numberDiff line change
@@ -31,10 +31,10 @@ async def run(self, args: List[str]) -> str:
3131
@property
3232
def help(self) -> str:
3333
return (
34-
"### CodeGate Version\n\n"
34+
"### CodeGate Version\n"
3535
"Prints the version of CodeGate.\n\n"
36+
"*args*: None\n\n"
3637
"**Usage**: `codegate version`\n\n"
37-
"*args*: None"
3838
)
3939

4040

@@ -46,6 +46,7 @@ def __init__(self):
4646
"list": self._list_workspaces,
4747
"add": self._add_workspace,
4848
"activate": self._activate_workspace,
49+
"system-prompt": self._add_system_prompt,
4950
}
5051

5152
async def _list_workspaces(self, *args: List[str]) -> str:
@@ -66,52 +67,63 @@ async def _add_workspace(self, args: List[str]) -> str:
6667
Add a workspace
6768
"""
6869
if args is None or len(args) == 0:
69-
return "Please provide a name. Use `codegate workspace add your_workspace_name`"
70+
return "Please provide a name. Use `codegate workspace add <workspace_name>`"
7071

7172
new_workspace_name = args[0]
7273
if not new_workspace_name:
73-
return "Please provide a name. Use `codegate workspace add your_workspace_name`"
74+
return "Please provide a name. Use `codegate workspace add <workspace_name>`"
7475

7576
try:
7677
_ = await self.workspace_crud.add_workspace(new_workspace_name)
7778
except ValidationError:
7879
return "Invalid workspace name: It should be alphanumeric and dashes"
7980
except AlreadyExistsError:
80-
return f"Workspace **{new_workspace_name}** already exists"
81+
return f"Workspace `{new_workspace_name}` already exists"
8182
except Exception:
8283
return "An error occurred while adding the workspace"
8384

84-
return f"Workspace **{new_workspace_name}** has been added"
85+
return f"Workspace `{new_workspace_name}` has been added"
8586

8687
async def _activate_workspace(self, args: List[str]) -> str:
8788
"""
8889
Activate a workspace
8990
"""
9091
if args is None or len(args) == 0:
91-
return "Please provide a name. Use `codegate workspace activate workspace_name`"
92+
return "Please provide a name. Use `codegate workspace activate <workspace_name>`"
9293

9394
workspace_name = args[0]
9495
if not workspace_name:
95-
return "Please provide a name. Use `codegate workspace activate workspace_name`"
96+
return "Please provide a name. Use `codegate workspace activate <workspace_name>`"
9697

9798
was_activated = await self.workspace_crud.activate_workspace(workspace_name)
9899
if not was_activated:
99100
return (
100-
f"Workspace **{workspace_name}** does not exist or was already active. "
101+
f"Workspace `{workspace_name}` does not exist or was already active. "
101102
f"Use `codegate workspace add {workspace_name}` to add it"
102103
)
103-
return f"Workspace **{workspace_name}** has been activated"
104+
return f"Workspace `{workspace_name}` has been activated"
104105

105-
async def _add_system_prompt(self, workspace_name: str, sys_prompt_lst: List[str]):
106-
updated_worksapce = await self.workspace_crud.update_workspace_system_prompt(workspace_name, sys_prompt_lst)
106+
async def _add_system_prompt(self, args: List[str]):
107+
if len(args) < 2:
108+
return (
109+
"Please provide a workspace name and a system prompt. "
110+
"Use `codegate workspace system-prompt <workspace_name> <system_prompt>`"
111+
)
112+
113+
workspace_name = args[0]
114+
sys_prompt_lst = args[1:]
115+
116+
updated_worksapce = await self.workspace_crud.update_workspace_system_prompt(
117+
workspace_name, sys_prompt_lst
118+
)
107119
if not updated_worksapce:
108120
return (
109121
f"Workspace system prompt not updated. "
110-
f"Check if the workspace **{workspace_name}** exists"
122+
f"Check if the workspace `{workspace_name}` exists"
111123
)
112124
return (
113-
f"Workspace **{updated_worksapce.name}** system prompt "
114-
f"updated to:\n\n```{updated_worksapce.system_prompt}```"
125+
f"Workspace `{updated_worksapce.name}` system prompt "
126+
f"updated to:\n```\n{updated_worksapce.system_prompt}\n```"
115127
)
116128

117129
async def run(self, args: List[str]) -> str:
@@ -122,23 +134,29 @@ async def run(self, args: List[str]) -> str:
122134
if command_to_execute is not None:
123135
return await command_to_execute(args[1:])
124136
else:
125-
if len(args) >= 2 and args[1] == "system-prompt":
126-
return await self._add_system_prompt(args[0], args[2:])
127137
return "Command not found. Use `codegate workspace -h` to see available commands"
128138

129139
@property
130140
def help(self) -> str:
131141
return (
132-
"### CodeGate Workspace\n\n"
142+
"### CodeGate Workspace\n"
133143
"Manage workspaces.\n\n"
134144
"**Usage**: `codegate workspace <command> [args]`\n\n"
135-
"Available commands:\n\n"
136-
"- `list`: List all workspaces\n\n"
137-
" - *args*: None\n\n"
138-
"- `add`: Add a workspace\n\n"
139-
" - *args*:\n\n"
140-
" - `workspace_name`\n\n"
141-
"- `activate`: Activate a workspace\n\n"
142-
" - *args*:\n\n"
143-
" - `workspace_name`"
145+
"Available commands:\n"
146+
"- `list`: List all workspaces\n"
147+
" - *args*: None\n"
148+
" - **Usage**: `codegate workspace list`\n"
149+
"- `add`: Add a workspace\n"
150+
" - *args*:\n"
151+
" - `workspace_name`\n"
152+
" - **Usage**: `codegate workspace add <workspace_name>`\n"
153+
"- `activate`: Activate a workspace\n"
154+
" - *args*:\n"
155+
" - `workspace_name`\n"
156+
" - **Usage**: `codegate workspace activate <workspace_name>`\n"
157+
"- `system-prompt`: Modify the system-prompt of a workspace\n"
158+
" - *args*:\n"
159+
" - `workspace_name`\n"
160+
" - `system_prompt`\n"
161+
" - **Usage**: `codegate workspace system-prompt <workspace_name> <system_prompt>`\n"
144162
)

0 commit comments

Comments
 (0)