feat(ui): worker client surface for in-app interactive sessions
Adds SendInteractiveMessageAsync/StopInteractiveSessionAsync and the InteractiveSessionStarted/Ended events to IWorkerClient + WorkerClient (UI-thread dispatch mirroring TaskQuestionAsked). Updates the IWorkerClient fakes in both test projects.
This commit is contained in:
@@ -25,6 +25,9 @@ public interface IWorkerClient : INotifyPropertyChanged
|
||||
/// <summary>A pending question was answered, timed out, or the run ended: (taskId, questionId).</summary>
|
||||
event Action<string, string>? TaskQuestionResolvedEvent;
|
||||
|
||||
event Action<string>? InteractiveSessionStartedEvent;
|
||||
event Action<string>? InteractiveSessionEndedEvent;
|
||||
|
||||
event Action? PrepStartedEvent;
|
||||
event Action<string>? PrepLineEvent;
|
||||
event Action<bool>? PrepFinishedEvent;
|
||||
@@ -46,6 +49,8 @@ public interface IWorkerClient : INotifyPropertyChanged
|
||||
Task ContinueTaskAsync(string taskId, string followUpPrompt);
|
||||
/// <summary>Answer a question a running task raised via AskUser.</summary>
|
||||
Task AnswerTaskQuestionAsync(string taskId, string questionId, string answer);
|
||||
Task SendInteractiveMessageAsync(string taskId, string text);
|
||||
Task StopInteractiveSessionAsync(string taskId);
|
||||
/// <summary>The question a running task is currently blocked on, if any (for re-attach).</summary>
|
||||
Task<PendingQuestionDto?> GetPendingQuestionAsync(string taskId);
|
||||
Task ResetTaskAsync(string taskId);
|
||||
|
||||
@@ -49,6 +49,8 @@ public partial class WorkerClient : ObservableObject, IAsyncDisposable, IWorkerC
|
||||
public event Action<string>? TaskUpdatedEvent;
|
||||
public event Action<string, string, string>? TaskQuestionAskedEvent;
|
||||
public event Action<string, string>? TaskQuestionResolvedEvent;
|
||||
public event Action<string>? InteractiveSessionStartedEvent;
|
||||
public event Action<string>? InteractiveSessionEndedEvent;
|
||||
public event Action? ConnectionRestoredEvent;
|
||||
public event Action<string>? WorktreeUpdatedEvent;
|
||||
public event Action<string>? ListUpdatedEvent;
|
||||
@@ -148,6 +150,16 @@ public partial class WorkerClient : ObservableObject, IAsyncDisposable, IWorkerC
|
||||
Dispatcher.UIThread.Post(() => TaskQuestionResolvedEvent?.Invoke(taskId, questionId));
|
||||
});
|
||||
|
||||
_hub.On<string>("InteractiveSessionStarted", taskId =>
|
||||
{
|
||||
Dispatcher.UIThread.Post(() => InteractiveSessionStartedEvent?.Invoke(taskId));
|
||||
});
|
||||
|
||||
_hub.On<string>("InteractiveSessionEnded", taskId =>
|
||||
{
|
||||
Dispatcher.UIThread.Post(() => InteractiveSessionEndedEvent?.Invoke(taskId));
|
||||
});
|
||||
|
||||
_hub.On<string>("WorktreeUpdated", taskId =>
|
||||
{
|
||||
Dispatcher.UIThread.Post(() => WorktreeUpdatedEvent?.Invoke(taskId));
|
||||
@@ -279,6 +291,18 @@ public partial class WorkerClient : ObservableObject, IAsyncDisposable, IWorkerC
|
||||
catch { /* offline or already resolved — the UI clears optimistically */ }
|
||||
}
|
||||
|
||||
public async Task SendInteractiveMessageAsync(string taskId, string text)
|
||||
{
|
||||
try { await _hub.InvokeAsync("SendInteractiveMessage", taskId, text); }
|
||||
catch { /* offline or session already ended */ }
|
||||
}
|
||||
|
||||
public async Task StopInteractiveSessionAsync(string taskId)
|
||||
{
|
||||
try { await _hub.InvokeAsync("StopInteractiveSession", taskId); }
|
||||
catch { /* offline */ }
|
||||
}
|
||||
|
||||
public Task<PendingQuestionDto?> GetPendingQuestionAsync(string taskId)
|
||||
=> TryInvokeAsync<PendingQuestionDto>("GetPendingQuestion", taskId);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user