feat: enhance daemon dispatching, device readiness fallback, and live streaming UI
- Admin Console & Task Queue: add cancellation, session startup progress endpoints, and support ingress metadata - Diagnostics & Runtime: enhance ADB probe to prefer unlocked devices and synchronize with readiness engine - MCP Server: dispatch tasks through Artemis Daemon scheduler with fallback to standalone runner, improve action overlays - Showcase UI: improve session auto-selection with pinning support, render startup progress, and refine stream styling - CLI & Makefile: expose server lifecycle commands (restart, stop, status) - Configuration: ignore runtime server state file in .gitignore
This commit is contained in:
1 parent
57655266cc
commit
8fdecf23d7
33 files changed
+1315
-293
No files matched your search
@@ -1375,6 +1375,31 @@
|
||||
<span>{{ isRefreshingDiagnostics() ? 'Checking...' : 'Check Again' }}</span>
|
||||
</button>
|
||||
</div>
|
||||
|
||||
<!-- Multi-Device Switcher if multiple devices detected -->
|
||||
@if (connectedDevices().length > 1) {
|
||||
<div class="multi-device-switcher" style="margin-top: 12px;">
|
||||
<span class="switcher-label">Select Active Device:</span>
|
||||
<div class="switcher-chips">
|
||||
@for (dev of connectedDevices(); track dev.serial) {
|
||||
<button
|
||||
type="button"
|
||||
class="device-chip-btn"
|
||||
[class.selected]="dev.serial === activeDevice()?.serial"
|
||||
(click)="selectTargetDevice(dev.serial)"
|
||||
>
|
||||
<span class="material-symbols-outlined chip-icon">
|
||||
phone_android
|
||||
</span>
|
||||
<span>{{ dev.model || dev.serial }}</span>
|
||||
@if (dev.serial === activeDevice()?.serial) {
|
||||
<span class="active-check">✓ Active</span>
|
||||
}
|
||||
</button>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
}
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
@@ -116,11 +116,11 @@
|
||||
<span class="material-symbols-outlined">close</span>
|
||||
</button>
|
||||
|
||||
<!-- Stop Button (Visible when task is running) -->
|
||||
<!-- Stop Button (Visible when currently viewed task is active) -->
|
||||
<button *ngIf="isTaskRunning()" type="button" class="dock-circle-btn btn-stop" [disabled]="isSubmitting"
|
||||
(click)="stopTask($event)"
|
||||
title="Stop running task"
|
||||
aria-label="Stop running task"
|
||||
[title]="stopButtonTitle()"
|
||||
[attr.aria-label]="stopButtonTitle()"
|
||||
>
|
||||
<span class="material-symbols-outlined">stop</span>
|
||||
</button>
|
||||
@@ -161,12 +161,12 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Separate Standalone Stop Button Beside the Capsule (Visible when task is running) -->
|
||||
<!-- Separate Standalone Stop Button Beside the Capsule (Visible when currently viewed task is active) -->
|
||||
<button *ngIf="isTaskRunning()" type="button" class="standalone-stop-btn"
|
||||
[disabled]="isSubmitting"
|
||||
(click)="stopTask($event)"
|
||||
title="Stop running task"
|
||||
aria-label="Stop running task"
|
||||
[title]="stopButtonTitle()"
|
||||
[attr.aria-label]="stopButtonTitle()"
|
||||
>
|
||||
<span class="material-symbols-outlined">stop</span>
|
||||
</button>
|
||||
|
||||
@@ -77,10 +77,29 @@ export class WorkspaceComponent implements OnInit {
|
||||
}
|
||||
|
||||
/**
|
||||
* Computed boolean whether a task is currently executing or active
|
||||
* Computed boolean whether the currently viewed task is actively running or paused.
|
||||
* Only displays the stop/cancel button when inspecting an active task.
|
||||
*/
|
||||
public isTaskRunning = computed(() => {
|
||||
return this.agentService.isRunningTask();
|
||||
return this.agentService.isCurrentSessionRunning();
|
||||
});
|
||||
|
||||
/**
|
||||
* Dynamic tooltip and label indicating which task will be stopped
|
||||
*/
|
||||
public stopButtonTitle = computed(() => {
|
||||
const session = this.agentService.currentSession();
|
||||
if (session?.initial_goal) {
|
||||
const truncated = session.initial_goal.length > 45
|
||||
? session.initial_goal.substring(0, 42) + '...'
|
||||
: session.initial_goal;
|
||||
return `Stop current task: "${truncated}"`;
|
||||
}
|
||||
const curId = this.agentService.currentSessionId();
|
||||
if (curId) {
|
||||
return `Stop current task (${curId})`;
|
||||
}
|
||||
return 'Stop current running task';
|
||||
});
|
||||
|
||||
/**
|
||||
@@ -216,7 +235,7 @@ export class WorkspaceComponent implements OnInit {
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop currently running task
|
||||
* Stop currently viewed task
|
||||
*/
|
||||
public stopTask(event?: MouseEvent): void {
|
||||
if (event) {
|
||||
@@ -225,9 +244,10 @@ export class WorkspaceComponent implements OnInit {
|
||||
if (!this.isTaskRunning()) {
|
||||
return;
|
||||
}
|
||||
const targetSessionId = this.agentService.currentSessionId();
|
||||
this.isSubmitting = true;
|
||||
this.errorMessage = null;
|
||||
this.agentService.stopTask(false);
|
||||
this.agentService.stopTask(targetSessionId, false);
|
||||
setTimeout(() => {
|
||||
this.isSubmitting = false;
|
||||
}, 400);
|
||||
|
||||
Reference in new issue
Block a user