feat(agents): Show subagents as their own conversations (#132)

* feat(agents): Show subagents as their own conversations

Agents that support ACP subagent sessions (Claude Code, Codex) now run each
subagent as a child session. Its tool calls and messages no longer mix into
the task's conversation: the parent shows a card per subagent with its state,
tool call count, latest step, task and result, and the card opens the
subagent's own conversation.

- Route session/update by session id; subagent settings and usage stay out
  of the task.
- Subagent permission requests are answered in the task's conversation,
  named after the subagent.
- Subagent conversations are saved with the task; a running subagent is
  marked stopped after a restart.
- A running subagent can be stopped on its own.

* fix(agents): Save a subagent's state when it changes after the turn
Цей коміт міститься в:
l0ng-ai authored and GitHub committed 2026-10-28 17:51:55 +08:00
1 джерело 5b63a2b95c
коміт ecb3134460
14 files changed
+1230 -80

No files matched your search

+16 -4
Переглянути файл
@@ -46,10 +46,16 @@ pub async fn agent_commands(
agent::commands(&state.host, window.label(), provider, task).await
}
/// Entries of `task`'s conversation, or of its subagent `subagent`'s.
#[tauri::command]
#[specta::specta]
pub fn agent_entries(window: Window, state: State<'_, AppState>, task: String) -> IdeResult<Vec<AgentEntry>> {
agent::entries(&state.host, window.label(), task)
pub fn agent_entries(
window: Window,
state: State<'_, AppState>,
task: String,
subagent: Option<String>,
) -> IdeResult<Vec<AgentEntry>> {
agent::entries(&state.host, window.label(), task, subagent)
}
#[tauri::command]
@@ -108,10 +114,16 @@ pub async fn agent_set_config(
agent::set_config(&state.host, window.label(), task, option, value).await
}
/// Stops the task's current turn, or with `subagent` only that subagent's work.
#[tauri::command]
#[specta::specta]
pub fn agent_cancel(window: Window, state: State<'_, AppState>, task: String) -> IdeResult<()> {
agent::cancel(&state.host, window.label(), task)
pub fn agent_cancel(
window: Window,
state: State<'_, AppState>,
task: String,
subagent: Option<String>,
) -> IdeResult<()> {
agent::cancel(&state.host, window.label(), task, subagent)
}
/// Answers a permission request; `option: null` cancels it.