ui: simplify worker console
This commit is contained in:
parent
05d39e05c7
commit
0602efd3b7
|
|
@ -694,67 +694,12 @@
|
||||||
color: var(--danger);
|
color: var(--danger);
|
||||||
}
|
}
|
||||||
|
|
||||||
.transcript-card,
|
.console-card,
|
||||||
.composer-card {
|
.composer-card {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: 1rem;
|
gap: 1rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.transcript-list {
|
|
||||||
display: grid;
|
|
||||||
gap: 0.85rem;
|
|
||||||
list-style: none;
|
|
||||||
margin: 0;
|
|
||||||
padding: 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
.transcript-item {
|
|
||||||
display: grid;
|
|
||||||
gap: 0.45rem;
|
|
||||||
padding: 0.85rem 1rem;
|
|
||||||
border-radius: 16px;
|
|
||||||
border: 1px solid var(--line);
|
|
||||||
background: var(--bg-raised);
|
|
||||||
}
|
|
||||||
|
|
||||||
.transcript-item.user {
|
|
||||||
margin-left: min(8vw, 4rem);
|
|
||||||
background: var(--bg-raised);
|
|
||||||
border-color: var(--line-strong);
|
|
||||||
}
|
|
||||||
|
|
||||||
.transcript-item.assistant {
|
|
||||||
margin-right: min(8vw, 4rem);
|
|
||||||
background: var(--bg-raised);
|
|
||||||
border-color: var(--line-strong);
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-meta {
|
|
||||||
display: flex;
|
|
||||||
flex-wrap: wrap;
|
|
||||||
align-items: center;
|
|
||||||
gap: 0.55rem;
|
|
||||||
color: var(--text-muted);
|
|
||||||
font-size: 0.78rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-meta strong {
|
|
||||||
color: var(--text-strong);
|
|
||||||
text-transform: uppercase;
|
|
||||||
letter-spacing: 0.05em;
|
|
||||||
}
|
|
||||||
|
|
||||||
.message-meta time {
|
|
||||||
margin-left: auto;
|
|
||||||
}
|
|
||||||
|
|
||||||
.transcript-item p {
|
|
||||||
margin: 0;
|
|
||||||
white-space: pre-wrap;
|
|
||||||
line-height: 1.55;
|
|
||||||
color: var(--code);
|
|
||||||
}
|
|
||||||
|
|
||||||
.empty-state {
|
.empty-state {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 1rem;
|
padding: 1rem;
|
||||||
|
|
@ -843,7 +788,20 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
.worker-console-shell {
|
.worker-console-shell {
|
||||||
grid-template-rows: auto minmax(0, 1fr) auto;
|
min-height: 100dvh;
|
||||||
|
padding-bottom: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.worker-console-shell > .console-body {
|
||||||
|
flex: 1 1 auto;
|
||||||
|
min-height: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
.console-header-actions {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: flex-end;
|
||||||
|
gap: var(--space-2);
|
||||||
}
|
}
|
||||||
|
|
||||||
.console-status-pill {
|
.console-status-pill {
|
||||||
|
|
@ -864,45 +822,45 @@
|
||||||
color: var(--warning);
|
color: var(--warning);
|
||||||
}
|
}
|
||||||
|
|
||||||
.console-grid {
|
.console-body {
|
||||||
display: grid;
|
display: flex;
|
||||||
grid-template-columns: minmax(0, 1fr) minmax(18rem, 26rem);
|
flex-direction: column;
|
||||||
gap: var(--space-4);
|
gap: var(--space-4);
|
||||||
min-height: 0;
|
min-height: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.transcript-toolbar {
|
.console-toolbar {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: flex-start;
|
align-items: flex-start;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
gap: var(--space-3);
|
gap: var(--space-3);
|
||||||
}
|
}
|
||||||
|
|
||||||
.worker-transcript {
|
.console-log {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: var(--space-3);
|
align-content: start;
|
||||||
max-height: min(68dvh, 50rem);
|
gap: var(--space-2);
|
||||||
|
max-height: none;
|
||||||
|
min-height: 0;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
padding: 0;
|
padding: 0;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
list-style: none;
|
list-style: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.worker-transcript li {
|
.console-log li {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: var(--space-2);
|
gap: var(--space-1);
|
||||||
border: 1px solid var(--line);
|
padding: 0.2rem 0;
|
||||||
border-radius: 14px;
|
background: transparent;
|
||||||
padding: 0.75rem 0.85rem;
|
|
||||||
background: var(--bg);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
.worker-transcript li.error-line {
|
.console-log li.error-line {
|
||||||
border-color: var(--danger);
|
color: var(--danger);
|
||||||
}
|
}
|
||||||
|
|
||||||
.message-heading {
|
.message-heading {
|
||||||
|
|
@ -910,8 +868,13 @@
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
gap: var(--space-2);
|
gap: var(--space-2);
|
||||||
color: var(--text-strong);
|
color: var(--text-muted);
|
||||||
font-weight: 800;
|
font-size: 0.78rem;
|
||||||
|
font-weight: 750;
|
||||||
|
}
|
||||||
|
|
||||||
|
.message-heading.streaming-heading {
|
||||||
|
justify-content: flex-start;
|
||||||
}
|
}
|
||||||
|
|
||||||
.message-heading small {
|
.message-heading small {
|
||||||
|
|
@ -922,7 +885,7 @@
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
.worker-transcript pre {
|
.console-log pre {
|
||||||
max-width: 100%;
|
max-width: 100%;
|
||||||
margin: 0;
|
margin: 0;
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
|
|
@ -942,15 +905,31 @@
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
}
|
}
|
||||||
|
|
||||||
.console-side-card {
|
.console-side-panel {
|
||||||
align-content: start;
|
position: fixed;
|
||||||
|
top: 0;
|
||||||
|
right: 0;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 5;
|
||||||
display: grid;
|
display: grid;
|
||||||
|
align-content: start;
|
||||||
gap: var(--space-4);
|
gap: var(--space-4);
|
||||||
min-width: 0;
|
width: min(32rem, 100vw);
|
||||||
|
padding: var(--space-6);
|
||||||
|
overflow-y: auto;
|
||||||
|
border-left: 1px solid var(--line);
|
||||||
|
background: var(--bg);
|
||||||
}
|
}
|
||||||
|
|
||||||
.console-side-card dl,
|
.side-panel-header {
|
||||||
.console-side-card ul {
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
justify-content: space-between;
|
||||||
|
gap: var(--space-3);
|
||||||
|
}
|
||||||
|
|
||||||
|
.console-side-panel dl,
|
||||||
|
.console-side-panel ul {
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: var(--space-2);
|
gap: var(--space-2);
|
||||||
margin: 0;
|
margin: 0;
|
||||||
|
|
@ -958,7 +937,7 @@
|
||||||
list-style: none;
|
list-style: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.console-side-card dt {
|
.console-side-panel dt {
|
||||||
color: var(--text-muted);
|
color: var(--text-muted);
|
||||||
font-size: 0.72rem;
|
font-size: 0.72rem;
|
||||||
font-weight: 800;
|
font-weight: 800;
|
||||||
|
|
@ -966,20 +945,21 @@
|
||||||
text-transform: uppercase;
|
text-transform: uppercase;
|
||||||
}
|
}
|
||||||
|
|
||||||
.console-side-card dd {
|
.console-side-panel dd {
|
||||||
margin: 0;
|
margin: 0;
|
||||||
color: var(--text-strong);
|
color: var(--text-strong);
|
||||||
font-weight: 700;
|
font-weight: 700;
|
||||||
}
|
}
|
||||||
|
|
||||||
.console-composer {
|
.console-composer {
|
||||||
|
position: sticky;
|
||||||
|
bottom: 0;
|
||||||
|
z-index: 2;
|
||||||
display: grid;
|
display: grid;
|
||||||
gap: var(--space-3);
|
gap: var(--space-3);
|
||||||
}
|
margin-inline: calc(-1 * var(--space-6));
|
||||||
|
padding: var(--space-3) var(--space-6) var(--space-4);
|
||||||
.console-composer label {
|
background: var(--bg);
|
||||||
color: var(--text-strong);
|
|
||||||
font-weight: 800;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.console-composer textarea {
|
.console-composer textarea {
|
||||||
|
|
@ -999,10 +979,6 @@
|
||||||
}
|
}
|
||||||
|
|
||||||
@media (max-width: 960px) {
|
@media (max-width: 960px) {
|
||||||
.console-grid {
|
|
||||||
grid-template-columns: 1fr;
|
|
||||||
}
|
|
||||||
|
|
||||||
.console-header {
|
.console-header {
|
||||||
flex-direction: column;
|
flex-direction: column;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ Deno.test("segmentsToText preserves protocol segment semantics", () => {
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
Deno.test("projectConsole keeps transcript and protocol-derived event rows distinct", () => {
|
Deno.test("projectConsole projects initial console output and live protocol rows", () => {
|
||||||
const projection = projectConsole(
|
const projection = projectConsole(
|
||||||
[
|
[
|
||||||
{
|
{
|
||||||
|
|
@ -101,15 +101,15 @@ Deno.test("projectConsole keeps transcript and protocol-derived event rows disti
|
||||||
|
|
||||||
assert(
|
assert(
|
||||||
projection.lines.some((line) =>
|
projection.lines.some((line) =>
|
||||||
line.source === "transcript" && line.kind === "user"
|
line.source === "initial" && line.kind === "user"
|
||||||
),
|
),
|
||||||
"transcript user row expected",
|
"initial user row expected",
|
||||||
);
|
);
|
||||||
assert(
|
assert(
|
||||||
projection.lines.some((line) =>
|
projection.lines.some((line) =>
|
||||||
line.source === "event" && line.kind === "assistant"
|
line.source === "live" && line.kind === "assistant"
|
||||||
),
|
),
|
||||||
"assistant event row expected",
|
"assistant live row expected",
|
||||||
);
|
);
|
||||||
assert(
|
assert(
|
||||||
projection.lines.some((line) => line.kind === "thinking"),
|
projection.lines.some((line) => line.kind === "thinking"),
|
||||||
|
|
@ -133,7 +133,7 @@ Deno.test("projectConsole keeps transcript and protocol-derived event rows disti
|
||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
Deno.test("projectConsole displays snapshot and in-flight state", () => {
|
Deno.test("projectConsole uses snapshot for state without rendering it as console output", () => {
|
||||||
const projection = projectConsole([], [
|
const projection = projectConsole([], [
|
||||||
{
|
{
|
||||||
cursor: "20",
|
cursor: "20",
|
||||||
|
|
@ -171,8 +171,8 @@ Deno.test("projectConsole displays snapshot and in-flight state", () => {
|
||||||
|
|
||||||
assert(projection.status === "running", "snapshot should update status");
|
assert(projection.status === "running", "snapshot should update status");
|
||||||
assert(
|
assert(
|
||||||
projection.lines.some((line) => line.kind === "snapshot"),
|
!projection.lines.some((line) => line.title.includes("snapshot")),
|
||||||
"snapshot row expected",
|
"snapshot should not render as a console row",
|
||||||
);
|
);
|
||||||
assert(
|
assert(
|
||||||
projection.lines.filter((line) => line.kind === "in_flight").length === 2,
|
projection.lines.filter((line) => line.kind === "in_flight").length === 2,
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,6 @@ export type ConsoleLineKind =
|
||||||
| "status"
|
| "status"
|
||||||
| "error"
|
| "error"
|
||||||
| "usage"
|
| "usage"
|
||||||
| "snapshot"
|
|
||||||
| "in_flight"
|
| "in_flight"
|
||||||
| "system";
|
| "system";
|
||||||
|
|
||||||
|
|
@ -24,7 +23,7 @@ export type ConsoleLine = {
|
||||||
body: string;
|
body: string;
|
||||||
detail?: string;
|
detail?: string;
|
||||||
cursor?: string | null;
|
cursor?: string | null;
|
||||||
source: "transcript" | "event";
|
source: "initial" | "live";
|
||||||
streaming?: boolean;
|
streaming?: boolean;
|
||||||
error?: boolean;
|
error?: boolean;
|
||||||
};
|
};
|
||||||
|
|
@ -53,23 +52,22 @@ export function workerConsolePath(runtimeId: string, workerId: string): string {
|
||||||
return workerConsoleHref({ runtime_id: runtimeId, worker_id: workerId });
|
return workerConsoleHref({ runtime_id: runtimeId, worker_id: workerId });
|
||||||
}
|
}
|
||||||
|
|
||||||
export function transcriptLines(items: WorkerTranscriptItem[]): ConsoleLine[] {
|
export function initialConsoleLines(items: WorkerTranscriptItem[]): ConsoleLine[] {
|
||||||
return items.map((item) => ({
|
return items.map((item) => ({
|
||||||
id: `transcript-${item.event_id}-${item.sequence}`,
|
id: `initial-${item.event_id}-${item.sequence}`,
|
||||||
kind: transcriptRoleKind(item.role),
|
kind: initialRoleKind(item.role),
|
||||||
title: `${item.role} · transcript #${item.sequence}`,
|
title: item.role,
|
||||||
body: item.content,
|
body: item.content,
|
||||||
detail: `event ${item.event_id}`,
|
source: "initial",
|
||||||
source: "transcript",
|
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function projectConsole(
|
export function projectConsole(
|
||||||
transcript: WorkerTranscriptItem[],
|
initialItems: WorkerTranscriptItem[],
|
||||||
events: Array<{ cursor: string; event: ProtocolEvent }> = [],
|
events: Array<{ cursor: string; event: ProtocolEvent }> = [],
|
||||||
): ConsoleProjection {
|
): ConsoleProjection {
|
||||||
return events.reduce(applyProtocolEvent, {
|
return events.reduce(applyProtocolEvent, {
|
||||||
lines: transcriptLines(transcript),
|
lines: initialConsoleLines(initialItems),
|
||||||
status: null,
|
status: null,
|
||||||
usage: null,
|
usage: null,
|
||||||
lastCursor: null,
|
lastCursor: null,
|
||||||
|
|
@ -208,15 +206,6 @@ export function applyProtocolEvent(
|
||||||
break;
|
break;
|
||||||
case "snapshot":
|
case "snapshot":
|
||||||
next.status = event.data.status;
|
next.status = event.data.status;
|
||||||
next.lines.push(
|
|
||||||
line(
|
|
||||||
envelope.cursor,
|
|
||||||
"snapshot",
|
|
||||||
`snapshot · ${event.data.status}`,
|
|
||||||
`${event.data.entries.length} entries · ${event.data.greeting.provider} / ${event.data.greeting.model}`,
|
|
||||||
`${event.data.greeting.worker_name} · context ${event.data.greeting.context_tokens}/${event.data.greeting.context_window}`,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
for (const block of event.data.in_flight?.blocks ?? []) {
|
for (const block of event.data.in_flight?.blocks ?? []) {
|
||||||
next.lines.push(inFlightLine(envelope.cursor, block));
|
next.lines.push(inFlightLine(envelope.cursor, block));
|
||||||
}
|
}
|
||||||
|
|
@ -443,7 +432,7 @@ export function segmentsToText(segments: Segment[]): string {
|
||||||
.join("\n");
|
.join("\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
function transcriptRoleKind(role: string): ConsoleLineKind {
|
function initialRoleKind(role: string): ConsoleLineKind {
|
||||||
if (role === "user" || role === "assistant" || role === "system") {
|
if (role === "user" || role === "assistant" || role === "system") {
|
||||||
return role;
|
return role;
|
||||||
}
|
}
|
||||||
|
|
@ -466,7 +455,7 @@ function line(
|
||||||
body,
|
body,
|
||||||
detail,
|
detail,
|
||||||
cursor,
|
cursor,
|
||||||
source: "event",
|
source: "live",
|
||||||
streaming,
|
streaming,
|
||||||
error,
|
error,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -38,6 +38,7 @@
|
||||||
let sendError = $state<string | null>(null);
|
let sendError = $state<string | null>(null);
|
||||||
let streamState = $state<'connecting' | 'open' | 'closed' | 'error'>('connecting');
|
let streamState = $state<'connecting' | 'open' | 'closed' | 'error'>('connecting');
|
||||||
let streamDiagnostics = $state<Diagnostic[]>([]);
|
let streamDiagnostics = $state<Diagnostic[]>([]);
|
||||||
|
let workerDetailsOpen = $state(false);
|
||||||
let observedEvents = $state<Array<{ cursor: string; event: ClientWorkerEventWsFrame & { kind: 'event' } }>>([]);
|
let observedEvents = $state<Array<{ cursor: string; event: ClientWorkerEventWsFrame & { kind: 'event' } }>>([]);
|
||||||
let nextReloadToken = 0;
|
let nextReloadToken = 0;
|
||||||
let reloadToken = $state(0);
|
let reloadToken = $state(0);
|
||||||
|
|
@ -138,11 +139,6 @@
|
||||||
return nextReloadToken;
|
return nextReloadToken;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function refreshConsole() {
|
|
||||||
advanceReloadToken();
|
|
||||||
await loadConsoleData(consoleTarget);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function sendMessage(event: SubmitEvent) {
|
async function sendMessage(event: SubmitEvent) {
|
||||||
event.preventDefault();
|
event.preventDefault();
|
||||||
const content = draft.trim();
|
const content = draft.trim();
|
||||||
|
|
@ -283,33 +279,27 @@
|
||||||
<main class="shell console-shell worker-console-shell">
|
<main class="shell console-shell worker-console-shell">
|
||||||
<section class="console-header card">
|
<section class="console-header card">
|
||||||
<div>
|
<div>
|
||||||
<p class="eyebrow">Worker attach Console</p>
|
|
||||||
<h2>{worker?.label ?? workerId}</h2>
|
<h2>{worker?.label ?? workerId}</h2>
|
||||||
<p class="section-note">
|
|
||||||
Target authority is <code>runtime_id</code> + <code>worker_id</code>. Browser traffic uses Workspace Backend Worker APIs only;
|
|
||||||
Runtime endpoints, credentials, socket paths, and session paths are not exposed.
|
|
||||||
</p>
|
|
||||||
</div>
|
</div>
|
||||||
<div class="console-status-pill" class:warn={streamState !== 'open'}>
|
<div class="console-header-actions">
|
||||||
{worker?.state ?? 'unknown'} · {worker?.status ?? 'loading'} · stream {streamState}
|
<div class="console-status-pill" class:warn={streamState !== 'open'}>
|
||||||
|
{worker?.state ?? 'unknown'} · {worker?.status ?? 'loading'} · stream {streamState}
|
||||||
|
</div>
|
||||||
|
<button type="button" class="secondary-button" aria-expanded={workerDetailsOpen} onclick={() => workerDetailsOpen = !workerDetailsOpen}>
|
||||||
|
Details
|
||||||
|
</button>
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
|
|
||||||
<section class="console-grid">
|
<section class="console-body">
|
||||||
<article class="card transcript-card worker-transcript-card">
|
<article class="card console-card worker-console-card">
|
||||||
<header class="transcript-toolbar">
|
{#if projection.status || projection.usage}
|
||||||
<div>
|
<p class="section-note">
|
||||||
<h3>Transcript and protocol events</h3>
|
{#if projection.status}status: {projection.status}{/if}
|
||||||
{#if projection.status || projection.usage}
|
{#if projection.status && projection.usage} · {/if}
|
||||||
<p class="section-note">
|
{#if projection.usage}usage: {projection.usage}{/if}
|
||||||
{#if projection.status}status: {projection.status}{/if}
|
</p>
|
||||||
{#if projection.status && projection.usage} · {/if}
|
{/if}
|
||||||
{#if projection.usage}usage: {projection.usage}{/if}
|
|
||||||
</p>
|
|
||||||
{/if}
|
|
||||||
</div>
|
|
||||||
<button type="button" class="secondary-button" onclick={refreshConsole}>Refresh</button>
|
|
||||||
</header>
|
|
||||||
|
|
||||||
{#if workerError}
|
{#if workerError}
|
||||||
<p class="error">{workerError}</p>
|
<p class="error">{workerError}</p>
|
||||||
|
|
@ -319,21 +309,26 @@
|
||||||
{/if}
|
{/if}
|
||||||
|
|
||||||
{#if lines.length === 0}
|
{#if lines.length === 0}
|
||||||
<p>No transcript items or observation events are available for this Worker yet.</p>
|
<p>No console output is available for this Worker yet.</p>
|
||||||
{:else}
|
{:else}
|
||||||
<ol class="transcript worker-transcript">
|
<ol class="console-log">
|
||||||
{#each lines as item}
|
{#each lines as item}
|
||||||
<li class:assistant={lineClass(item) === 'assistant'} class:user={lineClass(item) === 'user'} class:system={lineClass(item) !== 'assistant' && lineClass(item) !== 'user'} class:error-line={item.error}>
|
<li class:assistant={lineClass(item) === 'assistant'} class:user={lineClass(item) === 'user'} class:system={lineClass(item) !== 'assistant' && lineClass(item) !== 'user'} class:error-line={item.error}>
|
||||||
<div class="message-heading">
|
{#if lineClass(item) !== 'assistant' && lineClass(item) !== 'user'}
|
||||||
<span>{item.title}</span>
|
<div class="message-heading">
|
||||||
<small>{item.source}{item.streaming ? ' · streaming' : ''}</small>
|
<span>{item.title}</span>
|
||||||
</div>
|
{#if item.streaming}<small>streaming</small>{/if}
|
||||||
|
</div>
|
||||||
|
{:else if item.streaming}
|
||||||
|
<div class="message-heading streaming-heading">
|
||||||
|
<small>streaming</small>
|
||||||
|
</div>
|
||||||
|
{/if}
|
||||||
<pre>{item.body || '—'}</pre>
|
<pre>{item.body || '—'}</pre>
|
||||||
{#if item.detail || item.cursor}
|
{#if item.detail}
|
||||||
<details class="message-detail">
|
<details class="message-detail">
|
||||||
<summary>metadata</summary>
|
<summary>detail</summary>
|
||||||
{#if item.detail}<p>{item.detail}</p>{/if}
|
<p>{item.detail}</p>
|
||||||
{#if item.cursor}<code>{item.cursor}</code>{/if}
|
|
||||||
</details>
|
</details>
|
||||||
{/if}
|
{/if}
|
||||||
</li>
|
</li>
|
||||||
|
|
@ -342,8 +337,14 @@
|
||||||
{/if}
|
{/if}
|
||||||
</article>
|
</article>
|
||||||
|
|
||||||
<aside class="console-side-card card">
|
</section>
|
||||||
<h3>Worker detail</h3>
|
|
||||||
|
{#if workerDetailsOpen}
|
||||||
|
<aside class="console-side-panel" aria-label="Worker detail">
|
||||||
|
<header class="side-panel-header">
|
||||||
|
<h3>Worker detail</h3>
|
||||||
|
<button type="button" class="secondary-button" onclick={() => workerDetailsOpen = false}>Close</button>
|
||||||
|
</header>
|
||||||
{#if worker}
|
{#if worker}
|
||||||
<dl>
|
<dl>
|
||||||
<div>
|
<div>
|
||||||
|
|
@ -398,14 +399,13 @@
|
||||||
</details>
|
</details>
|
||||||
{/if}
|
{/if}
|
||||||
</aside>
|
</aside>
|
||||||
</section>
|
{/if}
|
||||||
|
|
||||||
<form class="console-composer card" onsubmit={sendMessage}>
|
<form class="console-composer card" onsubmit={sendMessage}>
|
||||||
<label for="worker-console-message">Send user input</label>
|
|
||||||
<textarea
|
<textarea
|
||||||
id="worker-console-message"
|
id="worker-console-message"
|
||||||
|
aria-label="Console input"
|
||||||
bind:value={draft}
|
bind:value={draft}
|
||||||
placeholder={worker?.capabilities.can_accept_input ? 'Message this Worker through the Backend input API…' : 'Input is unsupported for this Worker'}
|
|
||||||
disabled={!worker?.capabilities.can_accept_input || sending}
|
disabled={!worker?.capabilities.can_accept_input || sending}
|
||||||
></textarea>
|
></textarea>
|
||||||
<div class="composer-actions">
|
<div class="composer-actions">
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,8 @@ export default defineConfig({
|
||||||
proxy: {
|
proxy: {
|
||||||
'/api': {
|
'/api': {
|
||||||
target: 'http://127.0.0.1:8787',
|
target: 'http://127.0.0.1:8787',
|
||||||
changeOrigin: true
|
changeOrigin: true,
|
||||||
|
ws: true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user