workspace: remove input readiness capability
This commit is contained in:
parent
c948b669c1
commit
4a90267ebc
|
|
@ -170,7 +170,6 @@ pub struct RuntimeCapabilitySummary {
|
||||||
pub can_get_worker: bool,
|
pub can_get_worker: bool,
|
||||||
pub can_spawn_worker: bool,
|
pub can_spawn_worker: bool,
|
||||||
pub can_stop_worker: bool,
|
pub can_stop_worker: bool,
|
||||||
pub can_accept_input: bool,
|
|
||||||
pub has_workspace_fs: bool,
|
pub has_workspace_fs: bool,
|
||||||
pub has_shell: bool,
|
pub has_shell: bool,
|
||||||
pub has_git: bool,
|
pub has_git: bool,
|
||||||
|
|
@ -223,7 +222,6 @@ pub struct WorkerImplementationSummary {
|
||||||
|
|
||||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||||
pub struct WorkerCapabilitySummary {
|
pub struct WorkerCapabilitySummary {
|
||||||
pub can_accept_input: bool,
|
|
||||||
pub can_stop: bool,
|
pub can_stop: bool,
|
||||||
pub can_spawn_followup: bool,
|
pub can_spawn_followup: bool,
|
||||||
}
|
}
|
||||||
|
|
@ -1204,14 +1202,6 @@ impl EmbeddedWorkerRuntime {
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn can_accept_embedded_input(
|
|
||||||
&self,
|
|
||||||
status: EmbeddedWorkerStatus,
|
|
||||||
execution: &worker_runtime::execution::WorkerExecutionStatus,
|
|
||||||
) -> bool {
|
|
||||||
runtime_worker_can_accept_input(self.execution_enabled, status, execution)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn can_stop_embedded_worker(
|
fn can_stop_embedded_worker(
|
||||||
&self,
|
&self,
|
||||||
status: EmbeddedWorkerStatus,
|
status: EmbeddedWorkerStatus,
|
||||||
|
|
@ -1242,8 +1232,6 @@ impl EmbeddedWorkerRuntime {
|
||||||
display_hint: "backend-internal worker-runtime Worker".to_string(),
|
display_hint: "backend-internal worker-runtime Worker".to_string(),
|
||||||
},
|
},
|
||||||
capabilities: WorkerCapabilitySummary {
|
capabilities: WorkerCapabilitySummary {
|
||||||
can_accept_input: self
|
|
||||||
.can_accept_embedded_input(summary.status, &summary.execution),
|
|
||||||
can_stop: self.can_stop_embedded_worker(summary.status, &summary.execution),
|
can_stop: self.can_stop_embedded_worker(summary.status, &summary.execution),
|
||||||
can_spawn_followup: false,
|
can_spawn_followup: false,
|
||||||
},
|
},
|
||||||
|
|
@ -1278,7 +1266,6 @@ impl EmbeddedWorkerRuntime {
|
||||||
display_hint: "backend-internal worker-runtime Worker".to_string(),
|
display_hint: "backend-internal worker-runtime Worker".to_string(),
|
||||||
},
|
},
|
||||||
capabilities: WorkerCapabilitySummary {
|
capabilities: WorkerCapabilitySummary {
|
||||||
can_accept_input: self.can_accept_embedded_input(detail.status, &detail.execution),
|
|
||||||
can_stop: self.can_stop_embedded_worker(detail.status, &detail.execution),
|
can_stop: self.can_stop_embedded_worker(detail.status, &detail.execution),
|
||||||
can_spawn_followup: false,
|
can_spawn_followup: false,
|
||||||
},
|
},
|
||||||
|
|
@ -2014,7 +2001,6 @@ impl RemoteWorkerRuntime {
|
||||||
display_hint: "Backend-proxied remote worker-runtime Worker".to_string(),
|
display_hint: "Backend-proxied remote worker-runtime Worker".to_string(),
|
||||||
},
|
},
|
||||||
capabilities: WorkerCapabilitySummary {
|
capabilities: WorkerCapabilitySummary {
|
||||||
can_accept_input: runtime_worker_can_accept_input(true, summary.status, &summary.execution),
|
|
||||||
can_stop: runtime_worker_can_stop(true, summary.status, &summary.execution),
|
can_stop: runtime_worker_can_stop(true, summary.status, &summary.execution),
|
||||||
can_spawn_followup: false,
|
can_spawn_followup: false,
|
||||||
},
|
},
|
||||||
|
|
@ -2049,7 +2035,6 @@ impl RemoteWorkerRuntime {
|
||||||
display_hint: "Backend-proxied remote worker-runtime Worker".to_string(),
|
display_hint: "Backend-proxied remote worker-runtime Worker".to_string(),
|
||||||
},
|
},
|
||||||
capabilities: WorkerCapabilitySummary {
|
capabilities: WorkerCapabilitySummary {
|
||||||
can_accept_input: runtime_worker_can_accept_input(true, detail.status, &detail.execution),
|
|
||||||
can_stop: runtime_worker_can_stop(true, detail.status, &detail.execution),
|
can_stop: runtime_worker_can_stop(true, detail.status, &detail.execution),
|
||||||
can_spawn_followup: false,
|
can_spawn_followup: false,
|
||||||
},
|
},
|
||||||
|
|
@ -2459,7 +2444,6 @@ fn embedded_runtime_capabilities(
|
||||||
can_get_worker: available,
|
can_get_worker: available,
|
||||||
can_spawn_worker: available,
|
can_spawn_worker: available,
|
||||||
can_stop_worker: available && execution_enabled,
|
can_stop_worker: available && execution_enabled,
|
||||||
can_accept_input: available && execution_enabled,
|
|
||||||
has_workspace_fs: false,
|
has_workspace_fs: false,
|
||||||
has_shell: false,
|
has_shell: false,
|
||||||
has_git: false,
|
has_git: false,
|
||||||
|
|
@ -2508,18 +2492,6 @@ fn embedded_spawn_execution_failure_diagnostic(
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
fn runtime_worker_can_accept_input(
|
|
||||||
execution_enabled: bool,
|
|
||||||
status: EmbeddedWorkerStatus,
|
|
||||||
execution: &WorkerExecutionStatus,
|
|
||||||
) -> bool {
|
|
||||||
execution_enabled
|
|
||||||
&& status == EmbeddedWorkerStatus::Running
|
|
||||||
&& execution.backend == worker_runtime::execution::WorkerExecutionBackendKind::Connected
|
|
||||||
&& execution.run_state == WorkerExecutionRunState::Idle
|
|
||||||
&& !execution_last_result_blocks_control(execution)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn runtime_worker_can_stop(
|
fn runtime_worker_can_stop(
|
||||||
execution_enabled: bool,
|
execution_enabled: bool,
|
||||||
status: EmbeddedWorkerStatus,
|
status: EmbeddedWorkerStatus,
|
||||||
|
|
@ -2980,7 +2952,6 @@ fn remote_runtime_capabilities(
|
||||||
can_get_worker: available,
|
can_get_worker: available,
|
||||||
can_spawn_worker: available && worker_creation_available,
|
can_spawn_worker: available && worker_creation_available,
|
||||||
can_stop_worker: available,
|
can_stop_worker: available,
|
||||||
can_accept_input: available && worker_creation_available,
|
|
||||||
has_workspace_fs: false,
|
has_workspace_fs: false,
|
||||||
has_shell: false,
|
has_shell: false,
|
||||||
has_git: false,
|
has_git: false,
|
||||||
|
|
@ -3208,7 +3179,6 @@ pub fn placeholder_worker(host_id: impl Into<String>) -> WorkerSummary {
|
||||||
display_hint: "unsupported".to_string(),
|
display_hint: "unsupported".to_string(),
|
||||||
},
|
},
|
||||||
capabilities: WorkerCapabilitySummary {
|
capabilities: WorkerCapabilitySummary {
|
||||||
can_accept_input: false,
|
|
||||||
can_stop: false,
|
can_stop: false,
|
||||||
can_spawn_followup: false,
|
can_spawn_followup: false,
|
||||||
},
|
},
|
||||||
|
|
@ -3535,7 +3505,6 @@ mod tests {
|
||||||
display_hint: "test fixture".to_string(),
|
display_hint: "test fixture".to_string(),
|
||||||
},
|
},
|
||||||
capabilities: WorkerCapabilitySummary {
|
capabilities: WorkerCapabilitySummary {
|
||||||
can_accept_input: false,
|
|
||||||
can_stop: false,
|
can_stop: false,
|
||||||
can_spawn_followup: false,
|
can_spawn_followup: false,
|
||||||
},
|
},
|
||||||
|
|
@ -3565,7 +3534,6 @@ mod tests {
|
||||||
can_get_worker: true,
|
can_get_worker: true,
|
||||||
can_spawn_worker: false,
|
can_spawn_worker: false,
|
||||||
can_stop_worker: false,
|
can_stop_worker: false,
|
||||||
can_accept_input: false,
|
|
||||||
has_workspace_fs: false,
|
has_workspace_fs: false,
|
||||||
has_shell: false,
|
has_shell: false,
|
||||||
has_git: false,
|
has_git: false,
|
||||||
|
|
@ -3749,7 +3717,6 @@ mod tests {
|
||||||
let spawned = runtime.spawn_worker(embedded_spawn_request());
|
let spawned = runtime.spawn_worker(embedded_spawn_request());
|
||||||
assert_eq!(spawned.state, WorkerOperationState::Accepted);
|
assert_eq!(spawned.state, WorkerOperationState::Accepted);
|
||||||
let worker = spawned.worker.expect("created embedded worker");
|
let worker = spawned.worker.expect("created embedded worker");
|
||||||
assert!(worker.capabilities.can_accept_input);
|
|
||||||
assert!(worker.capabilities.can_stop);
|
assert!(worker.capabilities.can_stop);
|
||||||
|
|
||||||
let input = runtime.send_input(
|
let input = runtime.send_input(
|
||||||
|
|
@ -3768,7 +3735,6 @@ mod tests {
|
||||||
.worker
|
.worker
|
||||||
.expect("worker detail");
|
.expect("worker detail");
|
||||||
if detail.state == "idle" {
|
if detail.state == "idle" {
|
||||||
assert!(detail.capabilities.can_accept_input);
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
assert!(
|
assert!(
|
||||||
|
|
@ -3801,7 +3767,6 @@ mod tests {
|
||||||
);
|
);
|
||||||
assert_eq!(embedded_summary.source.status, RuntimeSourceStatus::Active);
|
assert_eq!(embedded_summary.source.status, RuntimeSourceStatus::Active);
|
||||||
assert!(embedded_summary.capabilities.can_spawn_worker);
|
assert!(embedded_summary.capabilities.can_spawn_worker);
|
||||||
assert!(embedded_summary.capabilities.can_accept_input);
|
|
||||||
|
|
||||||
let spawned = registry
|
let spawned = registry
|
||||||
.spawn_worker(
|
.spawn_worker(
|
||||||
|
|
@ -3837,8 +3802,6 @@ mod tests {
|
||||||
assert_eq!(worker.workspace.identity, "runtime_registry_worker");
|
assert_eq!(worker.workspace.identity, "runtime_registry_worker");
|
||||||
assert_eq!(worker.implementation.kind, "embedded_worker_runtime");
|
assert_eq!(worker.implementation.kind, "embedded_worker_runtime");
|
||||||
assert_eq!(worker.profile.as_deref(), Some("builtin:coder"));
|
assert_eq!(worker.profile.as_deref(), Some("builtin:coder"));
|
||||||
assert!(worker.capabilities.can_accept_input);
|
|
||||||
|
|
||||||
let input = registry
|
let input = registry
|
||||||
.send_input(
|
.send_input(
|
||||||
EMBEDDED_RUNTIME_ID,
|
EMBEDDED_RUNTIME_ID,
|
||||||
|
|
@ -4052,7 +4015,6 @@ mod tests {
|
||||||
workers.items[0].workspace.identity,
|
workers.items[0].workspace.identity,
|
||||||
"runtime_registry_worker"
|
"runtime_registry_worker"
|
||||||
);
|
);
|
||||||
assert!(workers.items[0].capabilities.can_accept_input);
|
|
||||||
assert!(workers.items[0].capabilities.can_stop);
|
assert!(workers.items[0].capabilities.can_stop);
|
||||||
|
|
||||||
let input = registry
|
let input = registry
|
||||||
|
|
@ -4157,11 +4119,6 @@ mod tests {
|
||||||
let workers = registry.list_workers(10);
|
let workers = registry.list_workers(10);
|
||||||
assert_eq!(workers.items.len(), 4);
|
assert_eq!(workers.items.len(), 4);
|
||||||
for worker in &workers.items {
|
for worker in &workers.items {
|
||||||
assert!(
|
|
||||||
!worker.capabilities.can_accept_input,
|
|
||||||
"{} should not be input-capable",
|
|
||||||
worker.worker_id
|
|
||||||
);
|
|
||||||
assert!(
|
assert!(
|
||||||
!worker.capabilities.can_stop,
|
!worker.capabilities.can_stop,
|
||||||
"{} should not be stoppable",
|
"{} should not be stoppable",
|
||||||
|
|
@ -4174,7 +4131,6 @@ mod tests {
|
||||||
assert_eq!(workers.items[3].state, "errored");
|
assert_eq!(workers.items[3].state, "errored");
|
||||||
|
|
||||||
let stale_detail = registry.worker("remote:primary", "1").unwrap();
|
let stale_detail = registry.worker("remote:primary", "1").unwrap();
|
||||||
assert!(!stale_detail.capabilities.can_accept_input);
|
|
||||||
assert!(!stale_detail.capabilities.can_stop);
|
assert!(!stale_detail.capabilities.can_stop);
|
||||||
assert_eq!(stale_detail.state, "stale");
|
assert_eq!(stale_detail.state, "stale");
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -4098,7 +4098,6 @@ fn worker_summary_from_registry(record: &WorkerRegistryRecord) -> WorkerSummary
|
||||||
pinned: record.retention_state == "pinned",
|
pinned: record.retention_state == "pinned",
|
||||||
retention_state: record.retention_state.clone(),
|
retention_state: record.retention_state.clone(),
|
||||||
capabilities: WorkerCapabilitySummary {
|
capabilities: WorkerCapabilitySummary {
|
||||||
can_accept_input: false,
|
|
||||||
can_stop: false,
|
can_stop: false,
|
||||||
can_spawn_followup: false,
|
can_spawn_followup: false,
|
||||||
},
|
},
|
||||||
|
|
@ -7142,7 +7141,6 @@ mod tests {
|
||||||
.worker("embedded-worker-runtime", &worker_id)
|
.worker("embedded-worker-runtime", &worker_id)
|
||||||
.expect("restored worker");
|
.expect("restored worker");
|
||||||
assert_eq!(restored_worker.state, "stale");
|
assert_eq!(restored_worker.state, "stale");
|
||||||
assert!(!restored_worker.capabilities.can_accept_input);
|
|
||||||
assert!(!restored_worker.capabilities.can_stop);
|
assert!(!restored_worker.capabilities.can_stop);
|
||||||
assert!(
|
assert!(
|
||||||
restored_worker
|
restored_worker
|
||||||
|
|
|
||||||
|
|
@ -35,7 +35,6 @@ export type RuntimeCapabilities = {
|
||||||
can_get_worker: boolean;
|
can_get_worker: boolean;
|
||||||
can_spawn_worker: boolean;
|
can_spawn_worker: boolean;
|
||||||
can_stop_worker: boolean;
|
can_stop_worker: boolean;
|
||||||
can_accept_input: boolean;
|
|
||||||
has_workspace_fs: boolean;
|
has_workspace_fs: boolean;
|
||||||
has_shell: boolean;
|
has_shell: boolean;
|
||||||
has_git: boolean;
|
has_git: boolean;
|
||||||
|
|
@ -70,7 +69,6 @@ export type Host = {
|
||||||
};
|
};
|
||||||
|
|
||||||
export type WorkerCapabilities = {
|
export type WorkerCapabilities = {
|
||||||
can_accept_input: boolean;
|
|
||||||
can_stop: boolean;
|
can_stop: boolean;
|
||||||
can_spawn_followup: boolean;
|
can_spawn_followup: boolean;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -29,7 +29,6 @@ function worker(overrides: Partial<Worker>): Worker {
|
||||||
display_hint: "Runtime Worker",
|
display_hint: "Runtime Worker",
|
||||||
},
|
},
|
||||||
capabilities: {
|
capabilities: {
|
||||||
can_accept_input: true,
|
|
||||||
can_stop: true,
|
can_stop: true,
|
||||||
can_spawn_followup: false,
|
can_spawn_followup: false,
|
||||||
},
|
},
|
||||||
|
|
@ -47,7 +46,6 @@ Deno.test("registry-only workers are not sidebar targets or console targets", ()
|
||||||
display_hint: "Missing Worker",
|
display_hint: "Missing Worker",
|
||||||
},
|
},
|
||||||
capabilities: {
|
capabilities: {
|
||||||
can_accept_input: false,
|
|
||||||
can_stop: false,
|
can_stop: false,
|
||||||
can_spawn_followup: false,
|
can_spawn_followup: false,
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -10,7 +10,8 @@
|
||||||
ClientWorkerEventWsFrame,
|
ClientWorkerEventWsFrame,
|
||||||
Diagnostic,
|
Diagnostic,
|
||||||
Worker,
|
Worker,
|
||||||
WorkerInputResult
|
WorkerInputResult,
|
||||||
|
PodProtocolEvent
|
||||||
} from '$lib/workspace-sidebar/types';
|
} from '$lib/workspace-sidebar/types';
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
|
|
@ -32,6 +33,7 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
let worker = $state<Worker | null>(null);
|
let worker = $state<Worker | null>(null);
|
||||||
|
let liveWorkerState = $state<string | null>(null);
|
||||||
let workerError = $state<string | null>(null);
|
let workerError = $state<string | null>(null);
|
||||||
let draft = $state('');
|
let draft = $state('');
|
||||||
let sending = $state(false);
|
let sending = $state(false);
|
||||||
|
|
@ -59,7 +61,9 @@
|
||||||
);
|
);
|
||||||
const lines = $derived(projection.lines);
|
const lines = $derived(projection.lines);
|
||||||
const diagnostics = $derived(mergeDiagnostics(worker?.diagnostics ?? [], streamDiagnostics));
|
const diagnostics = $derived(mergeDiagnostics(worker?.diagnostics ?? [], streamDiagnostics));
|
||||||
const canSend = $derived(Boolean(worker?.capabilities.can_accept_input) && draft.trim().length > 0 && !sending);
|
const workerState = $derived(liveWorkerState ?? worker?.state ?? 'loading');
|
||||||
|
const inputReady = $derived(workerState === 'idle');
|
||||||
|
const canSend = $derived(inputReady && draft.trim().length > 0 && !sending);
|
||||||
|
|
||||||
async function getJson<T>(path: string): Promise<T> {
|
async function getJson<T>(path: string): Promise<T> {
|
||||||
const response = await fetch(path);
|
const response = await fetch(path);
|
||||||
|
|
@ -97,12 +101,15 @@
|
||||||
async function loadWorker(target: ConsoleTarget) {
|
async function loadWorker(target: ConsoleTarget) {
|
||||||
workerError = null;
|
workerError = null;
|
||||||
try {
|
try {
|
||||||
worker = await getJson<Worker>(
|
const payload = await getJson<Worker>(
|
||||||
workerApiPath(`/runtimes/${encodeURIComponent(target.runtimeId)}/workers/${encodeURIComponent(target.workerId)}`)
|
workerApiPath(`/runtimes/${encodeURIComponent(target.runtimeId)}/workers/${encodeURIComponent(target.workerId)}`)
|
||||||
);
|
);
|
||||||
|
worker = payload;
|
||||||
|
liveWorkerState = payload.state;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
workerError = error instanceof Error ? error.message : String(error);
|
workerError = error instanceof Error ? error.message : String(error);
|
||||||
worker = null;
|
worker = null;
|
||||||
|
liveWorkerState = null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -132,7 +139,7 @@
|
||||||
async function sendMessage(event: SubmitEvent) {
|
async function sendMessage(event: SubmitEvent) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const content = draft.trim();
|
const content = draft.trim();
|
||||||
if (!content || sending || !worker?.capabilities.can_accept_input) {
|
if (!content || sending || !inputReady) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -145,6 +152,7 @@
|
||||||
);
|
);
|
||||||
if (result.state === 'accepted') {
|
if (result.state === 'accepted') {
|
||||||
draft = '';
|
draft = '';
|
||||||
|
liveWorkerState = 'running';
|
||||||
} else {
|
} else {
|
||||||
sendError = diagnosticsToText(result.diagnostics) || `Input was ${result.state}.`;
|
sendError = diagnosticsToText(result.diagnostics) || `Input was ${result.state}.`;
|
||||||
}
|
}
|
||||||
|
|
@ -155,6 +163,18 @@
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function workerStateFromProtocolEvent(event: PodProtocolEvent): string | null {
|
||||||
|
switch (event.event) {
|
||||||
|
case 'snapshot':
|
||||||
|
case 'status':
|
||||||
|
return event.data.status;
|
||||||
|
case 'shutdown':
|
||||||
|
return 'shutdown';
|
||||||
|
default:
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function connectObservation(targetWorker: Worker | null, token: number, target: ConsoleTarget) {
|
function connectObservation(targetWorker: Worker | null, token: number, target: ConsoleTarget) {
|
||||||
if (!targetWorker) {
|
if (!targetWorker) {
|
||||||
streamState = 'closed';
|
streamState = 'closed';
|
||||||
|
|
@ -182,6 +202,10 @@
|
||||||
if (!rememberObservationEvent(frame.envelope.event_id)) {
|
if (!rememberObservationEvent(frame.envelope.event_id)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
const observedState = workerStateFromProtocolEvent(frame.envelope.payload);
|
||||||
|
if (observedState) {
|
||||||
|
liveWorkerState = observedState;
|
||||||
|
}
|
||||||
observedEvents = [
|
observedEvents = [
|
||||||
...observedEvents,
|
...observedEvents,
|
||||||
{
|
{
|
||||||
|
|
@ -304,6 +328,7 @@
|
||||||
$effect(() => {
|
$effect(() => {
|
||||||
const target = consoleTarget;
|
const target = consoleTarget;
|
||||||
resetObservedEvents();
|
resetObservedEvents();
|
||||||
|
liveWorkerState = null;
|
||||||
streamDiagnostics = [];
|
streamDiagnostics = [];
|
||||||
advanceReloadToken();
|
advanceReloadToken();
|
||||||
void loadConsoleData(target);
|
void loadConsoleData(target);
|
||||||
|
|
@ -324,7 +349,7 @@
|
||||||
</div>
|
</div>
|
||||||
<div class="console-header-actions">
|
<div class="console-header-actions">
|
||||||
<div class="console-status-pill" class:warn={streamState !== 'open'}>
|
<div class="console-status-pill" class:warn={streamState !== 'open'}>
|
||||||
{worker?.state ?? 'loading'} · stream {streamState}
|
{workerState} · stream {streamState}
|
||||||
</div>
|
</div>
|
||||||
<button type="button" class="secondary-button" aria-expanded={workerDetailsOpen} onclick={() => workerDetailsOpen = !workerDetailsOpen}>
|
<button type="button" class="secondary-button" aria-expanded={workerDetailsOpen} onclick={() => workerDetailsOpen = !workerDetailsOpen}>
|
||||||
Details
|
Details
|
||||||
|
|
@ -430,7 +455,6 @@
|
||||||
<details class="metadata-details">
|
<details class="metadata-details">
|
||||||
<summary>Capabilities</summary>
|
<summary>Capabilities</summary>
|
||||||
<ul>
|
<ul>
|
||||||
<li>input: {worker.capabilities.can_accept_input ? 'available' : 'unsupported'}</li>
|
|
||||||
<li>stop: {worker.capabilities.can_stop ? 'available' : 'unsupported'}</li>
|
<li>stop: {worker.capabilities.can_stop ? 'available' : 'unsupported'}</li>
|
||||||
<li>follow-up spawn: {worker.capabilities.can_spawn_followup ? 'available' : 'unsupported'}</li>
|
<li>follow-up spawn: {worker.capabilities.can_spawn_followup ? 'available' : 'unsupported'}</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
@ -461,7 +485,7 @@
|
||||||
id="worker-console-message"
|
id="worker-console-message"
|
||||||
aria-label="Console input"
|
aria-label="Console input"
|
||||||
bind:value={draft}
|
bind:value={draft}
|
||||||
disabled={!worker?.capabilities.can_accept_input || sending}
|
disabled={!inputReady || sending}
|
||||||
></textarea>
|
></textarea>
|
||||||
<div class="composer-actions">
|
<div class="composer-actions">
|
||||||
<button type="submit" disabled={!canSend}>{sending ? 'Sending…' : 'Send'}</button>
|
<button type="submit" disabled={!canSend}>{sending ? 'Sending…' : 'Send'}</button>
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user