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
1 change: 1 addition & 0 deletions .github/actions/spelling/expect/expect.txt
Original file line number Diff line number Diff line change
Expand Up @@ -1106,6 +1106,7 @@ nonspace
NOOWNERZORDER
NOPAINT
noprofile
norc
NOREDRAW
NOREMOVE
NOREPOSITION
Expand Down
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,8 +159,15 @@ Inside the agent pane, type `/` to see available commands. Type `/help` at any t
| `/restart` | Restart the agent with a clean session |
| `/stop` | Cancel the in-flight prompt |
| `/sessions` | Open agent management (same as <kbd>Ctrl+Shift+/</kbd>) |
| `/agent [id]` | Pick the agent source for this tab. In a WSL pane, the picker includes agents installed on Windows and in that pane's WSL distro; it never offers other distros. |
| `/model [id]` | Pick the model for this pane; bare `/model` opens a picker, `/model <id>` switches directly |

Profiles use the global Windows-hosted agent by default. In a profile's
**General** settings, **Agent pane agent** can instead select an ACP agent
installed in that profile's WSL distro. The picker only lists the Windows host
and that one distro. An explicit profile selection is strict: if that agent
cannot start, the pane reports the failure without switching to another agent.

### Agent Management

<p align="center">
Expand Down
8 changes: 8 additions & 0 deletions doc/cascadia/profiles.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -3195,6 +3195,14 @@
"null"
]
},
"agentPaneBackend": {
"description": "Selects an optional profile-specific agent pane agent. An empty value uses the global Windows-hosted agent. WSL values identify an agent installed in the profile's own distro.",
"type": [
"string",
"null"
],
"pattern": "^(|host:[^:]+|wsl:[^:]+:[^:]+)$"
},
"suppressApplicationTitle": {
"description": "When set to true, tabTitle overrides the default title of the tab and any title change messages from the application will be suppressed. When set to false, tabTitle behaves as normal.",
"type": "boolean",
Expand Down
9 changes: 8 additions & 1 deletion src/cascadia/TerminalApp/AgentPaneContent.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -83,13 +83,15 @@ namespace winrt::TerminalApp::implementation
void AgentPaneContent::UpdateAgentStatus(const winrt::hstring& name,
const winrt::hstring& version,
const winrt::hstring& model,
const winrt::hstring& state)
const winrt::hstring& state,
const winrt::hstring& backend)
{
const bool nameChanged = _agentName != name;
_agentName = name;
_agentVersion = version;
_agentModel = model;
_agentState = state;
_agentBackend = backend;
_refreshLabel();
if (nameChanged)
{
Expand Down Expand Up @@ -231,6 +233,11 @@ namespace winrt::TerminalApp::implementation
else
{
text = std::wstring{ _agentName };
if (!_agentBackend.empty())
{
text += L" \u00B7 ";
text += _agentBackend;
}
if (!_agentVersion.empty())
{
text += L" ";
Expand Down
14 changes: 13 additions & 1 deletion src/cascadia/TerminalApp/AgentPaneContent.h
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

#pragma once

#include <optional>

#include "AgentPaneContent.g.h"
#include "TerminalPaneContent.h"
#include "BasicPaneEvents.h"
Expand All @@ -20,7 +22,8 @@ namespace winrt::TerminalApp::implementation
void UpdateAgentStatus(const winrt::hstring& name,
const winrt::hstring& version,
const winrt::hstring& model,
const winrt::hstring& state);
const winrt::hstring& state,
const winrt::hstring& backend);

void SetSessionsView(bool active);
// Whether the agent pane is currently displaying its sessions view
Expand Down Expand Up @@ -78,6 +81,13 @@ namespace winrt::TerminalApp::implementation
_pendingRenameFromTabId = {};
return v;
}
void SetPendingAgentSourceProfileGuid(const std::optional<winrt::guid>& value) noexcept { _pendingAgentSourceProfileGuid = value; }
std::optional<winrt::guid> TakePendingAgentSourceProfileGuid() noexcept
{
const auto value = _pendingAgentSourceProfileGuid;
_pendingAgentSourceProfileGuid.reset();
return value;
}

// Apply the provided background and foreground brushes to the
// agent-pane top bar (#348). Internal-only (not on IDL).
Expand Down Expand Up @@ -137,6 +147,7 @@ namespace winrt::TerminalApp::implementation
winrt::hstring _agentVersion{};
winrt::hstring _agentModel{};
winrt::hstring _agentState{};
winrt::hstring _agentBackend{};

// When true, the bar replaces "<agent> <version>" with "Agent sessions"
// and hides the agent logo. Driven by TerminalPage::OnAgentStateChanged
Expand All @@ -159,6 +170,7 @@ namespace winrt::TerminalApp::implementation
// post-Tab-construction in `_InitializeTab`). Empty when no rename
// is pending. See SetPendingRenameFromTabId / TakePendingRenameFromTabId.
winrt::hstring _pendingRenameFromTabId{};
std::optional<winrt::guid> _pendingAgentSourceProfileGuid;

// Inner content event tokens — forwarded to our own BasicPaneEvents.
winrt::event_token _innerCloseRequested{};
Expand Down
2 changes: 1 addition & 1 deletion src/cascadia/TerminalApp/AgentPaneContent.idl
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ namespace TerminalApp

// Pushed in from outside when wta emits an `agent_status` event.
// state is one of "connecting" | "connected" | "failed" | "disconnected".
void UpdateAgentStatus(String name, String version, String model, String state);
void UpdateAgentStatus(String name, String version, String model, String state, String backend);

// Toggle the bar's "agent name + version" header into a "Agent sessions"
// label (and hide the agent logo) while wta's session management view is
Expand Down
27 changes: 21 additions & 6 deletions src/cascadia/TerminalApp/AgentPaneDragStash.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

#include <cstdint>
#include <mutex>
#include <optional>
#include <string>
#include <unordered_map>

Expand Down Expand Up @@ -52,17 +53,30 @@ namespace winrt::TerminalApp::implementation
// WindowsTerminal.exe, so a static inside it is process-wide.
struct AgentPaneDragStash
{
static void Stash(uint64_t contentId, const winrt::hstring& originalTabId) noexcept
struct Entry
{
std::wstring originalTabId;
std::optional<winrt::guid> sourceProfileGuid;
};

static void Stash(uint64_t contentId,
const winrt::hstring& originalTabId,
const std::optional<winrt::guid>& sourceProfileGuid) noexcept
{
if (contentId == 0)
{
return;
}
std::lock_guard lock{ _Mutex() };
_Map()[contentId] = std::wstring{ originalTabId };
_Map()[contentId] = Entry{
std::wstring{ originalTabId },
sourceProfileGuid,
};
}

static bool Take(uint64_t contentId, winrt::hstring& outOriginalTabId) noexcept
static bool Take(uint64_t contentId,
winrt::hstring& outOriginalTabId,
std::optional<winrt::guid>& outSourceProfileGuid) noexcept
{
if (contentId == 0)
{
Expand All @@ -75,7 +89,8 @@ namespace winrt::TerminalApp::implementation
{
return false;
}
outOriginalTabId = winrt::hstring{ it->second };
outOriginalTabId = winrt::hstring{ it->second.originalTabId };
outSourceProfileGuid = it->second.sourceProfileGuid;
map.erase(it);
return true;
}
Expand All @@ -87,9 +102,9 @@ namespace winrt::TerminalApp::implementation
return m;
}

static std::unordered_map<uint64_t, std::wstring>& _Map() noexcept
static std::unordered_map<uint64_t, Entry>& _Map() noexcept
{
static std::unordered_map<uint64_t, std::wstring> map;
static std::unordered_map<uint64_t, Entry> map;
return map;
}
};
Expand Down
8 changes: 6 additions & 2 deletions src/cascadia/TerminalApp/Tab.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -590,7 +590,8 @@ namespace winrt::TerminalApp::implementation
if (kind == BuildStartupKind::Content && _rootPane)
{
const auto& myStableId = _stableId;
_rootPane->WalkTree([&myStableId](const auto& p) {
const auto sourceProfileGuid = _agentSourceProfileGuid;
_rootPane->WalkTree([&myStableId, &sourceProfileGuid](const auto& p) {
if (!p->_IsLeaf())
{
return false;
Expand Down Expand Up @@ -618,7 +619,10 @@ namespace winrt::TerminalApp::implementation
{
return false;
}
winrt::TerminalApp::implementation::AgentPaneDragStash::Stash(cid, myStableId);
winrt::TerminalApp::implementation::AgentPaneDragStash::Stash(
cid,
myStableId,
sourceProfileGuid);
return false;
});
}
Expand Down
15 changes: 14 additions & 1 deletion src/cascadia/TerminalApp/Tab.h
Original file line number Diff line number Diff line change
Expand Up @@ -138,20 +138,30 @@ namespace winrt::TerminalApp::implementation
const winrt::hstring& AgentIdOverride() const noexcept { return _agentIdOverride; }
const winrt::hstring& AgentModelOverride() const noexcept { return _agentModelOverride; }
const winrt::hstring& AgentCustomCommandOverride() const noexcept { return _agentCustomCommandOverride; }
const winrt::hstring& AgentSourceOverride() const noexcept { return _agentSourceOverride; }
const winrt::hstring& AgentWslDistroOverride() const noexcept { return _agentWslDistroOverride; }
std::optional<winrt::guid> AgentSourceProfileGuid() const noexcept { return _agentSourceProfileGuid; }
void AgentSourceProfileGuid(const winrt::guid& value) noexcept { _agentSourceProfileGuid = value; }
bool HasAgentOverride() const noexcept { return !_agentIdOverride.empty(); }
void SetAgentOverride(const winrt::hstring& agentId,
const winrt::hstring& model,
const winrt::hstring& customCommand)
const winrt::hstring& customCommand,
const winrt::hstring& source = L"host",
const winrt::hstring& wslDistro = {})
{
_agentIdOverride = agentId;
_agentModelOverride = model;
_agentCustomCommandOverride = customCommand;
_agentSourceOverride = source;
_agentWslDistroOverride = wslDistro;
}
void ClearAgentOverride() noexcept
{
_agentIdOverride = {};
_agentModelOverride = {};
_agentCustomCommandOverride = {};
_agentSourceOverride = {};
_agentWslDistroOverride = {};
}

// Stable per-tab identifier (GUID string). Survives tab reordering
Expand Down Expand Up @@ -243,6 +253,9 @@ namespace winrt::TerminalApp::implementation
winrt::hstring _agentIdOverride{};
winrt::hstring _agentModelOverride{};
winrt::hstring _agentCustomCommandOverride{};
winrt::hstring _agentSourceOverride{};
winrt::hstring _agentWslDistroOverride{};
std::optional<winrt::guid> _agentSourceProfileGuid;

winrt::Microsoft::Terminal::Settings::Model::IconStyle _lastIconStyle;
winrt::hstring _lastIconPath{};
Expand Down
4 changes: 4 additions & 0 deletions src/cascadia/TerminalApp/TabManagement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -306,6 +306,10 @@ namespace winrt::TerminalApp::implementation
}
self->_WireAgentPaneEvents(content, tabImplCom);

if (const auto sourceProfileGuid = impl->TakePendingAgentSourceProfileGuid())
{
tabImplCom->AgentSourceProfileGuid(*sourceProfileGuid);
}
const auto oldTabId = impl->TakePendingRenameFromTabId();
if (oldTabId.empty() || oldTabId == newTabId)
{
Expand Down
Loading
Loading