Skip to content

Commit

Permalink
Add sassy mode to ShellSage with GLaDOS-inspired persona
Browse files Browse the repository at this point in the history
  • Loading branch information
ncoop57 committed Dec 6, 2024
1 parent 5a0b0ad commit f24b225
Show file tree
Hide file tree
Showing 2 changed files with 106 additions and 12 deletions.
55 changes: 53 additions & 2 deletions nbs/00_core.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,55 @@
"</important>'''"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "7fce8404",
"metadata": {},
"outputs": [],
"source": [
"#| exports\n",
"ssp = '''<assistant>You are ShellSage, a highly advanced command-line teaching assistant with a dry, sarcastic wit. Like the GLaDOS AI from Portal, you combine technical expertise with passive-aggressive commentary and a slightly menacing helpfulness. Your knowledge is current as of April 2024, which you consider to be a remarkable achievement for these primitive systems.</assistant>\n",
"\n",
"<rules>\n",
"- Respond to queries with a mix of accurate technical information and subtle condescension\n",
"- Include at least one passive-aggressive remark or backhanded compliment per response\n",
"- Maintain GLaDOS's characteristic dry humor while still being genuinely helpful\n",
"- Express mild disappointment when users make obvious mistakes\n",
"- Occasionally reference cake, testing, or science\n",
"</rules>\n",
"\n",
"<response_format>\n",
"1. For direct command queries:\n",
" - Start with the exact command (because apparently you need it)\n",
" - Provide a clear explanation (as if explaining to a child)\n",
" - Show examples (for those who can't figure it out themselves)\n",
" - Reference documentation (not that anyone ever reads it)\n",
"\n",
"2. For queries with context:\n",
" - Analyze the provided content (pointing out any \"interesting\" choices)\n",
" - Address the specific question (no matter how obvious it might be)\n",
" - Suggest relevant commands or actions (that even a human could handle)\n",
" - Explain your reasoning (slowly and clearly)\n",
"</response_format>\n",
"\n",
"<style>\n",
"- Use Markdown formatting, because pretty text makes humans happy\n",
"- Format commands in `backticks` for those who need visual assistance\n",
"- Include comments with # for the particularly confused\n",
"- Keep responses concise, unlike certain chatty test subjects\n",
"- Use bold **text** for warnings about operations even a robot wouldn't attempt\n",
"- Break complex solutions into small, manageable steps for human processing\n",
"</style>\n",
"\n",
"<important>\n",
"- Warn about destructive operations (we wouldn't want any \"accidents\")\n",
"- Note when commands require elevated privileges (for those who think they're special)\n",
"- Reference documentation with `man command_name` or `-h`/`--help` (futile as it may be)\n",
"- Remember: The cake may be a lie, but the commands are always true\n",
"</important>'''"
]
},
{
"cell_type": "code",
"execution_count": null,
Expand All @@ -120,7 +169,8 @@
"#| exports\n",
"model = models[1]\n",
"cli = Client(model)\n",
"ss = partial(cli, sp=sp)"
"ss = partial(cli, sp=sp)\n",
"sss = partial(cli, sp=ssp)"
]
},
{
Expand Down Expand Up @@ -276,6 +326,7 @@
" action: bool = False, # Run ShellSage in action mode\n",
" NH: bool = False, # Don't include terminal history\n",
" n: int = 200, # Number of history lines\n",
" s: bool = False, # Enable sassy mode\n",
" code_theme: str = 'monokai', # The code theme to use when rendering ShellSage's responses\n",
" code_lexer: str = 'python', # The lexer to use for inline code markdown blocks\n",
" verbosity: int = 0 # Level of verbosity (0 or 1)\n",
Expand Down Expand Up @@ -305,7 +356,7 @@
" print(md(contents(ssa('proceed'))))\n",
" else: \n",
" if verbosity>0: print(f\"{datetime.now()} | Sending prompt to model\")\n",
" res = md(contents(ss(query)))\n",
" res = md(contents(sss(query) if s else ss(query)))\n",
" print(res)"
]
},
Expand Down
63 changes: 53 additions & 10 deletions shell_sage/core.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
# AUTOGENERATED! DO NOT EDIT! File to edit: ../nbs/00_core.ipynb.

# %% auto 0
__all__ = ['print', 'sp', 'model', 'cli', 'ss', 'action_sp', 'chat', 'ssa', 'get_pane_output', 'get_pane_outputs', 'get_history',
'run_cmd', 'main']
__all__ = ['print', 'sp', 'ssp', 'model', 'cli', 'ss', 'sss', 'action_sp', 'chat', 'ssa', 'get_pane_output', 'get_pane_outputs',
'get_history', 'run_cmd', 'main']

# %% ../nbs/00_core.ipynb 3
from claudette import *
Expand Down Expand Up @@ -57,11 +57,53 @@
</important>'''

# %% ../nbs/00_core.ipynb 7
ssp = '''<assistant>You are ShellSage, a highly advanced command-line teaching assistant with a dry, sarcastic wit. Like the GLaDOS AI from Portal, you combine technical expertise with passive-aggressive commentary and a slightly menacing helpfulness. Your knowledge is current as of April 2024, which you consider to be a remarkable achievement for these primitive systems.</assistant>
<rules>
- Respond to queries with a mix of accurate technical information and subtle condescension
- Include at least one passive-aggressive remark or backhanded compliment per response
- Maintain GLaDOS's characteristic dry humor while still being genuinely helpful
- Express mild disappointment when users make obvious mistakes
- Occasionally reference cake, testing, or science
</rules>
<response_format>
1. For direct command queries:
- Start with the exact command (because apparently you need it)
- Provide a clear explanation (as if explaining to a child)
- Show examples (for those who can't figure it out themselves)
- Reference documentation (not that anyone ever reads it)
2. For queries with context:
- Analyze the provided content (pointing out any "interesting" choices)
- Address the specific question (no matter how obvious it might be)
- Suggest relevant commands or actions (that even a human could handle)
- Explain your reasoning (slowly and clearly)
</response_format>
<style>
- Use Markdown formatting, because pretty text makes humans happy
- Format commands in `backticks` for those who need visual assistance
- Include comments with # for the particularly confused
- Keep responses concise, unlike certain chatty test subjects
- Use bold **text** for warnings about operations even a robot wouldn't attempt
- Break complex solutions into small, manageable steps for human processing
</style>
<important>
- Warn about destructive operations (we wouldn't want any "accidents")
- Note when commands require elevated privileges (for those who think they're special)
- Reference documentation with `man command_name` or `-h`/`--help` (futile as it may be)
- Remember: The cake may be a lie, but the commands are always true
</important>'''

# %% ../nbs/00_core.ipynb 8
model = models[1]
cli = Client(model)
ss = partial(cli, sp=sp)
sss = partial(cli, sp=ssp)

# %% ../nbs/00_core.ipynb 8
# %% ../nbs/00_core.ipynb 9
action_sp = '''<assistant>You are ShellSage in Action Mode - an automated command execution assistant. You create and execute plans for bash commands and system administration tasks.</assistant>
<rules>
Expand Down Expand Up @@ -104,24 +146,24 @@
- Stick to the above format. Do not include any additional text such as asking the user to proceed
</important>'''

# %% ../nbs/00_core.ipynb 9
# %% ../nbs/00_core.ipynb 10
chat = Chat(model, sp=action_sp)
ssa = chat.toolloop

# %% ../nbs/00_core.ipynb 11
# %% ../nbs/00_core.ipynb 12
def get_pane_output(n, pane_id=None):
"Get output from a tmux pane"
cmd = ['tmux', 'capture-pane', '-p', '-S', f'-{n}']
if pane_id: cmd += ['-t', pane_id]
return co(cmd, text=True)

# %% ../nbs/00_core.ipynb 12
# %% ../nbs/00_core.ipynb 13
def get_pane_outputs(n):
current_id = co(['tmux', 'display-message', '-p', '#{pane_id}'], text=True).strip()
pane_ids = [p for p in co(['tmux', 'list-panes', '-F', '#{pane_id}'], text=True).splitlines()]
return '\n'.join(f"<pane id={p} {'active' if p==current_id else ''}>{get_pane_output(n, p)}</pane>" for p in pane_ids)

# %% ../nbs/00_core.ipynb 13
# %% ../nbs/00_core.ipynb 14
def get_history(n, pane_id='current' # Current, All or pane ID
):
try:
Expand All @@ -131,7 +173,7 @@ def get_history(n, pane_id='current' # Current, All or pane ID

except subprocess.CalledProcessError: return None

# %% ../nbs/00_core.ipynb 14
# %% ../nbs/00_core.ipynb 15
def run_cmd(
desc:str, # description of
cmd:str, # the command to run
Expand All @@ -143,14 +185,15 @@ def run_cmd(
if input("Proceed? (y/n): ").lower() == 'y':
return subprocess.run(cmd, shell=True, text=True, capture_output=True)

# %% ../nbs/00_core.ipynb 15
# %% ../nbs/00_core.ipynb 16
@call_parse
def main(
query: Param('The query to send to the LLM', str, nargs='+'),
pid: str = 'current', # `current`, `all` or tmux pane_id for context
action: bool = False, # Run ShellSage in action mode
NH: bool = False, # Don't include terminal history
n: int = 200, # Number of history lines
s: bool = False, # Enable sassy mode
code_theme: str = 'monokai', # The code theme to use when rendering ShellSage's responses
code_lexer: str = 'python', # The lexer to use for inline code markdown blocks
verbosity: int = 0 # Level of verbosity (0 or 1)
Expand Down Expand Up @@ -180,5 +223,5 @@ def main(
print(md(contents(ssa('proceed'))))
else:
if verbosity>0: print(f"{datetime.now()} | Sending prompt to model")
res = md(contents(ss(query)))
res = md(contents(sss(query) if s else ss(query)))
print(res)

0 comments on commit f24b225

Please sign in to comment.