-
-
Couldn't load subscription status.
- Fork 26
Add live transcript auto-save to .agents/transcripts/ #97
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
273d9bd to
65508bc
Compare
|
Another benefit of doing something like this is that the buffers start to get laggy around 1M, and I'd like to have something like (add-hook 'agent-shell-mode-hook
(lambda ()
(setq-local comint-buffer-maximum-size 50000)
(add-hook 'comint-output-filter-functions 'comint-truncate-buffer nil t)))In my personal config to keep the buffers manageable, and be able to look up the history if desired. Perhaps I should open the that as a separate issue though. |
|
Thanks for the PR. Sorry, not had a chance to review. May need a little time...
1M characters? Something else? Could you please file a bug about this with more details? Bonus points if you investigate your laggy case. I spent some time recently chasing optimizations after a friend mentioned laggy buffers for codex agent. These helped, but I'm sure we can optimize elsewhere. Also, when reproducing the laggy scenario, make sure you update to the latest acp.el and logging is turned off (including saving any traffic), via M-x agent-shell-toggle-logging. Older acp.el versions saved traffic regardless. Btw, you prolly already know this (and not a solution), but the "clear" command wipes the content of the buffer but doesn't wipe agent history. Also, the markdown-overlay implementation is super expensive, specially for code blocks. If you comment out all of the |
|
1M characters, yes.
Ah, I didn't know this. I thought it was like /clear in claude, which does clear the agents context window. tbh, probably clear should mean to clear the context window ? I don't see a method in ACP for this though.
btw, looked more at ACP, and it does support restoring sessions: https://agentclientprotocol.com/protocol/session-setup#loading-sessions |
We're getting the "clear" command from "shell-maker" which merely clears shell content. I'm in two minds about also making it clear the agent. The convention seems to be that / is needed to operate on agent, though I can see how what we have today is confusing.
While it's in the protocol, not all agents seem to support it. I've added a display of agent capabilities to surface these details more prominently
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks for the PR. Here are some initial comments to get things going...
agent-shell.el
Outdated
| :type '(repeat string) | ||
| :group 'agent-shell) | ||
|
|
||
| (defcustom agent-shell-auto-save-transcript t |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Before opening the feature up for customizations, I'd like to give it some time to settle. This gives us time to use it, get a feel for it, and tweak without necessarily breaking users (if we decide to change settings around). Also gives us an opportunity to figure out how to reconcile this feature with the transcript feature in shell-maker (we need to turn that off, for example).
I'd say let's drop agent-shell-auto-save-transcript (we default to autosave) and agent-shell-transcript-directory for now. Let's rename agent-shell-transcript-filename-function to agent-shell--transcript-file-path-function (also private defvar).
For now if anyone would like to disable things, set agent-shell--transcript-file-path-function to nil.
This private var/function can take care of not just creating the file name but the entire path to write to.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For now if anyone would like to disable things, set agent-shell--transcript-file-path-function to nil.
On second thought, can we make this nil by default and create an internal function we can set it to for the time being? This gives us the opportunity to override ourselves and use it for a bit of time before we roll it out to others.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Makes sense to me!
Not for this PR, but we should consider iterating on log format later on. For example, we can maybe consider saving as .md. An upside is that opening in Emacs itself automatically gives us the ability to collapse and expand bits. |
- Remove customization variables (agent-shell-auto-save-transcript,
agent-shell-transcript-directory, agent-shell-transcript-filename-function)
- Create private agent-shell--transcript-file-path-function (nil by default)
- Add agent-shell--default-transcript-file-path internal function
- Change directory path from .agents/transcripts to .agent-shell/transcripts
- Add agent name to transcript header
- Refactor agent-shell--append-transcript to use :file-path keyword arg
- Create agent-shell--make-transcript-tool-call-entry helper function
- Group all transcript functions under ;;; Transcript section
Transcripts are now disabled by default for testing before rollout.
Set agent-shell--transcript-file-path-function to enable.
(with-eval-after-load 'agent-shell
(setq agent-shell--transcript-file-path-function
#'agent-shell--default-transcript-file-path))
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
|
Thanks for the feedback. Made the changes. Also, since it was a quick change, swapped from .txt to .md. Agreed that it makes sense to iterate on the log format. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thank you for the changes. LGTM, though looks like it needs to update to the latest to resove conflicts.
Added some minor comments. Mind addressing those when you resolve the conflicts?
Changes: - Use when-let* to flatten nested conditionals in init-transcript - Convert escaped newlines to actual multi-line strings for readability - Remove emojis from headers (User/Agent instead of 👤/🤖) - Remove redundant with-current-buffer wrappers (ACP callbacks run in buffer) - Inline variables in tool call logging (more concise) - Remove internal testing note from docstring - Simplify docstrings where appropriate All transcript code remains in the ;;; Transcript section for organization. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Implements automatic transcript saving that captures complete conversation
history including user prompts, agent responses, and tool executions.
Features:
- Enabled by default, saves to .agents/transcripts/{timestamp}.txt
- Captures all three conversation elements:
* User prompts with timestamps
* Agent responses (streamed chunks)
* Tool calls (when completed/failed) with output
- Configurable directory and filename generation
Configuration:
- agent-shell-auto-save-transcript (t by default, set to nil to disable)
- agent-shell-transcript-directory (".agents/transcripts")
- agent-shell-transcript-filename-function (timestamp generator)
This is separate from shell-maker's manual save functionality - this
auto-saves in the background for archival/debugging purposes.
Closes xenodium#63 - Auto-save transcripts without prompting
- Remove customization variables (agent-shell-auto-save-transcript,
agent-shell-transcript-directory, agent-shell-transcript-filename-function)
- Create private agent-shell--transcript-file-path-function (nil by default)
- Add agent-shell--default-transcript-file-path internal function
- Change directory path from .agents/transcripts to .agent-shell/transcripts
- Add agent name to transcript header
- Refactor agent-shell--append-transcript to use :file-path keyword arg
- Create agent-shell--make-transcript-tool-call-entry helper function
- Group all transcript functions under ;;; Transcript section
Transcripts are now disabled by default for testing before rollout.
Set agent-shell--transcript-file-path-function to enable.
(with-eval-after-load 'agent-shell
(setq agent-shell--transcript-file-path-function
#'agent-shell--default-transcript-file-path))
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude <noreply@anthropic.com>
Bug: After the first agent response, subsequent responses were missing the [timestamp] AGENT: header in transcripts. Root cause: :last-entry-type was not reset when a new user prompt was sent, causing the agent_message_chunk handler to skip writing the header for subsequent responses. Fix: Reset :last-entry-type to nil at the start of agent-shell--send-command to ensure each new conversation turn starts with a clean state. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Changes: - Change file extension from .txt to .md - Use markdown header (#) for transcript title - Use markdown metadata (bold text) for agent, timestamp, and directory - Use ## headers with emoji for user (👤) and agent (🤖) messages - Use <details>/<summary> collapsible sections for tool calls - Format tool call output in code blocks with backticks - Add horizontal rule (---) after header Benefits: - Better readability when viewed in editors or GitHub - Collapsible tool call sections reduce clutter - Syntax highlighting for code outputs - Native markdown rendering in most tools 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
Changes: - Use when-let* to flatten nested conditionals in init-transcript - Convert escaped newlines to actual multi-line strings for readability - Remove emojis from headers (User/Agent instead of 👤/🤖) - Remove redundant with-current-buffer wrappers (ACP callbacks run in buffer) - Inline variables in tool call logging (more concise) - Remove internal testing note from docstring - Simplify docstrings where appropriate All transcript code remains in the ;;; Transcript section for organization. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
fdd7855 to
3ec6843
Compare
|
Hi @ElleNajt I got notification of some commits addressing comments. Thank you! Are you finished with the changes? If so, I'll look into merging. |
|
Hi -- yes, finished with the changes! :) |

This PR implements automatic transcript saving that captures complete conversation history for archival purposes.
Features
Auto-saves transcripts as conversations progress:
Enabled by default - transcripts save to
.agents/transcripts/{timestamp}.txtNote on format: Transcripts are optimized for human readability (timestamped, formatted text). [Edit: This next sentence is wrong - ACP does support restoring sessions] While ACP doesn't currently support restoring sessions, a future enhancement could add a parallel machine-readable format for session restoration.
Configurable:
Relationship to shell-maker
This is separate from shell-maker's manual save functionality:
Users can use both, either, or neither depending on their needs.
Example transcript format
Closes #63 - Auto-save transcripts without prompting