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.

Workspace Sessions

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.

Scope

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 session with 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] --workspace or .save session [name] --global saves the session into the given scope and moves the live session there, so every subsequent save, auto-save, and .fork follows 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.

Listing and completion

  • .list sessions shows one row per session file with its scope; a global session hidden behind a workspace twin is marked shadowed.
  • --list-sessions (CLI) prints the merged, de-duplicated names across both scopes, one per line.
  • Tab completion for .session, .agent <name>, and the --session CLI flag offers sessions from both scopes, labeled workspace or global. Completion for .save session offers the --workspace and --global flags.
  • .delete session lists both copies of a twin separately (<name> (workspace) / <name> (global)) so you can pick exactly which file to remove.

Things to keep in mind

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 .gitignore if 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 session always tells you which scope the active session came from.

Usage

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.

Persistent Session Example

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.

Auto-Saved Sessions

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.

How Auto-Save Works

When you exit a temporary session with save_session: true, Coyote:

  1. Saves the session to a _/ subdirectory inside the sessions directory (e.g., ~/.config/coyote/sessions/_/).
  2. Generates a timestamped filename in the format YYYYMMDDTHHmmSS (e.g., 20260508T120838).
  3. 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.

Auto-Naming

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.

Finding Auto-Saved Sessions

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.

One-Time Save Override

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.

Save Behavior Summary

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

Configuration

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.
  • If true, then any time you're in a session, changes will auto-save unless explicitly defined otherwise.
  • If false, then any time you're in a session, changes will not auto-save unless explicitly specified otherwise.
  • If null, Coyote will always prompt the user for what to do.
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.

Per-Session Settings

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.

Mid-Stream Interruption

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:

  1. The model begins generating a response.
  2. You press Ctrl+C. The stream stops and Coyote prints Response interrupted.
  3. The partial response is saved to the session history.
  4. 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+C functions 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.

Error Recovery

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 .recover is available afterward. This is also the time when users can inject additional prompts or context to long-running prompts.

⚠️ **GitHub.com Fallback** ⚠️