<p>Most releases teach Elyra to do something new. This one is about something softer: knowing when to ask a colleague, remembering what you worked on last week, and not writing anything into your future without asking first.</p><p>Here's what changed, why, and how to use it.</p><h2>The oracle: a second pair of eyes</h2><h3>Why</h3><p>Every developer knows the moment. You've tried the fix twice, the test still fails one run in ten, and you're starting to go in circles. A good engineer doesn't keep circling. They turn their chair around and say, "Hey, can you take a look at this?"</p><p>Agents get stuck in the same loops, and until now Elyra had nobody to turn to. The <code>@elyracode/subagents</code> extension had an oracle, but you had to install it and ask for it explicitly.</p><p>In 0.9.54 the oracle is built in and on by default.</p><h3>How it works</h3><p>The oracle is a tool the agent can call. It makes one call to a second model with high reasoning, with no tools and no view of your conversation. That last part is deliberate. The agent has to explain the problem precisely: the goal, what it tried, what happened, and which files matter. Half the time, writing a good question is what solves the problem, and the oracle gets a clean slate instead of inheriting the agent's assumptions.</p><h3>Which model does it ask?</h3><ol><li><p><code>oracle.model</code>, if you've set one</p></li><li><p>Your smart routing powerful tier (Opus 5.5 by default), if that's a different model from the one you're running</p></li><li><p>The closest-matched model from another provider</p></li><li><p>Your current model, as a last resort</p></li></ol><p>So if you're working with Sonnet, the oracle is Opus. If you're already on Opus, it reaches for another provider. One honest caveat: a gateway like OpenRouter counts as "another provider", so it could pick the same model family through a different door. If you want a guaranteed different perspective, pin it:</p><pre><code class="language-json">{
  "oracle": { "model": "openai/gpt-6.1-sol" }
}
</code></pre><h3>What it looks like</h3><p>You can ask for it directly:</p><pre><code class="language-text">&gt; The checkout test is flaky. Ask the oracle what we're missing.

oracle Why does checkout.test.ts fail roughly 1 in 10 runs? (2 files)
anthropic/claude-opus-5-5 • $0.041
  The test and the webhook handler both write to the same order row.
  The handler's update can land after the assertion reads it...
</code></pre><p>The agent also calls it on its own when it's stuck after a couple of failed attempts, or before a risky change. It's told plainly not to use it for routine work, since the oracle is slower and costs more.</p><p>Speaking of cost: the oracle's spend is counted in <code>/cost</code>, the footer, <code>/goal --budget</code>, and the <code>Elyra-Cost</code> commit trailer. No hidden line items.</p><p>Don't want it? Set <code>"oracle": { "enabled": false }</code>.</p><h2>Sessions that remember each other</h2><h3>Why</h3><p>Here's a conversation every agent user has had:</p><blockquote><p><strong>You:</strong> Do the same thing we did for the login redirect last week.</p><p><strong>Agent:</strong> I don't have access to previous conversations. Could you describe what was done?</p></blockquote><p>Your sessions are sitting right there in <code>~/.elyra/agent/sessions/</code>. The agent just couldn't see them.</p><h3>How it works</h3><p>Two new tools, both on by default:</p><ul><li><p><code>find_sessions</code> searches earlier sessions in this project (or all projects) using the same query syntax as <code>/resume</code>: fuzzy words, <code>"exact phrases"</code>, or <code>re:</code> regex.</p></li><li><p><code>read_session</code> opens one session and has a model pull out what the current task needs: decisions, files, commands, and what was left unfinished. You get a focused summary, not a 40,000-token transcript dumped into your context. It uses your fast tier (Haiku by default) to keep this cheap.</p></li></ul><p>The friendliest way to use it is the new <code>@@</code> in the editor. Type it, start typing a few words, and pick a session from the list:</p><pre><code class="language-text">&gt; Apply the fix from @session:0198c3a2-7f1e-7b4a-9c2d-5e8f1a3b6c7d to the signup form
</code></pre><p>The agent sees the mention, reads that session, and gets to work. No re-explaining.</p><p>You can also just describe it:</p><pre><code class="language-text">&gt; What did we decide about the queue worker setup?

find sessions queue worker
read session 0198bbbb "the queue worker configuration and why"
  Session 0198bbbb "Queue setup" (/work/shop, 14 messages):
  Horizon with 3 workers on the default queue; the payments queue
  got its own supervisor after timeouts on Stripe webhooks...
</code></pre><h3>Commits that lead home</h3><p>Every commit the agent makes now carries a second trailer:</p><pre><code class="language-text">feat: add retry to the payment client

Elyra-Cost: $0.42 (claude-opus-5-5, 4 turns)
Elyra-Session: 0198c3a2-7f1e-7b4a-9c2d-5e8f1a3b6c7d
</code></pre><p>Six months from now, when you're staring at a strange line in <code>git blame</code>, you can open the conversation that produced it:</p><pre><code class="language-bash">elyra --session 0198c3a2
</code></pre><p>A prefix is enough, and it works from any project. The agent can follow that trail too: point it at a commit and it can read the session behind it. Turn it off with <code>gitSessionTrailer: false</code>. Ephemeral sessions (<code>--no-session</code>) skip it automatically.</p><h2>/handoff: a fresh start that keeps what matters</h2><h3>Why</h3><p>Long sessions get heavy. <code>/compact</code> helps, but it summarizes everything and keeps working in the same session. Sometimes what you really want is a clean slate for the next task, carrying only the parts of the past that the task needs.</p><h3>How it works</h3><pre><code class="language-text">&gt; /handoff now implement the same permission checks for teams
</code></pre><p>The model reads your conversation and writes a self-contained first prompt for a new session:</p><pre><code class="language-markdown">## Context
We added role-based permission checks to the project API.
Key decisions:
- Policies live in src/policies/, one per resource
- Checks happen in middleware, not controllers

Files involved:
- src/policies/ProjectPolicy.ts
- src/middleware/authorize.ts

## Task
Implement the same permission checks for teams...
</code></pre><p>That prompt lands in the editor of a brand-new session. Read it, tweak it, press Enter. The old session stays as it was and is recorded as the parent. Press Esc while it's generating if you change your mind.</p><h2>The tools that were quietly sleeping</h2><p>This one is a little embarrassing, so let's just say it.</p><p><code>skill_write</code>, <code>extension_write</code>, and <code>decision_record</code> (the tools that let the agent save a skill, give itself a new tool, or record an architecture decision) have shipped for months. The changelog described them. The system prompt had guidance for them. But they were never in the active tool set. They were registered and never switched on. The agent couldn't use them.</p><p>They're on now.</p><p>While fixing that, we found something more important. All three ask for your approval first, but if there was no interactive UI (print mode with <code>-p</code>, or MCP server mode), the approval step quietly said "yes". With the tools active, that would have meant an agent driven by a script or by an outer MCP host could write an extension, which is TypeScript that runs in every future session, without any human ever seeing it.</p><p>So the rule is now simple: <strong>if approval is required and nobody is there to give it, nothing is written.</strong> The agent is told why and which setting allows it:</p><pre><code class="language-text">Extension "jira-tools" was not saved: saving needs the user's approval
and this mode has no interactive UI. The user can set autoExtensions: true
to save without approval.
</code></pre><p>Interactive mode works as before: you get a dialog. If you want headless automation to save skills or decisions, opt in explicitly with <code>autoSkills</code>, <code>autoExtensions</code>, or <code>decisionLog: "auto"</code>.</p><h2>Small things you'll appreciate</h2><h3>Shell completions</h3><p>Tab completion for subcommands, flags, and values like <code>--provider</code>, <code>--thinking</code>, and <code>--mode</code>:</p><pre><code class="language-bash">source &lt;(elyra completions zsh)      # ~/.zshrc, after compinit
source &lt;(elyra completions bash)     # ~/.bashrc
elyra completions fish | source      # fish config
</code></pre><p>The script is generated from your installed version, and pressing Tab never starts Elyra.</p><h3>For extension authors</h3><p>A <code>tool_call</code> handler can now answer a call without running the tool. Useful for cache hits, dry runs, or policy answers:</p><pre><code class="language-ts">elyra.on("tool_call", (event) =&gt; {
  if (isToolCallEventType("bash", event) &amp;&amp; event.input.command.startsWith("terraform apply")) {
    return {
      result: {
        content: [{ type: "text", text: "Dry run only here. Use terraform plan." }],
      },
    };
  }
});
</code></pre><p>A tool that calls a model can return <code>details.modelUsage</code>, and Elyra counts that cost everywhere spend is shown.</p><h2>One thing to know when upgrading</h2><p>The default tool set grew from four tools to ten. That changes the tool list sent to your provider once, so your first request after upgrading misses the prompt cache. After that, the cache works as usual.</p><h2>Try it</h2><pre><code class="language-bash">elyra update
</code></pre><p>Then, in your next session:</p><ol><li><p>Type <code>@@</code> and mention something you worked on last week</p></li><li><p>Ask the oracle about the bug that's been bothering you</p></li><li><p>Run <code>/handoff</code> when the session starts feeling heavy</p></li></ol><p>None of this makes the agent smarter on its own. It makes it a better colleague: one that asks for help, remembers what you did together, and doesn't write anything into your future without asking.</p><p>Happy building. 🌿</p><p>— The Elyra team</p>