refactor(interactive): remove streaming interactive stack (superseded by ConPTY)
The embedded ConPTY terminal replaced the in-app streaming interactive session, so delete the dead stack: StreamingClaudeSession, InteractiveSessionService, ProcessClaudeStreamTransport, IClaudeStreamTransport, ILiveSession, LiveSessionRegistry, IdleSessionReaper (+ WorkerConfig.InteractiveIdleTimeoutMinutes), the WorkerHub interactive methods + HubBroadcaster events, IWorkerClient interactive members, the TaskMonitorViewModel composer + SessionTerminalView composer markup, and the old 'Run interactively' entry. AskUser/PendingQuestionRegistry, the autonomous path, planning, ResumeTaskInTerminal, and all ConPTY code are kept. Localization pruned.
This commit is contained in:
@@ -189,224 +189,4 @@ public class TaskMonitorViewModelTests : IDisposable
|
||||
|
||||
Assert.False(vm.HasPendingQuestion);
|
||||
}
|
||||
|
||||
// ── Interactive composer ──────────────────────────────────────────────────
|
||||
|
||||
[Fact]
|
||||
public void InteractiveStarted_ForSubscribedTask_SetsIsInteractiveLive()
|
||||
{
|
||||
var worker = new FakeWorker();
|
||||
using var vm = Build(worker);
|
||||
vm.SetTaskId("t1");
|
||||
|
||||
worker.RaiseInteractiveStarted("t1");
|
||||
|
||||
Assert.True(vm.IsInteractiveLive);
|
||||
Assert.Equal("running", vm.AgentState);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InteractiveStarted_ForOtherTask_IsIgnored()
|
||||
{
|
||||
var worker = new FakeWorker();
|
||||
using var vm = Build(worker);
|
||||
vm.SetTaskId("t1");
|
||||
|
||||
worker.RaiseInteractiveStarted("other");
|
||||
|
||||
Assert.False(vm.IsInteractiveLive);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InteractiveEnded_ForSubscribedTask_ClearsIsInteractiveLive()
|
||||
{
|
||||
var worker = new FakeWorker();
|
||||
using var vm = Build(worker);
|
||||
vm.SetTaskId("t1");
|
||||
worker.RaiseInteractiveStarted("t1");
|
||||
|
||||
worker.RaiseInteractiveEnded("t1");
|
||||
|
||||
Assert.False(vm.IsInteractiveLive);
|
||||
Assert.Equal("done", vm.AgentState);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InteractiveEnded_ForOtherTask_IsIgnored()
|
||||
{
|
||||
var worker = new FakeWorker();
|
||||
using var vm = Build(worker);
|
||||
vm.SetTaskId("t1");
|
||||
worker.RaiseInteractiveStarted("t1");
|
||||
|
||||
worker.RaiseInteractiveEnded("other");
|
||||
|
||||
Assert.True(vm.IsInteractiveLive); // unchanged
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SubmitComposerCommand_CanExecute_FalseWhenNotLive()
|
||||
{
|
||||
var worker = new FakeWorker();
|
||||
using var vm = Build(worker);
|
||||
vm.SetTaskId("t1");
|
||||
vm.ComposerDraft = "hello";
|
||||
|
||||
Assert.False(vm.SubmitComposerCommand.CanExecute(null));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SubmitComposerCommand_CanExecute_FalseWhenLiveButDraftWhitespace()
|
||||
{
|
||||
var worker = new FakeWorker();
|
||||
using var vm = Build(worker);
|
||||
vm.SetTaskId("t1");
|
||||
worker.RaiseInteractiveStarted("t1");
|
||||
vm.ComposerDraft = " ";
|
||||
|
||||
Assert.False(vm.SubmitComposerCommand.CanExecute(null));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void SubmitComposerCommand_CanExecute_TrueWhenLiveAndDraftSet()
|
||||
{
|
||||
var worker = new FakeWorker();
|
||||
using var vm = Build(worker);
|
||||
vm.SetTaskId("t1");
|
||||
worker.RaiseInteractiveStarted("t1");
|
||||
vm.ComposerDraft = "hello";
|
||||
|
||||
Assert.True(vm.SubmitComposerCommand.CanExecute(null));
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task SubmitComposer_CallsClient_ClearsDraft_DoesNotAddLogLine()
|
||||
{
|
||||
var worker = new FakeWorker();
|
||||
using var vm = Build(worker);
|
||||
vm.SetTaskId("t1");
|
||||
worker.RaiseInteractiveStarted("t1");
|
||||
vm.ComposerDraft = "do the thing";
|
||||
|
||||
await vm.SubmitComposerCommand.ExecuteAsync(null);
|
||||
|
||||
Assert.Single(worker.SentInteractive);
|
||||
Assert.Equal(("t1", "do the thing"), worker.SentInteractive[0]);
|
||||
Assert.Equal(string.Empty, vm.ComposerDraft);
|
||||
// Log must NOT be updated by submit itself; it updates on InteractiveMessageSent
|
||||
Assert.Empty(vm.Log);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InteractiveMessageSent_ForSubscribedTask_AddsUserLogLine()
|
||||
{
|
||||
var worker = new FakeWorker();
|
||||
using var vm = Build(worker);
|
||||
vm.SetTaskId("t1");
|
||||
|
||||
worker.RaiseInteractiveMessageSent("t1", "hello from event");
|
||||
|
||||
Assert.Single(vm.Log);
|
||||
Assert.Equal(LogKind.User, vm.Log[0].Kind);
|
||||
Assert.Equal("hello from event", vm.Log[0].Text);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InteractiveMessageSent_ForOtherTask_IsIgnored()
|
||||
{
|
||||
var worker = new FakeWorker();
|
||||
using var vm = Build(worker);
|
||||
vm.SetTaskId("t1");
|
||||
|
||||
worker.RaiseInteractiveMessageSent("other", "not mine");
|
||||
|
||||
Assert.Empty(vm.Log);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InteractiveQueueChanged_ForSubscribedTask_PopulatesQueue()
|
||||
{
|
||||
var worker = new FakeWorker();
|
||||
using var vm = Build(worker);
|
||||
vm.SetTaskId("t1");
|
||||
|
||||
worker.RaiseInteractiveQueueChanged("t1", new[] { "msg1", "msg2" });
|
||||
|
||||
Assert.Equal(2, vm.QueuedMessages.Count);
|
||||
Assert.Equal("msg1", vm.QueuedMessages[0].Text);
|
||||
Assert.Equal("msg2", vm.QueuedMessages[1].Text);
|
||||
Assert.True(vm.HasQueuedMessages);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InteractiveQueueChanged_EmptyList_ClearsQueue()
|
||||
{
|
||||
var worker = new FakeWorker();
|
||||
using var vm = Build(worker);
|
||||
vm.SetTaskId("t1");
|
||||
worker.RaiseInteractiveQueueChanged("t1", new[] { "msg1" });
|
||||
|
||||
worker.RaiseInteractiveQueueChanged("t1", Array.Empty<string>());
|
||||
|
||||
Assert.Empty(vm.QueuedMessages);
|
||||
Assert.False(vm.HasQueuedMessages);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InteractiveQueueChanged_ForOtherTask_IsIgnored()
|
||||
{
|
||||
var worker = new FakeWorker();
|
||||
using var vm = Build(worker);
|
||||
vm.SetTaskId("t1");
|
||||
|
||||
worker.RaiseInteractiveQueueChanged("other", new[] { "msg1" });
|
||||
|
||||
Assert.Empty(vm.QueuedMessages);
|
||||
Assert.False(vm.HasQueuedMessages);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public void InteractiveEnded_ClearsQueuedMessages()
|
||||
{
|
||||
var worker = new FakeWorker();
|
||||
using var vm = Build(worker);
|
||||
vm.SetTaskId("t1");
|
||||
worker.RaiseInteractiveStarted("t1");
|
||||
worker.RaiseInteractiveQueueChanged("t1", new[] { "pending msg" });
|
||||
|
||||
worker.RaiseInteractiveEnded("t1");
|
||||
|
||||
Assert.Empty(vm.QueuedMessages);
|
||||
Assert.False(vm.HasQueuedMessages);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task QueuedMessageViewModel_RemoveCommand_RecordsRemoveCall()
|
||||
{
|
||||
var worker = new FakeWorker();
|
||||
using var vm = Build(worker);
|
||||
vm.SetTaskId("t1");
|
||||
worker.RaiseInteractiveQueueChanged("t1", new[] { "a", "b" });
|
||||
|
||||
vm.QueuedMessages[0].RemoveCommand.Execute(null);
|
||||
// RemoveQueuedAsync is fire-and-forget; yield to let the async continuation run
|
||||
await System.Threading.Tasks.Task.Yield();
|
||||
|
||||
Assert.Single(worker.RemovedQueued);
|
||||
Assert.Equal(("t1", "a"), worker.RemovedQueued[0]);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task InterruptInteractiveCommand_WhenLive_RecordsOneCall()
|
||||
{
|
||||
var worker = new FakeWorker();
|
||||
using var vm = Build(worker);
|
||||
vm.SetTaskId("t1");
|
||||
worker.RaiseInteractiveStarted("t1");
|
||||
|
||||
await vm.InterruptInteractiveCommand.ExecuteAsync(null);
|
||||
|
||||
Assert.Single(worker.InterruptedInteractive);
|
||||
Assert.Equal("t1", worker.InterruptedInteractive[0]);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user