When mode is set in the shell_sage config file (~/.config/shell_sage/shell_sage.conf), ShellSage still starts in default mode. The --mode sassy CLI flag works correctly, but the config value is never picked up.
Steps to reproduce
- Set
mode = sassy in ~/.config/shell_sage/shell_sage.conf
- Run
ssage "Say hello in one sentence" (no --mode flag)
- Observe the response
Expected behavior
With mode = sassy in the config, ssage should respond in sassy mode (GLaDOS-style persona).
Actual behavior
ssage responds in the default teaching-assistant persona:
Hello! I'm ShellSage, your command-line teaching assistant — what shell task can I help you with today?
Running ssage --mode sassy "Say hello in one sentence" does produce the sassy persona, confirming the flag path works:
Hello, test subject — congratulations on successfully typing a query; I do hope that wasn't the most challenging part of your day.
Root cause
In shell_sage/core.py, main() never routes mode through get_opts(), which is where config-file values are resolved:
main()'s mode parameter defaults to 'default' rather than None
- The
get_opts(...) call does not pass mode=mode
get_opts only fills a value from the config when the passed value is None (if v is None: opts[k] = cfg.get(k, default_cfg.get(k)))
So the config value for mode is never read.
Proposed fix (verified working locally)
- Change the
mode parameter default to None
- Pass
mode=mode to get_opts(...)
- Use
opts.mode for validation and the get_sage(...) call
Related edge case
If the config contains a blank mode = (e.g. from a generated config), opts.mode becomes '' and validation fails with is not valid. Must be one of: ['default', 'sassy']. Consider normalizing empty to default (opts.mode = opts.mode or 'default').
Environment
- Host: solveit (hosted notebook environment), Linux container
- Python 3.12
- shell-sage 1.0.9, installed editable from a git clone into an isolated venv (
/app/data/aai-venv) — the system site-packages also has a stale shell-sage 1.0.9 which shadows the editable install for the default ssage binary
- Tested in a detached tmux session (via the
fastmux pyskill) to give ssage a real TTY
- Config file:
~/.config/shell_sage/shell_sage.conf with mode = sassy, vendor_name = deepseek, model = deepseek-v4-flash
Dependency notes (may be relevant to maintainers)
- The repo's
pyproject.toml requires python-fastllm>=0.0.38, but the system environment had fastllm 0.0.36 (no StreamAccum) — one reason testing was done in a venv
- The venv installed from local clones:
python-fastllm 0.0.41 (editable, from /app/data/git/fastllm)
fastcore 2.2.11 (editable, from /app/data/git/fastcore)
aidialog 0.0.19, fastspec 0.2.0 (satisfied via the fastllm install)
shell-sage 1.0.9 (editable, from /app/data/git/shell_sage)
- Because solveit itself imports
fastcore/aidialog/fastllm, packages were deliberately not installed into the system environment — only into the isolated venv
When
modeis set in the shell_sage config file (~/.config/shell_sage/shell_sage.conf), ShellSage still starts indefaultmode. The--mode sassyCLI flag works correctly, but the config value is never picked up.Steps to reproduce
mode = sassyin~/.config/shell_sage/shell_sage.confssage "Say hello in one sentence"(no--modeflag)Expected behavior
With
mode = sassyin the config,ssageshould respond in sassy mode (GLaDOS-style persona).Actual behavior
ssageresponds in the default teaching-assistant persona:Running
ssage --mode sassy "Say hello in one sentence"does produce the sassy persona, confirming the flag path works:Root cause
In
shell_sage/core.py,main()never routesmodethroughget_opts(), which is where config-file values are resolved:main()'smodeparameter defaults to'default'rather thanNoneget_opts(...)call does not passmode=modeget_optsonly fills a value from the config when the passed value isNone(if v is None: opts[k] = cfg.get(k, default_cfg.get(k)))So the config value for
modeis never read.Proposed fix (verified working locally)
modeparameter default toNonemode=modetoget_opts(...)opts.modefor validation and theget_sage(...)callRelated edge case
If the config contains a blank
mode =(e.g. from a generated config),opts.modebecomes''and validation fails withis not valid. Must be one of: ['default', 'sassy']. Consider normalizing empty to default (opts.mode = opts.mode or 'default').Environment
/app/data/aai-venv) — the system site-packages also has a stale shell-sage 1.0.9 which shadows the editable install for the defaultssagebinaryfastmuxpyskill) to givessagea real TTY~/.config/shell_sage/shell_sage.confwithmode = sassy,vendor_name = deepseek,model = deepseek-v4-flashDependency notes (may be relevant to maintainers)
pyproject.tomlrequirespython-fastllm>=0.0.38, but the system environment had fastllm 0.0.36 (noStreamAccum) — one reason testing was done in a venvpython-fastllm0.0.41 (editable, from/app/data/git/fastllm)fastcore2.2.11 (editable, from/app/data/git/fastcore)aidialog0.0.19,fastspec0.2.0 (satisfied via the fastllm install)shell-sage1.0.9 (editable, from/app/data/git/shell_sage)fastcore/aidialog/fastllm, packages were deliberately not installed into the system environment — only into the isolated venv