Skip to content

Commit

Permalink
[bbrt] Compact/expandable tool calls (#4140)
Browse files Browse the repository at this point in the history
Tool calls are now one concise line, with an expander to see all the
details.

Also:
- Ellipsis loading indication on completions/tool calls
- The prompt now shakes if you try and send a message but the chat is
not ready to receive it.
- System prompt improvements.
- Improved error handling.
- Various CSS improvements/cleanup.
  • Loading branch information
aomarks authored Jan 16, 2025
1 parent 464c0a7 commit 9bb5021
Show file tree
Hide file tree
Showing 14 changed files with 385 additions and 182 deletions.
5 changes: 5 additions & 0 deletions .changeset/brave-pots-cross.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
"@breadboard-ai/bbrt": patch
---

Tool calls are now one concise line, with an expander to see all the details.
1 change: 0 additions & 1 deletion packages/bbrt/src/breadboard/breadboard-component-tool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,6 @@ export class BreadboardComponentTool implements BBRTTool {
);
return {
result: this.#execute(invocation),
render: () => invocation.render(),
};
}

Expand Down
1 change: 0 additions & 1 deletion packages/bbrt/src/breadboard/breadboard-tool.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,6 @@ export class BreadboardTool implements BBRTTool {
);
return {
result: this.#execute(invocation),
render: () => invocation.render(),
};
}

Expand Down
29 changes: 19 additions & 10 deletions packages/bbrt/src/components/artifact-display.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import type { GraphDescriptor } from "@google-labs/breadboard";
import { SignalWatcher } from "@lit-labs/signals";
import { LitElement, css, html, nothing } from "lit";
import { customElement, property } from "lit/decorators.js";
import { until } from "lit/directives/until.js";
import type { ArtifactEntry } from "../artifacts/artifact-store.js";
import "./board-visualizer.js";
import "./markdown-viewer.js";
Expand All @@ -30,6 +29,10 @@ export class BBRTArtifactDisplay extends SignalWatcher(LitElement) {
padding: 24px;
margin-top: 0;
}
#error {
padding: 20px;
min-width: 0;
}
`;

override render() {
Expand All @@ -48,15 +51,21 @@ export class BBRTArtifactDisplay extends SignalWatcher(LitElement) {
return html`<div>Internal error: Missing Blob</div>`;
}
if (blob.type === "application/vnd.breadboard.board") {
return until(
this.artifact.json.complete.then((graph) => {
return html`
<bbrt-board-visualizer
.graph=${graph as GraphDescriptor}
></bbrt-board-visualizer>
`;
})
);
if (this.artifact.json.status === "complete") {
const graph = this.artifact.json.value as GraphDescriptor;
return html`
<bbrt-board-visualizer .graph=${graph}></bbrt-board-visualizer>
`;
} else if (this.artifact.json.status === "error") {
return html`
<div id="error">
<bbrt-error-message
class="error"
.error=${this.artifact.json.error}
></bbrt-error-message>
</div>
`;
}
}
if (blob.type === "text/markdown") {
return html`
Expand Down
77 changes: 43 additions & 34 deletions packages/bbrt/src/components/chat-message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@
import { SignalWatcher } from "@lit-labs/signals";
import { LitElement, css, html, nothing } from "lit";
import { customElement, property } from "lit/decorators.js";
import { classMap } from "lit/directives/class-map.js";
import { CutEvent, EditEvent, ForkEvent, RetryEvent } from "../llm/events.js";
import type { ReactiveTurnState } from "../state/turn.js";
import { iconButtonStyle } from "../style/icon-button.js";
import { loadingEllipsisStyle } from "../style/loading-ellipsis.js";
import { connectedEffect } from "../util/connected-effect.js";
import "./error-message.js";
import "./markdown.js";
Expand All @@ -29,47 +31,34 @@ export class BBRTChatMessage extends SignalWatcher(LitElement) {

static override styles = [
iconButtonStyle,
loadingEllipsisStyle,
css`
:host {
--icon-size: 24px;
--pad-size: 24px;
font-family: Helvetica, sans-serif;
position: relative;
display: grid;
grid-template-areas:
"icon pad markdown"
"icon pad toolcalls"
"icon pad errors"
"icon pad actions";
grid-template-areas: "icon pad content";
grid-template-columns: var(--icon-size) var(--pad-size) 1fr;
grid-template-rows: min-content;
}
:host::part(icon) {
grid-area: icon;
}
:host::part(markdown) {
grid-area: markdown;
overflow-x: auto;
}
:host::part(toolcalls) {
grid-area: toolcalls;
overflow-x: auto;
}
:host::part(errors) {
grid-area: errors;
overflow-x: auto;
}
:host::part(actions) {
grid-area: actions;
overflow-x: auto;
}
bbrt-tool-call:not(:first-child) {
margin-top: 20px;
}
/* Icon styling */
#content {
grid-area: content;
min-width: 0;
}
:host::part(error) {
margin-bottom: 20px;
}
/* Icon */
:host::part(icon) {
grid-area: icon;
width: var(--icon-size);
aspect-ratio: 1;
}
Expand All @@ -92,8 +81,9 @@ export class BBRTChatMessage extends SignalWatcher(LitElement) {
animation: throb 0.5s 1;
}
:host::part(icon-hide) {
opacity: 20%;
scale: 50%;
opacity: 40%;
scale: 20%;
filter: grayscale(100%);
}
@keyframes throb {
0%,
Expand All @@ -111,7 +101,7 @@ export class BBRTChatMessage extends SignalWatcher(LitElement) {
height: min-content;
width: min-content;
position: relative;
margin: 4px auto 12px -10px;
margin: -10px auto 10px -7px;
display: flex;
}
:host(:hover) #actions,
Expand Down Expand Up @@ -144,6 +134,10 @@ export class BBRTChatMessage extends SignalWatcher(LitElement) {
#cutButton {
--bb-icon: var(--bb-icon-content-cut);
}
.loading-ellipsis {
color: #b8b8b8;
}
`,
];

Expand All @@ -160,19 +154,32 @@ export class BBRTChatMessage extends SignalWatcher(LitElement) {
}
return [
this.#renderRoleIcon(),
this.#renderMarkdown(),
this.#renderToolCalls(),
this.#renderErrors(),
this.#renderActions(),
html`<div id="content">
${[
this.#renderMarkdown(),
this.#renderToolCalls(),
this.#renderErrors(),
this.#renderActions(),
this.#renderEllipsisIfPending(),
]}
</div>`,
];
}

#renderEllipsisIfPending() {
return this.info?.turn.status === "pending"
? html`<span class="loading-ellipsis"></span>`
: nothing;
}

#renderRoleIcon() {
if (!this.info) {
return nothing;
}
const role = this.info.turn.role;
return html`<svg
id="role-icon"
class=${classMap({ hidden: this.info.hideIcon })}
aria-label="${role}"
role="img"
part="icon icon-${role} icon-${this.info.turn.status} ${this.info.hideIcon
Expand Down Expand Up @@ -277,7 +284,9 @@ export class BBRTChatMessage extends SignalWatcher(LitElement) {
></button>
</div>`);
}
return html`<div id="actions" part="actions">${buttons}</div>`;
return buttons.length > 0
? html`<div id="actions" part="actions">${buttons}</div>`
: nothing;
}

#onClickEditButton() {
Expand Down
5 changes: 2 additions & 3 deletions packages/bbrt/src/components/chat.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,9 @@ export class BBRTChat extends SignalWatcher(LitElement) {

static override styles = css`
:host {
background: #fafafa;
display: block;
padding: 16px;
overflow-y: auto;
background: #fafdff;
padding: 16px 28px 16px 16px;
}
`;

Expand Down
1 change: 1 addition & 0 deletions packages/bbrt/src/components/error-message.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@ export class BBRTErrorMessage extends LitElement {
:host::part(error) {
background: #fff0ef;
padding: 12px 16px;
border: 1px solid red;
border-radius: 8px;
}
:host::part(message) {
Expand Down
4 changes: 1 addition & 3 deletions packages/bbrt/src/components/markdown.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,15 +18,13 @@ export class BBRTMarkdown extends LitElement {

static override styles = css`
:host {
display: block;
line-height: 1.4;
color: #222;
}
:first-child {
margin-top: 0;
}
:last-child {
margin-bottom: 0;
}
ol,
ul {
/* The default chrome value is 40px, which is weird since it doesn't scale
Expand Down
33 changes: 30 additions & 3 deletions packages/bbrt/src/components/prompt.ts
Original file line number Diff line number Diff line change
Expand Up @@ -107,11 +107,18 @@ export class BBRTPrompt extends SignalWatcher(LitElement) {
if (event.key === "Enter" && !event.shiftKey) {
event.preventDefault();
event.stopImmediatePropagation();
if (this.conversation?.status === "ready" && event.target.value) {
const textarea = event.target;
void this.conversation.send(textarea.value);
const textarea = this.#textarea.value;
const value = textarea?.value;
if (
value &&
this.conversation?.status === "ready" &&
event.target.value
) {
void this.conversation.send(value);
textarea.value = "";
textarea.style.setProperty("--num-lines", "1");
} else {
this.#shake();
}
}
}
Expand All @@ -135,6 +142,26 @@ export class BBRTPrompt extends SignalWatcher(LitElement) {
const numLines = Math.round(measure.scrollHeight / lineHeight);
textarea.style.setProperty("--num-lines", `${numLines}`);
}

#shake() {
const textarea = this.#textarea.value;
if (!textarea) {
return;
}
const numShakes = 3;
const distance = 3;
const duration = 200;
const keyframes = [];
keyframes.push({ transform: "translateX(0)" });
for (let i = 0; i < numShakes; i++) {
keyframes.push(
{ transform: `translateX(${-distance}px)` },
{ transform: `translateX(${distance}px)` }
);
}
keyframes.push({ transform: "translateX(0)" });
textarea.animate(keyframes, { duration, easing: "ease-in-out" });
}
}

declare global {
Expand Down
Loading

0 comments on commit 9bb5021

Please sign in to comment.