blob: 9c817d82cb5c081a126db99c574f68264b00a2d1 [file] [log] [blame]
<html>
<head>
<title>sketch-timeline demo</title>
<link rel="stylesheet" href="demo.css" />
<script type="module" src="../sketch-timeline.ts"></script>
<script>
const messages = [
{
type: "user",
content: "a user message",
timestamp: "2025-04-14T16:39:30.639533919Z",
conversation_id: "conv-123456",
idx: 0,
},
{
type: "agent",
content: "an agent message with usage information",
timestamp: "2025-04-14T16:39:31.639533919Z",
conversation_id: "conv-123456",
idx: 1,
usage: {
input_tokens: 4,
cache_creation_input_tokens: 2620,
cache_read_input_tokens: 0,
output_tokens: 106,
cost_usd: 0.011427,
},
},
{
type: "agent",
content: "an agent message with a single tool call",
timestamp: "2025-04-14T16:39:32.639533919Z",
conversation_id: "conv-123456",
idx: 2,
tool_calls: [
{
name: "bash",
input: 'find . -type f -name "*.go" | wc -l',
tool_call_id: "call_12345",
args: '{"command": "find . -type f -name \\"*.go\\" | wc -l"}',
result: "486",
},
],
},
{
type: "agent",
content:
"an agent message with a bash command that is extremely long and would create a horizontal scrollbar",
timestamp: "2025-04-14T16:39:32.739533919Z",
conversation_id: "conv-123456",
idx: 2.5,
tool_calls: [
{
name: "bash",
input:
'find /app -type f -name "*.ts" -o -name "*.js" -o -name "*.tsx" -o -name "*.jsx" | xargs grep -l "useState" | while read file; do echo "File: $file"; grep -n "useState" $file | head -5; echo; done | head -50',
tool_call_id: "call_verylongbash",
args: '{"command": "find /app -type f -name \\"*.ts\\" -o -name \\"*.js\\" -o -name \\"*.tsx\\" -o -name \\"*.jsx\\" | xargs grep -l \\"useState\\" | while read file; do echo \\"File: $file\\"; grep -n \\"useState\\" $file | head -5; echo; done | head -50"}',
result:
'File: /app/webui/src/web-components/sketch-chat-input.ts\n97: useState,\n\nFile: /app/webui/src/web-components/sketch-diff-view.ts\n47:import { createRef, ref, useState } from "lit/directives/ref.js";\n110: const [selectedFiles, setSelectedFiles] = useState([]);\n',
},
],
},
{
type: "agent",
content:
"an agent message with a bash command that has a very long output that would create a horizontal scrollbar",
timestamp: "2025-04-14T16:39:32.839533919Z",
conversation_id: "conv-123456",
idx: 2.7,
tool_calls: [
{
name: "bash",
input: "cat /app/webui/package.json | grep -A 5 dependencies",
tool_call_id: "call_longoutput",
args: '{"command": "cat /app/webui/package.json | grep -A 5 dependencies"}',
result:
' "dependencies": {\n "@xterm/addon-fit": "^0.10.0",\n "@xterm/xterm": "^5.5.0",\n "diff2html": "3.4.51",\n "lit": "^3.2.1",\n "marked": "^15.0.7",\n "mermaid": "^11.6.0",\n "sanitize-html": "^2.15.0",\n "vega": "^5.33.0",\n "vega-embed": "^6.29.0",\n "vega-lite": "^5.23.0",\n "react": "^18.2.0",\n "react-dom": "^18.2.0",\n "styled-components": "^6.1.8",\n "tailwindcss": "^3.4.1",\n "typescript": "^5.3.3",\n "zod": "^3.22.4",\n "@types/react": "^18.2.55",\n "@types/react-dom": "^18.2.19",\n "eslint": "^8.56.0",\n "prettier": "^3.2.5"\n },',
},
],
},
{
type: "agent",
content:
"an agent message with two tool calls that will show how the width behaves with very long content that should push the boundaries of the UI layout with really wide tool calls that might stretch beyond the regular message content width",
timestamp: "2025-04-14T16:39:33.639533919Z",
conversation_id: "conv-123456",
idx: 3,
tool_calls: [
{
name: "keyword_search",
input: "Search for files related to the timeline component",
tool_call_id: "call_67890",
args: '{"query": "Find all files related to the timeline component in the project", "search_terms": ["timeline", "message", "component", "web-components"]}',
result:
"Found 3 files: sketch-timeline.ts, sketch-timeline-message.ts, sketch-timeline.demo.html",
},
{
name: "patch",
input: "Update the timeline component CSS",
tool_call_id: "call_abcdef",
args: '{"path": "/app/webui/src/web-components/sketch-timeline.ts", "patches": [{"operation": "replace", "oldText": "width: 100%;", "newText": "width: auto; max-width: 100%;"}, {"operation": "replace", "oldText": "margin-bottom: 20px;", "newText": "margin-bottom: 24px;"}]}',
result: "Applied all patches successfully",
},
],
},
{
type: "user",
content: "another user message",
timestamp: "2025-04-14T16:39:34.639533919Z",
conversation_id: "conv-123456",
idx: 4,
},
{
type: "agent",
content: "an agent message with detailed information and usage data",
timestamp: "2025-04-14T16:39:35.639533919Z",
conversation_id: "conv-123456",
idx: 5,
usage: {
input_tokens: 125,
cache_creation_input_tokens: 0,
cache_read_input_tokens: 3050,
output_tokens: 245,
cost_usd: 0.023456,
},
},
{
type: "tool",
content: "a tool use message",
timestamp: "2025-04-14T16:39:36.639533919Z",
conversation_id: "conv-123456",
idx: 6,
},
{
type: "commit",
end_of_turn: false,
content: "",
commits: [
{
hash: "ece101c103ec231da87f4df05c1b5e6a24e13add",
subject: "Add README.md for web components directory",
body: "This adds documentation for the web components used in the Loop UI,\nincluding a description of each component, usage examples, and\ndevelopment guidelines.\n\nCo-Authored-By: sketch\nadd README.md for webui/src/web-components",
pushed_branch:
"sketch/create-readmemd-for-web-components-directory",
},
],
timestamp: "2025-04-14T16:39:37.639533919Z",
conversation_id: "conv-123456",
idx: 7,
},
{
type: "agent",
content: "an end-of-turn agent message",
end_of_turn: true,
timestamp: "2025-04-14T16:39:38.639533919Z",
conversation_id: "conv-123456",
idx: 8,
usage: {
input_tokens: 85,
cache_creation_input_tokens: 1240,
cache_read_input_tokens: 750,
output_tokens: 178,
cost_usd: 0.018976,
},
},
];
document.addEventListener("DOMContentLoaded", () => {
const appShell = document.querySelector(".app-shell");
const timelineEl = document.querySelector("sketch-timeline");
timelineEl.messages = messages;
timelineEl.scrollContainer = appShell;
const addMessagesCheckbox = document.querySelector("#addMessages");
addMessagesCheckbox.addEventListener("change", toggleAddMessages);
let addingMessages = false;
const addNewMessagesInterval = 1000;
function addNewMessages() {
if (!addingMessages) {
return;
}
const n = new Date().getMilliseconds() % messages.length;
const msgToDup = messages[n];
const dup = JSON.parse(JSON.stringify(msgToDup));
dup.idx = messages.length;
dup.timestamp = new Date().toISOString();
messages.push(dup);
timelineEl.messages = messages.concat();
timelineEl.prop;
timelineEl.requestUpdate();
}
let addMessagesHandler = setInterval(
addNewMessages,
addNewMessagesInterval,
);
function toggleAddMessages() {
addingMessages = !addingMessages;
if (addingMessages) {
} else {
}
}
});
</script>
<style>
.app-shell {
display: block;
font-family:
system-ui,
-apple-system,
BlinkMacSystemFont,
"Segoe UI",
Roboto,
sans-serif;
color: rgb(51, 51, 51);
line-height: 1.4;
min-height: 100vh;
width: 100%;
position: relative;
overflow-x: hidden;
}
.app-header {
flex-grow: 0;
}
.view-container {
flex-grow: 2;
}
</style>
</head>
<body>
<div class="app-shell">
<div class="app-header">
<h1>sketch-timeline demo</h1>
<input
type="checkbox"
id="addMessages"
title="Automatically add new messages"
/><label for="addMessages">Automatically add new messages</label>
</div>
<div class="view-container">
<div class="chat-view view-active">
<sketch-timeline></sketch-timeline>
</div>
</div>
</div>
</body>
</html>