mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-02 04:48:36 +00:00
mac: bundle web chat assets
This commit is contained in:
@@ -0,0 +1,275 @@
|
||||
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
|
||||
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
|
||||
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
|
||||
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
|
||||
return c > 3 && r && Object.defineProperty(target, key, r), r;
|
||||
};
|
||||
import { html, LitElement } from "lit";
|
||||
import { customElement, property } from "lit/decorators.js";
|
||||
import { renderTool } from "../tools/index.js";
|
||||
import { formatUsage } from "../utils/format.js";
|
||||
import { i18n } from "../utils/i18n.js";
|
||||
import "./ThinkingBlock.js";
|
||||
let UserMessage = class UserMessage extends LitElement {
|
||||
createRenderRoot() {
|
||||
return this;
|
||||
}
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.style.display = "block";
|
||||
}
|
||||
render() {
|
||||
const content = typeof this.message.content === "string"
|
||||
? this.message.content
|
||||
: this.message.content.find((c) => c.type === "text")?.text || "";
|
||||
return html `
|
||||
<div class="flex justify-start mx-4">
|
||||
<div class="user-message-container py-2 px-4 rounded-xl">
|
||||
<markdown-block .content=${content}></markdown-block>
|
||||
${this.message.attachments && this.message.attachments.length > 0
|
||||
? html `
|
||||
<div class="mt-3 flex flex-wrap gap-2">
|
||||
${this.message.attachments.map((attachment) => html ` <attachment-tile .attachment=${attachment}></attachment-tile> `)}
|
||||
</div>
|
||||
`
|
||||
: ""}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
};
|
||||
__decorate([
|
||||
property({ type: Object })
|
||||
], UserMessage.prototype, "message", void 0);
|
||||
UserMessage = __decorate([
|
||||
customElement("user-message")
|
||||
], UserMessage);
|
||||
export { UserMessage };
|
||||
let AssistantMessage = class AssistantMessage extends LitElement {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.hideToolCalls = false;
|
||||
this.isStreaming = false;
|
||||
}
|
||||
createRenderRoot() {
|
||||
return this;
|
||||
}
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.style.display = "block";
|
||||
}
|
||||
render() {
|
||||
// Render content in the order it appears
|
||||
const orderedParts = [];
|
||||
for (const chunk of this.message.content) {
|
||||
if (chunk.type === "text" && chunk.text.trim() !== "") {
|
||||
orderedParts.push(html `<markdown-block .content=${chunk.text}></markdown-block>`);
|
||||
}
|
||||
else if (chunk.type === "thinking" && chunk.thinking.trim() !== "") {
|
||||
orderedParts.push(html `<thinking-block .content=${chunk.thinking} .isStreaming=${this.isStreaming}></thinking-block>`);
|
||||
}
|
||||
else if (chunk.type === "toolCall") {
|
||||
if (!this.hideToolCalls) {
|
||||
const tool = this.tools?.find((t) => t.name === chunk.name);
|
||||
const pending = this.pendingToolCalls?.has(chunk.id) ?? false;
|
||||
const result = this.toolResultsById?.get(chunk.id);
|
||||
// A tool call is aborted if the message was aborted and there's no result for this tool call
|
||||
const aborted = this.message.stopReason === "aborted" && !result;
|
||||
orderedParts.push(html `<tool-message
|
||||
.tool=${tool}
|
||||
.toolCall=${chunk}
|
||||
.result=${result}
|
||||
.pending=${pending}
|
||||
.aborted=${aborted}
|
||||
.isStreaming=${this.isStreaming}
|
||||
></tool-message>`);
|
||||
}
|
||||
}
|
||||
}
|
||||
return html `
|
||||
<div>
|
||||
${orderedParts.length ? html ` <div class="px-4 flex flex-col gap-3">${orderedParts}</div> ` : ""}
|
||||
${this.message.usage && !this.isStreaming
|
||||
? this.onCostClick
|
||||
? html ` <div class="px-4 mt-2 text-xs text-muted-foreground cursor-pointer hover:text-foreground transition-colors" @click=${this.onCostClick}>${formatUsage(this.message.usage)}</div> `
|
||||
: html ` <div class="px-4 mt-2 text-xs text-muted-foreground">${formatUsage(this.message.usage)}</div> `
|
||||
: ""}
|
||||
${this.message.stopReason === "error" && this.message.errorMessage
|
||||
? html `
|
||||
<div class="mx-4 mt-3 p-3 bg-destructive/10 text-destructive rounded-lg text-sm overflow-hidden">
|
||||
<strong>${i18n("Error:")}</strong> ${this.message.errorMessage}
|
||||
</div>
|
||||
`
|
||||
: ""}
|
||||
${this.message.stopReason === "aborted"
|
||||
? html `<span class="text-sm text-destructive italic">${i18n("Request aborted")}</span>`
|
||||
: ""}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
};
|
||||
__decorate([
|
||||
property({ type: Object })
|
||||
], AssistantMessage.prototype, "message", void 0);
|
||||
__decorate([
|
||||
property({ type: Array })
|
||||
], AssistantMessage.prototype, "tools", void 0);
|
||||
__decorate([
|
||||
property({ type: Object })
|
||||
], AssistantMessage.prototype, "pendingToolCalls", void 0);
|
||||
__decorate([
|
||||
property({ type: Boolean })
|
||||
], AssistantMessage.prototype, "hideToolCalls", void 0);
|
||||
__decorate([
|
||||
property({ type: Object })
|
||||
], AssistantMessage.prototype, "toolResultsById", void 0);
|
||||
__decorate([
|
||||
property({ type: Boolean })
|
||||
], AssistantMessage.prototype, "isStreaming", void 0);
|
||||
__decorate([
|
||||
property({ attribute: false })
|
||||
], AssistantMessage.prototype, "onCostClick", void 0);
|
||||
AssistantMessage = __decorate([
|
||||
customElement("assistant-message")
|
||||
], AssistantMessage);
|
||||
export { AssistantMessage };
|
||||
let ToolMessageDebugView = class ToolMessageDebugView extends LitElement {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.hasResult = false;
|
||||
}
|
||||
createRenderRoot() {
|
||||
return this; // light DOM for shared styles
|
||||
}
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.style.display = "block";
|
||||
}
|
||||
pretty(value) {
|
||||
try {
|
||||
if (typeof value === "string") {
|
||||
const maybeJson = JSON.parse(value);
|
||||
return { content: JSON.stringify(maybeJson, null, 2), isJson: true };
|
||||
}
|
||||
return { content: JSON.stringify(value, null, 2), isJson: true };
|
||||
}
|
||||
catch {
|
||||
return { content: typeof value === "string" ? value : String(value), isJson: false };
|
||||
}
|
||||
}
|
||||
render() {
|
||||
const textOutput = this.result?.content
|
||||
?.filter((c) => c.type === "text")
|
||||
.map((c) => c.text)
|
||||
.join("\n") || "";
|
||||
const output = this.pretty(textOutput);
|
||||
const details = this.pretty(this.result?.details);
|
||||
return html `
|
||||
<div class="mt-3 flex flex-col gap-2">
|
||||
<div>
|
||||
<div class="text-xs font-medium mb-1 text-muted-foreground">${i18n("Call")}</div>
|
||||
<code-block .code=${this.pretty(this.callArgs).content} language="json"></code-block>
|
||||
</div>
|
||||
<div>
|
||||
<div class="text-xs font-medium mb-1 text-muted-foreground">${i18n("Result")}</div>
|
||||
${this.hasResult
|
||||
? html `<code-block .code=${output.content} language="${output.isJson ? "json" : "text"}"></code-block>
|
||||
<code-block .code=${details.content} language="${details.isJson ? "json" : "text"}"></code-block>`
|
||||
: html `<div class="text-xs text-muted-foreground">${i18n("(no result)")}</div>`}
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
};
|
||||
__decorate([
|
||||
property({ type: Object })
|
||||
], ToolMessageDebugView.prototype, "callArgs", void 0);
|
||||
__decorate([
|
||||
property({ type: Object })
|
||||
], ToolMessageDebugView.prototype, "result", void 0);
|
||||
__decorate([
|
||||
property({ type: Boolean })
|
||||
], ToolMessageDebugView.prototype, "hasResult", void 0);
|
||||
ToolMessageDebugView = __decorate([
|
||||
customElement("tool-message-debug")
|
||||
], ToolMessageDebugView);
|
||||
export { ToolMessageDebugView };
|
||||
let ToolMessage = class ToolMessage extends LitElement {
|
||||
constructor() {
|
||||
super(...arguments);
|
||||
this.pending = false;
|
||||
this.aborted = false;
|
||||
this.isStreaming = false;
|
||||
}
|
||||
createRenderRoot() {
|
||||
return this;
|
||||
}
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.style.display = "block";
|
||||
}
|
||||
render() {
|
||||
const toolName = this.tool?.name || this.toolCall.name;
|
||||
// Render tool content (renderer handles errors and styling)
|
||||
const result = this.aborted
|
||||
? {
|
||||
role: "toolResult",
|
||||
isError: true,
|
||||
content: [],
|
||||
toolCallId: this.toolCall.id,
|
||||
toolName: this.toolCall.name,
|
||||
timestamp: Date.now(),
|
||||
}
|
||||
: this.result;
|
||||
const renderResult = renderTool(toolName, this.toolCall.arguments, result, !this.aborted && (this.isStreaming || this.pending));
|
||||
// Handle custom rendering (no card wrapper)
|
||||
if (renderResult.isCustom) {
|
||||
return renderResult.content;
|
||||
}
|
||||
// Default: wrap in card
|
||||
return html `
|
||||
<div class="p-2.5 border border-border rounded-md bg-card text-card-foreground shadow-xs">
|
||||
${renderResult.content}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
};
|
||||
__decorate([
|
||||
property({ type: Object })
|
||||
], ToolMessage.prototype, "toolCall", void 0);
|
||||
__decorate([
|
||||
property({ type: Object })
|
||||
], ToolMessage.prototype, "tool", void 0);
|
||||
__decorate([
|
||||
property({ type: Object })
|
||||
], ToolMessage.prototype, "result", void 0);
|
||||
__decorate([
|
||||
property({ type: Boolean })
|
||||
], ToolMessage.prototype, "pending", void 0);
|
||||
__decorate([
|
||||
property({ type: Boolean })
|
||||
], ToolMessage.prototype, "aborted", void 0);
|
||||
__decorate([
|
||||
property({ type: Boolean })
|
||||
], ToolMessage.prototype, "isStreaming", void 0);
|
||||
ToolMessage = __decorate([
|
||||
customElement("tool-message")
|
||||
], ToolMessage);
|
||||
export { ToolMessage };
|
||||
let AbortedMessage = class AbortedMessage extends LitElement {
|
||||
createRenderRoot() {
|
||||
return this;
|
||||
}
|
||||
connectedCallback() {
|
||||
super.connectedCallback();
|
||||
this.style.display = "block";
|
||||
}
|
||||
render() {
|
||||
return html `<span class="text-sm text-destructive italic">${i18n("Request aborted")}</span>`;
|
||||
}
|
||||
};
|
||||
AbortedMessage = __decorate([
|
||||
customElement("aborted-message")
|
||||
], AbortedMessage);
|
||||
export { AbortedMessage };
|
||||
//# sourceMappingURL=Messages.js.map
|
||||
Reference in New Issue
Block a user