feat(worker): in-app interactive session service, replacing the wt terminal launch
InteractiveSessionService resolves a task's list working dir + seeded prompt, spawns a StreamingClaudeSession (claude stream-json in the list dir, model+auto as before), registers it in LiveSessionRegistry, streams output over TaskMessage, and broadcasts InteractiveSessionStarted/Ended (an exit watcher fires Ended). The hub's OpenInteractiveTerminalAsync now starts this in-app session; SendInteractiveMessage and StopInteractiveSession route to it. The external Windows-Terminal interactive launch (LaunchInteractiveAsync / InteractiveLaunchContext / OpenInteractiveAsync) is removed; planning sessions keep their terminal launch.
This commit is contained in:
@@ -77,4 +77,10 @@ public sealed class HubBroadcaster : IPrimeBroadcaster, IRefineBroadcaster
|
||||
Task IRefineBroadcaster.RefineStartedAsync(string taskId) => RefineStarted(taskId);
|
||||
Task IRefineBroadcaster.RefineFinishedAsync(string taskId, bool success, string? error) =>
|
||||
RefineFinished(taskId, success, error);
|
||||
|
||||
public Task InteractiveSessionStarted(string taskId) =>
|
||||
_hub.Clients.All.SendAsync("InteractiveSessionStarted", taskId);
|
||||
|
||||
public Task InteractiveSessionEnded(string taskId) =>
|
||||
_hub.Clients.All.SendAsync("InteractiveSessionEnded", taskId);
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ using ClaudeDo.Worker.Lifecycle;
|
||||
using ClaudeDo.Worker.Logging;
|
||||
using ClaudeDo.Worker.Online;
|
||||
using ClaudeDo.Worker.Planning;
|
||||
using ClaudeDo.Worker.Runner;
|
||||
using ClaudeDo.Worker.Prime;
|
||||
using ClaudeDo.Worker.Queue;
|
||||
using ClaudeDo.Worker.Refine;
|
||||
@@ -116,6 +117,7 @@ public sealed class WorkerHub : Microsoft.AspNetCore.SignalR.Hub
|
||||
private readonly OnlineInboxConfig _onlineInboxConfig;
|
||||
private readonly OnlineTokenStore _onlineTokenStore;
|
||||
private readonly Runner.PendingQuestionRegistry _pendingQuestions;
|
||||
private readonly InteractiveSessionService _interactive;
|
||||
private readonly LogRingBuffer? _logBuffer;
|
||||
|
||||
public WorkerHub(
|
||||
@@ -142,6 +144,7 @@ public sealed class WorkerHub : Microsoft.AspNetCore.SignalR.Hub
|
||||
OnlineInboxConfig onlineInboxConfig,
|
||||
OnlineTokenStore onlineTokenStore,
|
||||
Runner.PendingQuestionRegistry pendingQuestions,
|
||||
InteractiveSessionService interactive,
|
||||
LogRingBuffer? logBuffer = null)
|
||||
{
|
||||
_queue = queue;
|
||||
@@ -167,6 +170,7 @@ public sealed class WorkerHub : Microsoft.AspNetCore.SignalR.Hub
|
||||
_onlineInboxConfig = onlineInboxConfig;
|
||||
_onlineTokenStore = onlineTokenStore;
|
||||
_pendingQuestions = pendingQuestions;
|
||||
_interactive = interactive;
|
||||
_logBuffer = logBuffer;
|
||||
}
|
||||
|
||||
@@ -568,11 +572,14 @@ public sealed class WorkerHub : Microsoft.AspNetCore.SignalR.Hub
|
||||
return ctx;
|
||||
}
|
||||
|
||||
public async Task OpenInteractiveTerminalAsync(string taskId)
|
||||
{
|
||||
var ctx = await _planning.OpenInteractiveAsync(taskId, Context.ConnectionAborted);
|
||||
await _launcher.LaunchInteractiveAsync(ctx, Context.ConnectionAborted);
|
||||
}
|
||||
public Task OpenInteractiveTerminalAsync(string taskId) =>
|
||||
_interactive.StartAsync(taskId, Context.ConnectionAborted);
|
||||
|
||||
public Task SendInteractiveMessage(string taskId, string text) =>
|
||||
_interactive.SendAsync(taskId, text, Context.ConnectionAborted);
|
||||
|
||||
public Task StopInteractiveSession(string taskId) =>
|
||||
_interactive.StopAsync(taskId, Context.ConnectionAborted);
|
||||
|
||||
public async Task<DiscardPlanningOutcome> DiscardPlanningSessionAsync(string taskId, bool dequeueQueuedChildren = false)
|
||||
{
|
||||
|
||||
Reference in New Issue
Block a user