Skip to content
This repository was archived by the owner on Jun 5, 2025. It is now read-only.

Rename workspaces system-prompt to custom-instructions #713

Merged
merged 2 commits into from
Jan 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
"""rename system_prompt

Revision ID: 90d5471db49a
Revises: 4dec3e456c9e
Create Date: 2025-01-22 09:56:21.520839+00:00

"""

from typing import Sequence, Union

from alembic import op

# revision identifiers, used by Alembic.
revision: str = "90d5471db49a"
down_revision: Union[str, None] = "4dec3e456c9e"
branch_labels: Union[str, Sequence[str], None] = None
depends_on: Union[str, Sequence[str], None] = None


def upgrade() -> None:
op.execute("ALTER TABLE workspaces RENAME COLUMN system_prompt TO custom_instructions;")


def downgrade() -> None:
op.execute("ALTER TABLE workspaces RENAME COLUMN custom_instructions TO system_prompt;")
26 changes: 14 additions & 12 deletions src/codegate/api/v1.py
Original file line number Diff line number Diff line change
Expand Up @@ -228,35 +228,37 @@ async def get_workspace_messages(workspace_name: str) -> List[Conversation]:


@v1.get(
"/workspaces/{workspace_name}/system-prompt",
"/workspaces/{workspace_name}/custom-instructions",
tags=["Workspaces"],
generate_unique_id_function=uniq_name,
)
async def get_workspace_system_prompt(workspace_name: str) -> v1_models.SystemPrompt:
"""Get the system prompt for a workspace."""
async def get_workspace_custom_instructions(workspace_name: str) -> v1_models.CustomInstructions:
"""Get the custom instructions of a workspace."""
try:
ws = await wscrud.get_workspace_by_name(workspace_name)
except crud.WorkspaceDoesNotExistError:
raise HTTPException(status_code=404, detail="Workspace does not exist")
except Exception:
raise HTTPException(status_code=500, detail="Internal server error")

if ws.system_prompt is None:
return v1_models.SystemPrompt(prompt="")
if ws.custom_instructions is None:
return v1_models.CustomInstructions(prompt="")

return v1_models.SystemPrompt(prompt=ws.system_prompt)
return v1_models.CustomInstructions(prompt=ws.custom_instructions)


@v1.put(
"/workspaces/{workspace_name}/system-prompt",
"/workspaces/{workspace_name}/custom-instructions",
tags=["Workspaces"],
generate_unique_id_function=uniq_name,
status_code=204,
)
async def set_workspace_system_prompt(workspace_name: str, request: v1_models.SystemPrompt):
async def set_workspace_custom_instructions(
workspace_name: str, request: v1_models.CustomInstructions
):
try:
# This already checks if the workspace exists
await wscrud.update_workspace_system_prompt(workspace_name, [request.prompt])
await wscrud.update_workspace_custom_instructions(workspace_name, [request.prompt])
except crud.WorkspaceDoesNotExistError:
raise HTTPException(status_code=404, detail="Workspace does not exist")
except Exception:
Expand All @@ -266,15 +268,15 @@ async def set_workspace_system_prompt(workspace_name: str, request: v1_models.Sy


@v1.delete(
"/workspaces/{workspace_name}/system-prompt",
"/workspaces/{workspace_name}/custom-instructions",
tags=["Workspaces"],
generate_unique_id_function=uniq_name,
status_code=204,
)
async def delete_workspace_system_prompt(workspace_name: str):
async def delete_workspace_custom_instructions(workspace_name: str):
try:
# This already checks if the workspace exists
await wscrud.update_workspace_system_prompt(workspace_name, [])
await wscrud.update_workspace_custom_instructions(workspace_name, [])
except crud.WorkspaceDoesNotExistError:
raise HTTPException(status_code=404, detail="Workspace does not exist")
except Exception:
Expand Down
2 changes: 1 addition & 1 deletion src/codegate/api/v1_models.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ class Workspace(pydantic.BaseModel):
is_active: bool


class SystemPrompt(pydantic.BaseModel):
class CustomInstructions(pydantic.BaseModel):
prompt: str


Expand Down
12 changes: 6 additions & 6 deletions src/codegate/db/connection.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,7 +271,7 @@ async def add_workspace(self, workspace_name: str) -> Workspace:
It may raise a ValidationError if the workspace name is invalid.
or a AlreadyExistsError if the workspace already exists.
"""
workspace = Workspace(id=str(uuid.uuid4()), name=workspace_name, system_prompt=None)
workspace = Workspace(id=str(uuid.uuid4()), name=workspace_name, custom_instructions=None)
sql = text(
"""
INSERT INTO workspaces (id, name)
Expand All @@ -294,7 +294,7 @@ async def update_workspace(self, workspace: Workspace) -> Workspace:
"""
UPDATE workspaces SET
name = :name,
system_prompt = :system_prompt
custom_instructions = :custom_instructions
WHERE id = :id
RETURNING *
"""
Expand Down Expand Up @@ -477,7 +477,7 @@ async def get_archived_workspaces(self) -> List[Workspace]:
sql = text(
"""
SELECT
id, name, system_prompt
id, name, custom_instructions
FROM workspaces
WHERE deleted_at IS NOT NULL
ORDER BY deleted_at DESC
Expand All @@ -490,7 +490,7 @@ async def get_workspace_by_name(self, name: str) -> Optional[Workspace]:
sql = text(
"""
SELECT
id, name, system_prompt
id, name, custom_instructions
FROM workspaces
WHERE name = :name AND deleted_at IS NULL
"""
Expand All @@ -505,7 +505,7 @@ async def get_archived_workspace_by_name(self, name: str) -> Optional[Workspace]
sql = text(
"""
SELECT
id, name, system_prompt
id, name, custom_instructions
FROM workspaces
WHERE name = :name AND deleted_at IS NOT NULL
"""
Expand All @@ -531,7 +531,7 @@ async def get_active_workspace(self) -> Optional[ActiveWorkspace]:
sql = text(
"""
SELECT
w.id, w.name, w.system_prompt, s.id as session_id, s.last_update
w.id, w.name, w.custom_instructions, s.id as session_id, s.last_update
FROM sessions s
INNER JOIN workspaces w ON w.id = s.active_workspace_id
"""
Expand Down
4 changes: 2 additions & 2 deletions src/codegate/db/models.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ class Setting(BaseModel):
class Workspace(BaseModel):
id: str
name: WorskpaceNameStr
system_prompt: Optional[str]
custom_instructions: Optional[str]


class Session(BaseModel):
Expand Down Expand Up @@ -99,6 +99,6 @@ class WorkspaceActive(BaseModel):
class ActiveWorkspace(BaseModel):
id: str
name: str
system_prompt: Optional[str]
custom_instructions: Optional[str]
session_id: str
last_update: datetime.datetime
4 changes: 2 additions & 2 deletions src/codegate/pipeline/cli/cli.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
PipelineResult,
PipelineStep,
)
from codegate.pipeline.cli.commands import SystemPrompt, Version, Workspace
from codegate.pipeline.cli.commands import CustomInstructions, Version, Workspace

HELP_TEXT = """
## CodeGate CLI\n
Expand All @@ -32,7 +32,7 @@ async def codegate_cli(command):
available_commands = {
"version": Version().exec,
"workspace": Workspace().exec,
"system-prompt": SystemPrompt().exec,
"custom-instructions": CustomInstructions().exec,
}
out_func = available_commands.get(command[0])
if out_func is None:
Expand Down
59 changes: 30 additions & 29 deletions src/codegate/pipeline/cli/commands.py
Original file line number Diff line number Diff line change
Expand Up @@ -355,40 +355,40 @@ def help(self) -> str:
)


class SystemPrompt(CodegateCommandSubcommand):
class CustomInstructions(CodegateCommandSubcommand):

def __init__(self):
self.workspace_crud = crud.WorkspaceCrud()

@property
def command_name(self) -> str:
return "system-prompt"
return "custom-instructions"

@property
def flags(self) -> List[str]:
"""
Flags for the system-prompt command.
Flags for the custom-instructions command.
-w: Workspace name
"""
return ["-w"]

@property
def subcommands(self) -> Dict[str, Callable[[List[str]], Awaitable[str]]]:
return {
"set": self._set_system_prompt,
"show": self._show_system_prompt,
"reset": self._reset_system_prompt,
"set": self._set_custom_instructions,
"show": self._show_custom_instructions,
"reset": self._reset_custom_instructions,
}

async def _set_system_prompt(self, flags: Dict[str, str], args: List[str]) -> str:
async def _set_custom_instructions(self, flags: Dict[str, str], args: List[str]) -> str:
"""
Set the system prompt of a workspace
Set the custom instructions of a workspace
If a workspace name is not provided, the active workspace is used
"""
if len(args) == 0:
return (
"Please provide a workspace name and a system prompt. "
"Use `codegate workspace system-prompt -w <workspace_name> <system_prompt>`"
"Please provide a workspace name and custom instructions to use. "
"Use `codegate workspace custom-instructions -w <workspace_name> <instructions>`"
)

workspace_name = flags.get("-w")
Expand All @@ -397,19 +397,20 @@ async def _set_system_prompt(self, flags: Dict[str, str], args: List[str]) -> st
workspace_name = active_workspace.name

try:
updated_worksapce = await self.workspace_crud.update_workspace_system_prompt(
updated_worksapce = await self.workspace_crud.update_workspace_instructions(
workspace_name, args
)
except crud.WorkspaceDoesNotExistError:
return (
f"Workspace system prompt not updated. Workspace `{workspace_name}` doesn't exist"
f"Workspace custom instructions not updated. "
f"Workspace `{workspace_name}` doesn't exist"
)

return f"Workspace `{updated_worksapce.name}` system prompt updated."
return f"Workspace `{updated_worksapce.name}` custom instructions updated."

async def _show_system_prompt(self, flags: Dict[str, str], args: List[str]) -> str:
async def _show_custom_instructions(self, flags: Dict[str, str], args: List[str]) -> str:
"""
Show the system prompt of a workspace
Show the custom instructions of a workspace
If a workspace name is not provided, the active workspace is used
"""
workspace_name = flags.get("-w")
Expand All @@ -422,15 +423,15 @@ async def _show_system_prompt(self, flags: Dict[str, str], args: List[str]) -> s
except crud.WorkspaceDoesNotExistError:
return f"Workspace `{workspace_name}` doesn't exist"

sysprompt = workspace.system_prompt
sysprompt = workspace.custom_instructions
if not sysprompt:
return f"Workspace **{workspace.name}** system prompt is unset."
return f"Workspace **{workspace.name}** custom instructions is unset."

return f"Workspace **{workspace.name}** system prompt:\n\n{sysprompt}."
return f"Workspace **{workspace.name}** custom instructions:\n\n{sysprompt}."

async def _reset_system_prompt(self, flags: Dict[str, str], args: List[str]) -> str:
async def _reset_custom_instructions(self, flags: Dict[str, str], args: List[str]) -> str:
"""
Reset the system prompt of a workspace
Reset the custom instructions of a workspace
If a workspace name is not provided, the active workspace is used
"""
workspace_name = flags.get("-w")
Expand All @@ -439,28 +440,28 @@ async def _reset_system_prompt(self, flags: Dict[str, str], args: List[str]) ->
workspace_name = active_workspace.name

try:
updated_worksapce = await self.workspace_crud.update_workspace_system_prompt(
updated_worksapce = await self.workspace_crud.update_workspace_custom_instructions(
workspace_name, [""]
)
except crud.WorkspaceDoesNotExistError:
return f"Workspace `{workspace_name}` doesn't exist"

return f"Workspace `{updated_worksapce.name}` system prompt reset."
return f"Workspace `{updated_worksapce.name}` custom instructions reset."

@property
def help(self) -> str:
return (
"### CodeGate System Prompt\n"
"Manage the system prompts of workspaces.\n\n"
"*Note*: If you want to update the system prompt using files please go to the "
"### CodeGate Custom Instructions\n"
"Manage the custom instructionss of workspaces.\n\n"
"*Note*: If you want to update the custom instructions using files please go to the "
"[dashboard](http://localhost:9090).\n\n"
"**Usage**: `codegate system-prompt -w <workspace_name> <command>`\n\n"
"**Usage**: `codegate custom-instructions -w <workspace_name> <command>`\n\n"
"*args*:\n"
"- `workspace_name`: Optional workspace name. If not specified will use the "
"active workspace\n\n"
"Available commands:\n"
"- `set`: Set the system prompt of the workspace\n"
"- `set`: Set the custom instructions of the workspace\n"
" - *args*:\n"
" - `system_prompt`: The system prompt to set\n"
" - **Usage**: `codegate system-prompt -w <workspace_name> set <system_prompt>`\n"
" - `instructions`: The custom instructions to set\n"
" - **Usage**: `codegate custom-instructions -w <workspace_name> set <instructions>`\n"
)
16 changes: 8 additions & 8 deletions src/codegate/pipeline/system_prompt/codegate.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,17 @@ def name(self) -> str:
"""
return "system-prompt"

async def _get_workspace_system_prompt(self) -> str:
async def _get_workspace_custom_instructions(self) -> str:
wksp_crud = WorkspaceCrud()
workspace = await wksp_crud.get_active_workspace()
if not workspace:
return ""

return workspace.system_prompt
return workspace.custom_instructions

async def _construct_system_prompt(
self,
wrksp_sys_prompt: str,
wrksp_custom_instr: str,
req_sys_prompt: Optional[str],
should_add_codegate_sys_prompt: bool,
) -> ChatCompletionSystemMessage:
Expand All @@ -52,8 +52,8 @@ def _start_or_append(existing_prompt: str, new_prompt: str) -> str:
system_prompt = _start_or_append(system_prompt, self.codegate_system_prompt)

# Add workspace system prompt if present
if wrksp_sys_prompt:
system_prompt = _start_or_append(system_prompt, wrksp_sys_prompt)
if wrksp_custom_instr:
system_prompt = _start_or_append(system_prompt, wrksp_custom_instr)

# Add request system prompt if present
if req_sys_prompt and "codegate" not in req_sys_prompt.lower():
Expand All @@ -72,12 +72,12 @@ async def process(
to the existing system prompt
"""

wrksp_sys_prompt = await self._get_workspace_system_prompt()
wrksp_custom_instructions = await self._get_workspace_custom_instructions()
should_add_codegate_sys_prompt = await self._should_add_codegate_system_prompt(context)

# Nothing to do if no secrets or bad_packages are found and we don't have a workspace
# system prompt
if not should_add_codegate_sys_prompt and not wrksp_sys_prompt:
if not should_add_codegate_sys_prompt and not wrksp_custom_instructions:
return PipelineResult(request=request, context=context)

new_request = request.copy()
Expand All @@ -92,7 +92,7 @@ async def process(
req_sys_prompt = request_system_message.get("content")

system_prompt = await self._construct_system_prompt(
wrksp_sys_prompt, req_sys_prompt, should_add_codegate_sys_prompt
wrksp_custom_instructions, req_sys_prompt, should_add_codegate_sys_prompt
)
context.add_alert(self.name, trigger_string=system_prompt)
if not request_system_message:
Expand Down
Loading
Loading