feat(ui): interactive chat composer state on the session monitor VM

TaskMonitorViewModel gains IsInteractiveLive + ComposerDraft + SubmitComposer
(optimistic LogKind.User echo, then SendInteractiveMessageAsync) + StopInteractive,
driven by the InteractiveSessionStarted/Ended events. Since DetailsIslandViewModel
embeds this monitor, both task detail and Mission Control get the composer. Mission
Control auto-creates a monitor on InteractiveSessionStarted. Adds LogKind.User.
This commit is contained in:
Mika Kuns
2026-06-26 09:29:58 +02:00
parent 9effddeb2c
commit 140b8e1551
5 changed files with 190 additions and 3 deletions

View File

@@ -57,6 +57,9 @@ public abstract class StubWorkerClient : IWorkerClient
public void RaisePrepLine(string line) => PrepLineEvent?.Invoke(line);
public void RaisePrepFinished(bool ok) => PrepFinishedEvent?.Invoke(ok);
public void RaiseInteractiveStarted(string taskId) => InteractiveSessionStartedEvent?.Invoke(taskId);
public void RaiseInteractiveEnded(string taskId) => InteractiveSessionEndedEvent?.Invoke(taskId);
public virtual bool IsConnected => false;
public virtual bool IsReconnecting => false;
public virtual string? LastApproveTarget => null;
@@ -135,8 +138,18 @@ public abstract class StubWorkerClient : IWorkerClient
public virtual Task SetOnlineInboxConfigAsync(OnlineInboxConfigInputDto input) => Task.CompletedTask;
public virtual Task SetOnlineInboxAuthAsync(string refreshToken) => Task.CompletedTask;
public virtual Task ClearOnlineInboxAuthAsync() => Task.CompletedTask;
public virtual Task SendInteractiveMessageAsync(string taskId, string text) => Task.CompletedTask;
public virtual Task StopInteractiveSessionAsync(string taskId) => Task.CompletedTask;
public List<(string TaskId, string Text)> SentInteractive { get; } = new();
public virtual Task SendInteractiveMessageAsync(string taskId, string text)
{
SentInteractive.Add((taskId, text));
return Task.CompletedTask;
}
public List<string> StoppedInteractive { get; } = new();
public virtual Task StopInteractiveSessionAsync(string taskId)
{
StoppedInteractive.Add(taskId);
return Task.CompletedTask;
}
protected void RaisePropertyChanged(string name) => PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
}