Spaces:
Running
Running
File size: 2,408 Bytes
bc7e9cd db9635c bc7e9cd db9635c bc7e9cd db9635c bc7e9cd |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 |
<script lang="ts">
import type { ChatMessage } from "../../models/chat-data";
import TextRenderer from "./TextRenderer.svelte";
import ToolBlock from "./segments/ToolBlock.svelte";
import TodoSegment from "./segments/TodoSegment.svelte";
import { filterToolCalls } from "../../utils/tool-call-parser";
export let message: ChatMessage;
$: hasSegments = message.segments && message.segments.length > 0;
$: isStreaming = message.streaming || (message.segments?.some(s => s.streaming));
// Normalize content for consistent rendering with tool call filtering
$: normalizedContent = hasSegments ? null : filterToolCalls(message.content || "");
// Filter segments for rendering
$: segmentsToRender = hasSegments ? message.segments!.filter((segment) => {
// Skip tool results that are paired with previous invocation (except todos)
if (segment.type === "tool-result") {
const isTodoTool = segment.toolName?.includes("task");
return isTodoTool;
}
return true;
}) : [];
</script>
<div class="message-content">
{#if normalizedContent !== null}
<!-- Fallback content rendering -->
<TextRenderer content={normalizedContent} streaming={isStreaming} />
{#if isStreaming}
<span class="streaming-indicator">●</span>
{/if}
{:else if hasSegments}
<!-- Segmented content rendering -->
{#each segmentsToRender as segment (segment.id)}
{#if segment.type === "text"}
<TextRenderer content={filterToolCalls(segment.content)} streaming={segment.streaming || false} />
{:else if segment.type === "tool-invocation"}
<ToolBlock
invocation={segment}
result={message.segments && message.segments[message.segments.indexOf(segment) + 1]?.type === "tool-result"
? message.segments[message.segments.indexOf(segment) + 1]
: null}
/>
{:else if segment.type === "tool-result" && segment.toolName?.includes("task")}
<TodoSegment {segment} />
{/if}
{/each}
{/if}
</div>
<style>
.message-content {
display: flex;
flex-direction: column;
gap: 0.125rem;
}
.streaming-indicator {
display: inline-block;
color: rgba(65, 105, 225, 0.8);
animation: pulse 1.5s ease-in-out infinite;
margin-left: 0.25rem;
}
@keyframes pulse {
0%, 100% {
opacity: 0.3;
}
50% {
opacity: 1;
}
}
</style> |