Sessions - Dark-Alex-17/coyote GitHub Wiki
By default, Coyote does not send back all previous messages in a conversation to the model. This means that each time you
query a model, it's essentially a one-off. However, Coyote does support chat-like conversations with LLMs via its
sessions mechanism.
Sessions in Coyote enable the familiar conversational interactions with LLMs. This means you can reference previous answers and ask follow-up questions and the model will know what you're referring to.
Sessions can be temporary, or can be saved so you can continue conversations at a later time.
Sessions persist one conversation. For facts that should survive across all sessions (e.g., user preferences, project constraints, accumulated feedback), see Memory.
Saved sessions are stored in the sessions subdirectory of the Coyote configuration directory (agent sessions live
under agents/<agent-name>/sessions instead). The location of the sessions directory varies by system, so you can
use the following command to find the sessions directory if you need it:
coyote --info | grep 'sessions_dir' | awk '{print $2}'Sessions can also be saved into the current workspace instead of the global configuration directory; see Workspace Sessions below.
In addition to the global sessions directory, Coyote reads and writes sessions local to the current working
directory, mirroring the layout of the global configuration directory under .coyote/:
<project-root>/
└── .coyote/
├── sessions/
│ └── <name>.yaml # workspace session (no agent)
└── agents/
└── <agent-name>/
└── sessions/
└── <name>.yaml # workspace session for that agent
This works the same way as workspace-local MCP servers,
skills, and macros: the workspace is the current working
directory (Coyote does not walk up to a git root), and the .coyote/ directory name follows
COYOTE_WORKSPACE_CONFIG_DIR (see Environment Variables). The COYOTE_SESSIONS_DIR override
only affects the global sessions directory.
Every session has a scope: global or workspace. The scope is recorded when a session is loaded and is shown as
the scope line of .info session. It is not written into the session file itself; the file format is identical in
both locations.
-
Loading (
.session <name>,--session <name>,.agent <name> <session>): if<name>exists in the workspace, the workspace copy is loaded and shadows any global session of the same name. Otherwise the global copy is loaded. A name that exists nowhere creates a new global session. -
Saving:
.save sessionwith no flag re-saves the session wherever it currently lives. The same is true of auto-save on exit (save_session: true), so a workspace session stays in the workspace for its whole lifetime. -
Re-homing:
.save session [name] --workspaceor.save session [name] --globalsaves the session into the given scope and moves the live session there, so every subsequent save, auto-save, and.forkfollows the new scope. The file in the old scope is left in place. If the file you just saved is shadowed by a same-named session in the other scope, Coyote prints a warning telling you which copy.session <name>will load. -
Forking:
.fork [name]creates the fork in the same scope as the session being forked. Fork names must be unused in both scopes. -
Temporary sessions are always global. To keep one in the workspace, name it first:
.save session <name> --workspace.
-
.list sessionsshows one row per session file with itsscope; a global session hidden behind a workspace twin is markedshadowed. -
--list-sessions(CLI) prints the merged, de-duplicated names across both scopes, one per line. -
Tab completion for
.session,.agent <name>, and the--sessionCLI flag offers sessions from both scopes, labeledworkspaceorglobal. Completion for.save sessionoffers the--workspaceand--globalflags. -
.delete sessionlists both copies of a twin separately (<name> (workspace)/<name> (global)) so you can pick exactly which file to remove.
Workspace sessions live inside your working directory. A session file contains the full conversation, including tool output and any data you pasted. Coyote does not modify your
.gitignoreif you're in a git repository; add.coyote/sessions/(and.coyote/agents/*/sessions/) yourself if the project is shared.
Session names come from the repository when the working directory is a git repository. Because workspace session files can be committed, a checked-out project can ship sessions that shadow your own global sessions of the same name.
.info sessionalways tells you which scope the active session came from.
When you use a session in Coyote, you can either persist it or discard it once you're done. Sessions you discard are then just considered 'temporary' sessions.

Sessions you persist and then load again later will inherit the same configuration as was used during the last usage of that session. That is to say, if you had certain tools or MCP servers enabled when you were last in that session, they will be available again when you continue that session.
When save_session is set to true and you don't provide an explicit session name (i.e., you're in a temporary
session), Coyote will automatically save your session when you exit. These auto-saved sessions behave differently from
manually saved sessions in a few important ways.
When you exit a temporary session with save_session: true, Coyote:
- Saves the session to a
_/subdirectory inside the sessions directory (e.g.,~/.config/coyote/sessions/_/). - Generates a timestamped filename in the format
YYYYMMDDTHHmmSS(e.g.,20260508T120838). - If an auto-generated name is available (see Auto-Naming below), it is appended to the timestamp
(e.g.,
20260508T120838-discuss-rust-error-handling.yaml).
For agent sessions, auto-saved sessions are stored in the agent's own session directory under _/ (e.g.,
~/.config/coyote/agents/<agent-name>/sessions/_/). For a workspace session, the _/
subdirectory is created inside the workspace sessions directory instead.
When save_session: true is set and you send your first message in a temporary session, Coyote will use the LLM to
automatically generate a short descriptive name for the session based on the initial exchange. This name is appended to
the timestamp in the filename, making it easier to identify sessions later.
You can view the auto-generated name for the current session with .info session under the autoname field.
Auto-saved sessions are stored separately from manually named sessions. This means they won't appear in the default session list:
-
--list-sessions(CLI): Does not include auto-saved sessions. -
.session+ Tab (REPL): Does not show auto-saved sessions in completions.
To access auto-saved sessions, prefix your query with _/:
-
.session _/+ Tab (REPL): Will show auto-saved sessions in completions, since Coyote looks in the_/subdirectory when it sees this prefix. Both the workspace and the global_/directories are searched, and each completion is labeled with its scope. -
.session _/<name>(REPL): Loads a specific auto-saved session. For example:.session _/20260508T120838-discuss-rust-error-handling.
When you load an auto-saved session this way, it is treated as a temporary session again, meaning the session name resets to
temp internally. If auto-naming had previously generated a name, it will be restored so that subsequent saves continue
to use it.
You can force a single session to be saved regardless of the global save_session setting by using the --save-session
CLI flag:
coyote --session --save-session "What is Rust?"This overrides the configured save_session value for that one invocation only, and the session will auto-save to the
_/ subdirectory just like it would with save_session: true.
The following table summarizes what happens when you exit a session, depending on the save_session setting and the
session type:
save_session |
Session Type | Mode | Behavior |
|---|---|---|---|
true |
Named session | Any | Auto-saves to <sessions_dir>/<name>.yaml
|
true |
Temporary (temp) |
Any | Auto-saves to <sessions_dir>/_/<timestamp>[-autoname].yaml
|
false |
Any | Any | Never saves |
null |
Any | REPL | Prompts "Save session?" (if you say yes with a temp session, you'll be asked for a name) |
null |
Any | CLI | Does not save |
Session behavior can be configured from the global Coyote configuration file. The location of this file varies between systems so you can use the following command to locate it on your system:
coyote --info | grep '^config_file' | awk '{print $2}'The following settings are available to customize the default behavior of sessions globally:
| Setting | Description |
|---|---|
save_session |
Controls the persistence of the session.
|
compression_threshold |
Defines the token count threshold at which Coyote will compress the session to save on the context length |
compression_safety_valve |
Fraction of the model's input window (default 0.8) at which compression is forced regardless of compression_threshold. Compared against the larger of Coyote's local token estimate and the prompt-token count the provider reported for the last request. Global only; agents cannot override it. |
summarization_prompt |
This is the prompt that is used to compress the session up to a given point when compression is triggered |
summary_context_prompt |
This is the prompt that's used to add the summarized conversation generated by the summarization_prompt as context to the model |
compression_keep_last |
Upper bound on the number of most recent messages kept word-for-word after compression. The kept tail always starts at a user message and is also limited by a token budget (the smaller of half the threshold and a quarter of the safety-valve limit), so fewer messages may survive. Earlier messages are folded into the summary. 0 (the default) keeps nothing. |
compression_model |
Model to use for the compression (summarization) LLM call (e.g. openai:gpt-4o-mini), letting you use a cheaper/faster model than the session's current model. If the specified model fails (unknown model, API error, or timeout), Coyote prints a warning and falls back to the session's current model. null (the default) uses the session's current model. Agents can override this per-agent via compression_model in their config.yaml. |
max_tool_result_chars |
Caps the number of characters from any single tool result forwarded to the model. Results that exceed this limit are truncated and a notice is prepended. Useful for preventing large tool outputs from consuming context. null (the default) disables the cap. |
See Session Compression for how compression works and how to tune it.
In addition to the global settings above, individual sessions can override the following settings. These can be set
at runtime using the .set command or configured in the session's YAML file:
| Setting | Default | Description |
|---|---|---|
model |
Active model at session creation | The model used for this session. Changed via .model in the REPL; persisted in the session YAML. |
temperature |
Global temperature value |
Model temperature for this session. |
top_p |
Global top_p value |
Model top-p for this session. |
reasoning_effort |
Global reasoning_effort value |
Reasoning effort level for models that support it (e.g. low, medium, high). Only valid when the active model declares reasoning_levels. |
enabled_tools |
Global enabled_tools value |
Tools enabled for this session. Accepts a comma-separated string (e.g. fs_ls,fs_cat) or all. |
enabled_mcp_servers |
Global enabled_mcp_servers value |
MCP servers enabled for this session. Accepts a comma-separated string (e.g. github,slack) or all. |
mcp_tools |
None (not inherited from the role) | Per-server MCP tool whitelists for this session, set via .set mcp_tools.<server> <patterns> and persisted in the session YAML. The role's mcp_tools map is not copied into the session; it applies as its own layer. See Restricting MCP Tools. |
auto_continue |
Global auto_continue value |
Enable the Todo System auto-continuation for this session. Overrides global and role settings. |
max_auto_continues |
Global max_auto_continues value |
Maximum number of automatic continuations before stopping. Overrides global and role settings. |
inject_todo_instructions |
Global inject_todo_instructions value |
Inject default todo tool usage instructions into the system prompt. Overrides global and role settings. |
continuation_prompt |
Global continuation_prompt value |
Custom prompt used when auto-continuing. Overrides global and role settings. |
compression_keep_last |
Global compression_keep_last value |
Upper bound on messages kept verbatim by compression. Set via .set compression_keep_last N while in a session; persisted in the session YAML. .set compression_keep_last null clears the override. |
skills_enabled |
Global skills_enabled value |
Master switch for skills in this session. .set skills_enabled null clears the session override. |
enabled_skills |
Inherited via the skill cascade | The active skills for this session. Accepts either a YAML list or a comma-separated string in the saved session YAML. |
inject_skill_instructions |
Global inject_skill_instructions value |
Whether to inject the skill-discovery hint into the session's system prompt. |
skill_instructions |
Global skill_instructions value |
Custom text for the skill-discovery hint. null to reset to the built-in default. |
For more information on the Todo System, see the Todo System documentation.
When streaming is enabled and a session is active, pressing Ctrl+C during a response interrupts the stream and preserves any text the model had already generated. The partial response is saved to the session as the model's last turn, and Coyote returns to the prompt so you can continue the conversation.
This lets you redirect the LLM mid-flight without losing the context that led up to the interruption:
- The model begins generating a response.
- You press Ctrl+C. The stream stops and Coyote prints
Response interrupted. - The partial response is saved to the session history.
- You type your next message at the normal prompt. The model sees the full conversation history, including the partial response, and your new prompt.
If you want to discard the partial response entirely rather than continuing from it, use .undo
to remove the last exchange from the session and restore your original prompt for editing or re-sending.
Requires an active session. Mid-stream interruption only preserves partial responses when a session is open. Without a session, Ctrl+C aborts the response as usual and nothing is saved to history.
Ctrl+C before the first token. If you press Ctrl+C while the spinner is still showing (before any response text has arrived), the request is aborted cleanly and nothing is saved. This is identical behavior to how
Ctrl+Cfunctions without a session.
Ctrl+D is always a hard abort. Pressing Ctrl+D during streaming discards the partial response regardless of session state and exits the REPL.
REPL only. When running Coyote as a one-shot CLI command (
coyote <prompt>), Ctrl+C aborts as usual. Mid-stream interruption is a REPL-only feature.
During long agentic sessions, errors can interrupt generation mid-chain; e.g. transient API errors (rate limits, network failures, token exhaustion, timeouts, etc). Without recovery, all the tool calls and context accumulated in the current session would be lost.
When a session is active and an error occurs during generation, Coyote automatically checkpoints the full session state, including every completed tool call and its result up to the point of failure, and marks the session as recoverable. You can then resume with:
.recover [message]
The model receives:
- The original user prompt
- All tool calls and results that completed before the error
- An
[Response interrupted due to error]marker as the last assistant turn - Your recovery message (defaults to
"Please continue from where you left off."if omitted)
How this differs from .continue: .continue is for text responses that were cut off mid-generation (e.g.,
the model hit its output token limit mid-sentence). .recover is for agentic chains that were cut off by some
error, restoring full tool call context so the model can continue the task rather than restart it.
Requires an active session. Without a session, interrupted agentic context is not preserved. If you run long multi-tool tasks, use a session to make them recoverable.
Completed turns are preserved; the interrupted turn is not. Tool calls that fully executed before the error are checkpointed. Any tool call that the model had begun streaming but not yet completed at the moment of failure is not included, meaning the model will need to re-issue it.
Ctrl+C during generation also triggers recovery. If you interrupt a streaming response with Ctrl+C while a session is active, the same checkpoint is written and
.recoveris available afterward. This is also the time when users can inject additional prompts or context to long-running prompts.