Skip to content
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
93 changes: 85 additions & 8 deletions nbs/00_core.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,22 @@
"execution_count": null,
"id": "2ddd0b97",
"metadata": {},
"outputs": [],
"outputs": [
{
"name": "stderr",
"output_type": "stream",
"text": [
"\u001b[92m11:15:42 - LiteLLM:WARNING\u001b[0m: common_utils.py:979 - litellm: could not pre-load bedrock-runtime response stream shape — Bedrock event-stream decoding will be unavailable. Error: No module named 'botocore'\n"
]
},
{
"name": "stderr",
"output_type": "stream",
"text": [
"\u001b[92m11:15:42 - LiteLLM:WARNING\u001b[0m: common_utils.py:24 - litellm: could not pre-load sagemaker-runtime response stream shape — SageMaker event-stream decoding will be unavailable. Error: No module named 'botocore'\n"
]
}
],
"source": [
"#| hide\n",
"enable_cachy()"
Expand Down Expand Up @@ -318,7 +333,15 @@
"id": "b2912805",
"metadata": {},
"source": [
"## Tmux"
"## Terminal history"
]
},
{
"cell_type": "markdown",
"id": "723ba859",
"metadata": {},
"source": [
"The most cross platfrom way is to use tmux"
]
},
{
Expand Down Expand Up @@ -435,14 +458,69 @@
"outputs": [],
"source": [
"#| export\n",
"def get_history(n, pid='current'):\n",
"def get_hist_tmux(n, pid='current'):\n",
" if not os.environ.get('TMUX'): return None\n",
" try:\n",
" if pid=='current': return get_pane(n)\n",
" if pid=='all': return get_panes(n)\n",
" return get_pane(n, pid)\n",
" except subprocess.CalledProcessError: return None"
]
},
{
"cell_type": "markdown",
"id": "6a05b3f9",
"metadata": {},
"source": [
"We can also use the terminal app's API to get the history. Here is how to do it for Apple Terminal and iTerm.app.\n",
"\n",
"Due to macOS sandboxing, osascript can only script the terminal app it was executed from and cannot access other terminal apps. So, the easiest way to test this is to run these commands manually in the terminal:\n",
"\n",
"```bash\n",
"osascript -e 'tell application \"Terminal\" to get the contents of the selected tab of the front window'\n",
"osascript -e 'tell application id \"com.googlecode.iterm2\" to get text of current session of current tab of current window'\n",
"```"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "0eda0216",
"metadata": {},
"outputs": [],
"source": [
"#| export\n",
"def get_hist_osa(n, pid=''):\n",
" script = ({\n",
" 'Apple_Terminal':'tell application \"Terminal\" to get the contents of the selected tab of the front window',\n",
" 'iTerm.app':'tell application id \"com.googlecode.iterm2\" to get text of current session of current tab of current window',\n",
" }).get(os.getenv('TERM_PROGRAM'))\n",
" if not script: return None\n",
" return \"\\n\".join(co(['osascript', '-e', script], text=True).splitlines()[:n])"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "e6e9b4b5",
"metadata": {},
"outputs": [],
"source": [
"#get_hist_osa(3)"
]
},
{
"cell_type": "code",
"execution_count": null,
"id": "5344a2bd",
"metadata": {},
"outputs": [],
"source": [
"#| export\n",
"def get_history(n, pid='current'):\n",
" return get_hist_tmux(n, pid) or get_hist_osa(n)"
]
},
{
"cell_type": "markdown",
"id": "fc100d13",
Expand Down Expand Up @@ -930,11 +1008,10 @@
" ctxt = '' if skip_system else _sys_info()\n",
"\n",
" # Get tmux history if in a tmux session\n",
" if os.environ.get('TMUX'):\n",
" if opts.history_lines is None or opts.history_lines < 0:\n",
" opts.history_lines = tmux_history_lim()\n",
" history = get_history(opts.history_lines, pid)\n",
" if history: ctxt += f'<terminal_history>\\n{history}\\n</terminal_history>'\n",
" if opts.history_lines is None or opts.history_lines < 0:\n",
" opts.history_lines = tmux_history_lim()\n",
" history = get_history(opts.history_lines, pid)\n",
" if history: ctxt += f'<terminal_history>\\n{history}\\n</terminal_history>'\n",
"\n",
" # Read from redirect stdin if available\n",
" if not sys.stdin.isatty() and not IN_NOTEBOOK:\n",
Expand Down
2 changes: 2 additions & 0 deletions shell_sage/_modidx.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@
'shell_sage.core._sys_info': ('core.html#_sys_info', 'shell_sage/core.py'),
'shell_sage.core.extract': ('core.html#extract', 'shell_sage/core.py'),
'shell_sage.core.extract_cf': ('core.html#extract_cf', 'shell_sage/core.py'),
'shell_sage.core.get_hist_osa': ('core.html#get_hist_osa', 'shell_sage/core.py'),
'shell_sage.core.get_hist_tmux': ('core.html#get_hist_tmux', 'shell_sage/core.py'),
'shell_sage.core.get_history': ('core.html#get_history', 'shell_sage/core.py'),
'shell_sage.core.get_opts': ('core.html#get_opts', 'shell_sage/core.py'),
'shell_sage.core.get_pane': ('core.html#get_pane', 'shell_sage/core.py'),
Expand Down
29 changes: 21 additions & 8 deletions shell_sage/core.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@

# %% auto #0
__all__ = ['console', 'print', 'sp', 'ssp', 'default_cfg', 'tools', 'sps', 'log_path', 'get_pane', 'get_panes',
'tmux_history_lim', 'get_history', 'get_opts', 'with_permission', 'get_sage', 'get_res', 'Log', 'mk_db',
'main', 'extract_cf', 'extract']
'tmux_history_lim', 'get_hist_tmux', 'get_hist_osa', 'get_history', 'get_opts', 'with_permission',
'get_sage', 'get_res', 'Log', 'mk_db', 'main', 'extract_cf', 'extract']

# %% ../nbs/00_core.ipynb #d7c5634a
from contextlib import contextmanager
Expand Down Expand Up @@ -162,13 +162,27 @@ def tmux_history_lim():


# %% ../nbs/00_core.ipynb #0d70591e
def get_history(n, pid='current'):
def get_hist_tmux(n, pid='current'):
if not os.environ.get('TMUX'): return None
try:
if pid=='current': return get_pane(n)
if pid=='all': return get_panes(n)
return get_pane(n, pid)
except subprocess.CalledProcessError: return None

# %% ../nbs/00_core.ipynb #0eda0216
def get_hist_osa(n, pid=''):
script = ({
'Apple_Terminal':'tell application "Terminal" to get the contents of the selected tab of the front window',
'iTerm.app':'tell application id "com.googlecode.iterm2" to get text of current session of current tab of current window',
}).get(os.getenv('TERM_PROGRAM'))
if not script: return None
return "\n".join(co(['osascript', '-e', script], text=True).splitlines()[:n])

# %% ../nbs/00_core.ipynb #5344a2bd
def get_history(n, pid='current'):
return get_hist_tmux(n, pid) or get_hist_osa(n)

# %% ../nbs/00_core.ipynb #0dcbb503
default_cfg = asdict(ShellSageConfig())
def get_opts(**opts):
Expand Down Expand Up @@ -295,11 +309,10 @@ async def main(
ctxt = '' if skip_system else _sys_info()

# Get tmux history if in a tmux session
if os.environ.get('TMUX'):
if opts.history_lines is None or opts.history_lines < 0:
opts.history_lines = tmux_history_lim()
history = get_history(opts.history_lines, pid)
if history: ctxt += f'<terminal_history>\n{history}\n</terminal_history>'
if opts.history_lines is None or opts.history_lines < 0:
opts.history_lines = tmux_history_lim()
history = get_history(opts.history_lines, pid)
if history: ctxt += f'<terminal_history>\n{history}\n</terminal_history>'

# Read from redirect stdin if available
if not sys.stdin.isatty() and not IN_NOTEBOOK:
Expand Down