blob: 805de6da43bf9f2971503bd28e85cd088e69a293 (
plain)
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
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
|
<script lang="ts">
import type { ToolCallDisplay } from "../types.js";
const { toolCall }: { toolCall: ToolCallDisplay } = $props();
let isExpanded = $state(false);
function toggle() {
isExpanded = !isExpanded;
}
interface ShellResult {
stdout: string;
stderr: string;
exitCode: number;
}
function parseShellResult(result: string): ShellResult | null {
try {
const parsed = JSON.parse(result) as unknown;
if (
parsed !== null &&
typeof parsed === "object" &&
"stdout" in parsed &&
"stderr" in parsed &&
"exitCode" in parsed
) {
return {
stdout: String((parsed as Record<string, unknown>).stdout ?? ""),
stderr: String((parsed as Record<string, unknown>).stderr ?? ""),
exitCode: Number((parsed as Record<string, unknown>).exitCode ?? 0),
};
}
return null;
} catch {
return null;
}
}
const isShell = $derived(toolCall.name === "run_shell");
const shellResult = $derived(
isShell && toolCall.result !== undefined ? parseShellResult(toolCall.result) : null,
);
</script>
<div class="collapse collapse-arrow mb-2 p-1 opacity-60 {isExpanded ? 'collapse-open' : ''}">
<button
type="button"
class="collapse-title flex items-center gap-2 text-sm italic cursor-pointer w-full text-left"
onclick={toggle}
aria-expanded={isExpanded}
>
<span class="badge badge-neutral badge-sm">tool</span>
<span class="font-mono">{toolCall.name}</span>
{#if toolCall.result !== undefined}
{#if isShell && shellResult !== null}
<span class="badge badge-sm ml-auto {shellResult.exitCode === 0 ? 'badge-success' : 'badge-error'}">
exit {shellResult.exitCode}
</span>
{:else if toolCall.isError}
<span class="badge badge-error badge-sm ml-auto">error</span>
{:else}
<span class="badge badge-success badge-sm ml-auto">done</span>
{/if}
{:else}
<span class="badge badge-warning badge-sm ml-auto">pending</span>
{/if}
</button>
<div class="collapse-content text-xs">
<div class="mt-2">
<p class="font-semibold text-base-content/70 mb-1">Arguments</p>
<pre class="bg-base-300 rounded p-2 overflow-auto max-h-40 whitespace-pre-wrap break-all">{JSON.stringify(toolCall.arguments, null, 2)}</pre>
</div>
{#if isShell && toolCall.result !== undefined}
{#if shellResult !== null}
<div class="mt-2">
<p class="font-semibold text-base-content/70 mb-1">stdout:</p>
<pre class="bg-base-300 rounded p-2 overflow-auto max-h-40 whitespace-pre-wrap break-all font-mono">{shellResult.stdout || "(empty)"}</pre>
</div>
{#if shellResult.stderr}
<div class="mt-2">
<p class="font-semibold text-error/80 mb-1">stderr:</p>
<pre class="bg-error/10 text-error rounded p-2 overflow-auto max-h-40 whitespace-pre-wrap break-all font-mono">{shellResult.stderr}</pre>
</div>
{/if}
<div class="mt-2 flex items-center gap-2">
<span class="font-semibold text-base-content/70">exit code:</span>
<span class="badge badge-sm {shellResult.exitCode === 0 ? 'badge-success' : 'badge-error'}">{shellResult.exitCode}</span>
</div>
{:else}
<div class="mt-2">
<p class="font-semibold text-base-content/70 mb-1">Result</p>
<pre class="rounded p-2 overflow-auto max-h-40 whitespace-pre-wrap break-all {toolCall.isError ? 'bg-error/20 text-error' : 'bg-base-300'}">{toolCall.result}</pre>
</div>
{/if}
{:else if isShell && toolCall.shellOutput}
{#if toolCall.shellOutput.stdout}
<div class="mt-2">
<p class="font-semibold text-base-content/70 mb-1">stdout</p>
<pre class="bg-base-300 rounded p-2 overflow-auto max-h-40 whitespace-pre-wrap break-all text-xs">{toolCall.shellOutput.stdout}</pre>
</div>
{/if}
{#if toolCall.shellOutput.stderr}
<div class="mt-2">
<p class="font-semibold text-error/70 mb-1">stderr</p>
<pre class="bg-error/10 rounded p-2 overflow-auto max-h-40 whitespace-pre-wrap break-all text-xs text-error">{toolCall.shellOutput.stderr}</pre>
</div>
{/if}
<span class="text-xs text-base-content/50 italic">Running...</span>
{:else if toolCall.result !== undefined}
<div class="mt-2">
<p class="font-semibold text-base-content/70 mb-1">Result</p>
<pre
class="rounded p-2 overflow-auto max-h-40 whitespace-pre-wrap break-all {toolCall.isError
? 'bg-error/20 text-error'
: 'bg-base-300'}">{toolCall.result}</pre>
</div>
{/if}
</div>
</div>
|