3838 No debug data stored for this turn.
3939 </div >
4040
41- <div
41+ <details
4242 v-for =" sequence in debugSequences"
4343 :key =" sequence.sequenceId"
4444 class =" rounded-xl border border-slate-200 bg-white p-4 shadow-sm dark:border-slate-700 dark:bg-slate-900"
4545 >
46- <div class =" flex flex-wrap items-start justify-between gap-3" >
47- <div >
48- <div class =" text-lg font-semibold text-slate-900 dark:text-white" >
49- Sequence #{{ sequence.sequenceId }}
50- </div >
51- <div class =" mt-1 text-xs text-slate-500 dark:text-slate-400" >
52- Started {{ formatTimestamp(sequence.startedAt) }}
53- <span v-if =" sequence.endedAt" > • Ended {{ formatTimestamp(sequence.endedAt) }}</span >
54- <span v-if =" sequenceDuration(sequence)" > • {{ sequenceDuration(sequence) }}</span >
46+ <summary class =" cursor-pointer list-none" >
47+ <div class =" flex flex-wrap items-start justify-between gap-3" >
48+ <div >
49+ <div class =" text-lg font-semibold text-slate-900 dark:text-white" >
50+ Sequence #{{ sequence.sequenceId }}
51+ </div >
52+ <div class =" mt-1 text-xs text-slate-500 dark:text-slate-400" >
53+ Started {{ formatTimestamp(sequence.startedAt) }}
54+ <span v-if =" sequence.endedAt" > • Ended {{ formatTimestamp(sequence.endedAt) }}</span >
55+ <span v-if =" sequenceDuration(sequence)" > • {{ sequenceDuration(sequence) }}</span >
56+ </div >
5557 </div >
56- </div >
5758
58- <div
59- class =" rounded-full px-3 py-1 text-xs font-semibold uppercase tracking-wide"
60- :class =" sequence.resultType === 'tool_calls'
61- ? 'bg-amber-100 text-amber-800 dark:bg-amber-900/50 dark:text-amber-200'
62- : 'bg-emerald-100 text-emerald-800 dark:bg-emerald-900/50 dark:text-emerald-200'"
63- >
64- {{ sequence.resultType.replace('_', ' ') }}
59+ <div class =" flex items-center gap-3" >
60+ <div
61+ class =" rounded-full px-3 py-1 text-xs font-semibold uppercase tracking-wide"
62+ :class =" sequence.resultType === 'tool_calls'
63+ ? 'bg-amber-100 text-amber-800 dark:bg-amber-900/50 dark:text-amber-200'
64+ : 'bg-emerald-100 text-emerald-800 dark:bg-emerald-900/50 dark:text-emerald-200'"
65+ >
66+ {{ sequence.resultType.replace('_', ' ') }}
67+ </div >
68+ <div class =" text-xs font-semibold uppercase tracking-[0.2em] text-slate-400 dark:text-slate-500" >
69+ Toggle
70+ </div >
71+ </div >
6572 </div >
66- </div >
73+ </summary >
6774
6875 <div class =" mt-4 grid gap-3 md:grid-cols-4" >
6976 <div class =" rounded-lg bg-slate-50 p-3 dark:bg-slate-800/70" >
93100 </div >
94101
95102 <section v-if =" sequence.prompt" class =" mt-4" >
96- <div class =" mb-2 text-xs font-semibold uppercase tracking-[0.2em] text-slate-500 dark:text-slate-400" >
97- Prompt Sent To LLM
103+ <div class =" mb-2 flex items-center justify-between gap-3" >
104+ <div class =" text-xs font-semibold uppercase tracking-[0.2em] text-slate-500 dark:text-slate-400" >
105+ Prompt Sent To LLM
106+ </div >
107+ <button
108+ type =" button"
109+ class =" rounded-md border border-slate-200 px-2.5 py-1 text-[11px] font-semibold text-slate-600 transition hover:bg-slate-100 dark:border-slate-700 dark:text-slate-300 dark:hover:bg-slate-800"
110+ @click =" copyText(`sequence-${sequence.sequenceId}-prompt`, sequence.prompt)"
111+ >
112+ {{ copyLabel(`sequence-${sequence.sequenceId}-prompt`) }}
113+ </button >
98114 </div >
99115 <pre class =" max-h-80 overflow-auto rounded-lg bg-slate-950 p-4 text-xs leading-6 text-sky-100 whitespace-pre-wrap" >{{ sequence.prompt }}</pre >
100116 </section >
101117
102118 <section v-if =" sequence.reasoning" class =" mt-4" >
103- <div class =" mb-2 text-xs font-semibold uppercase tracking-[0.2em] text-slate-500 dark:text-slate-400" >
104- Reasoning
119+ <div class =" mb-2 flex items-center justify-between gap-3" >
120+ <div class =" text-xs font-semibold uppercase tracking-[0.2em] text-slate-500 dark:text-slate-400" >
121+ Reasoning
122+ </div >
123+ <button
124+ type =" button"
125+ class =" rounded-md border border-slate-200 px-2.5 py-1 text-[11px] font-semibold text-slate-600 transition hover:bg-slate-100 dark:border-slate-700 dark:text-slate-300 dark:hover:bg-slate-800"
126+ @click =" copyText(`sequence-${sequence.sequenceId}-reasoning`, sequence.reasoning)"
127+ >
128+ {{ copyLabel(`sequence-${sequence.sequenceId}-reasoning`) }}
129+ </button >
105130 </div >
106131 <pre class =" max-h-80 overflow-auto rounded-lg bg-slate-950 p-4 text-xs leading-6 text-slate-100 whitespace-pre-wrap" >{{ sequence.reasoning }}</pre >
107132 </section >
108133
109134 <section v-if =" sequence.text" class =" mt-4" >
110- <div class =" mb-2 text-xs font-semibold uppercase tracking-[0.2em] text-slate-500 dark:text-slate-400" >
111- Text
135+ <div class =" mb-2 flex items-center justify-between gap-3" >
136+ <div class =" text-xs font-semibold uppercase tracking-[0.2em] text-slate-500 dark:text-slate-400" >
137+ Text
138+ </div >
139+ <button
140+ type =" button"
141+ class =" rounded-md border border-slate-200 px-2.5 py-1 text-[11px] font-semibold text-slate-600 transition hover:bg-slate-100 dark:border-slate-700 dark:text-slate-300 dark:hover:bg-slate-800"
142+ @click =" copyText(`sequence-${sequence.sequenceId}-text`, sequence.text)"
143+ >
144+ {{ copyLabel(`sequence-${sequence.sequenceId}-text`) }}
145+ </button >
112146 </div >
113147 <pre class =" max-h-80 overflow-auto rounded-lg bg-slate-100 p-4 text-xs leading-6 text-slate-800 whitespace-pre-wrap dark:bg-slate-800 dark:text-slate-100" >{{ sequence.text }}</pre >
114148 </section >
121155 <details
122156 v-for =" (toolCall, toolCallIndex) in sequence.toolCalls"
123157 :key =" `${sequence.sequenceId}-${toolCallIndex}-${toolCall.toolName}`"
124- :open =" toolCallIndex === 0"
125158 class =" overflow-hidden rounded-lg border border-slate-200 bg-slate-50 dark:border-slate-700 dark:bg-slate-800/60"
126159 >
127160 <summary class =" cursor-pointer list-none px-4 py-3" >
142175
143176 <div class =" grid gap-3 border-t border-slate-200 p-4 dark:border-slate-700" >
144177 <div >
145- <div class =" mb-2 text-xs font-semibold uppercase tracking-[0.2em] text-slate-500 dark:text-slate-400" >
146- Input YAML
178+ <div class =" mb-2 flex items-center justify-between gap-3" >
179+ <div class =" text-xs font-semibold uppercase tracking-[0.2em] text-slate-500 dark:text-slate-400" >
180+ Input YAML
181+ </div >
182+ <button
183+ type =" button"
184+ class =" rounded-md border border-slate-200 px-2.5 py-1 text-[11px] font-semibold text-slate-600 transition hover:bg-slate-100 dark:border-slate-700 dark:text-slate-300 dark:hover:bg-slate-800"
185+ @click =" copyText(`sequence-${sequence.sequenceId}-tool-${toolCall.toolCallId}-input`, toolCall.input)"
186+ >
187+ {{ copyLabel(`sequence-${sequence.sequenceId}-tool-${toolCall.toolCallId}-input`) }}
188+ </button >
147189 </div >
148190 <pre class =" max-h-72 overflow-auto rounded-lg bg-slate-950 p-4 text-xs leading-6 text-slate-100 whitespace-pre-wrap" >{{ toolCall.input }}</pre >
149191 </div >
150192
151193 <div v-if =" toolCall.output" >
152- <div class =" mb-2 text-xs font-semibold uppercase tracking-[0.2em] text-slate-500 dark:text-slate-400" >
153- Output YAML
194+ <div class =" mb-2 flex items-center justify-between gap-3" >
195+ <div class =" text-xs font-semibold uppercase tracking-[0.2em] text-slate-500 dark:text-slate-400" >
196+ Output YAML
197+ </div >
198+ <button
199+ type =" button"
200+ class =" rounded-md border border-slate-200 px-2.5 py-1 text-[11px] font-semibold text-slate-600 transition hover:bg-slate-100 dark:border-slate-700 dark:text-slate-300 dark:hover:bg-slate-800"
201+ @click =" copyText(`sequence-${sequence.sequenceId}-tool-${toolCall.toolCallId}-output`, toolCall.output)"
202+ >
203+ {{ copyLabel(`sequence-${sequence.sequenceId}-tool-${toolCall.toolCallId}-output`) }}
204+ </button >
154205 </div >
155206 <pre class =" max-h-72 overflow-auto rounded-lg bg-slate-950 p-4 text-xs leading-6 text-emerald-100 whitespace-pre-wrap" >{{ toolCall.output }}</pre >
156207 </div >
157208
158209 <div v-if =" toolCall.error" >
159- <div class =" mb-2 text-xs font-semibold uppercase tracking-[0.2em] text-rose-500 dark:text-rose-300" >
160- Error YAML
210+ <div class =" mb-2 flex items-center justify-between gap-3" >
211+ <div class =" text-xs font-semibold uppercase tracking-[0.2em] text-rose-500 dark:text-rose-300" >
212+ Error YAML
213+ </div >
214+ <button
215+ type =" button"
216+ class =" rounded-md border border-rose-200 px-2.5 py-1 text-[11px] font-semibold text-rose-600 transition hover:bg-rose-50 dark:border-rose-900/70 dark:text-rose-300 dark:hover:bg-rose-950/60"
217+ @click =" copyText(`sequence-${sequence.sequenceId}-tool-${toolCall.toolCallId}-error`, toolCall.error)"
218+ >
219+ {{ copyLabel(`sequence-${sequence.sequenceId}-tool-${toolCall.toolCallId}-error`) }}
220+ </button >
161221 </div >
162222 <pre class =" max-h-72 overflow-auto rounded-lg bg-rose-950 p-4 text-xs leading-6 text-rose-100 whitespace-pre-wrap" >{{ toolCall.error }}</pre >
163223 </div >
164224 </div >
165225 </details >
166226 </section >
167- </div >
227+ </details >
168228
169229 <details class =" rounded-xl border border-slate-200 bg-white p-4 shadow-sm dark:border-slate-700 dark:bg-slate-900" >
170- <summary class =" cursor-pointer text-sm font-semibold text-slate-900 dark:text-white" >
171- Raw JSON
230+ <summary class =" flex cursor-pointer items-center justify-between gap-3 text-sm font-semibold text-slate-900 dark:text-white" >
231+ <span >Raw JSON</span >
232+ <button
233+ type =" button"
234+ class =" rounded-md border border-slate-200 px-2.5 py-1 text-[11px] font-semibold text-slate-600 transition hover:bg-slate-100 dark:border-slate-700 dark:text-slate-300 dark:hover:bg-slate-800"
235+ @click.prevent.stop =" copyText('raw-json', rawJson)"
236+ >
237+ {{ copyLabel('raw-json') }}
238+ </button >
172239 </summary >
173240 <pre class =" mt-4 max-h-[32rem] overflow-auto rounded-lg bg-slate-950 p-4 text-xs leading-6 text-slate-100 whitespace-pre-wrap" >{{ rawJson }}</pre >
174241 </details >
175242 </div >
176243</template >
177244
178245<script setup lang="ts">
179- import { computed } from ' vue' ;
246+ import { computed , ref } from ' vue' ;
180247import type {
181248 AdminForthResourceColumnCommon ,
182249 AdminForthResourceCommon ,
@@ -225,6 +292,8 @@ const toolCallSequences = computed(() =>
225292);
226293
227294const rawJson = computed (() => JSON .stringify (debugSequences .value , null , 2 ));
295+ const copiedFieldKey = ref <string | null >(null );
296+ let copiedFieldResetTimer: ReturnType <typeof setTimeout > | null = null ;
228297
229298function formatTimestamp(value : string ) {
230299 return new Date (value ).toLocaleString ();
@@ -241,4 +310,23 @@ function sequenceDuration(sequence: DebugSequence) {
241310
242311 return ` ${(durationMs / 1000 ).toFixed (2 )} s ` ;
243312}
313+
314+ async function copyText(key : string , value : string ) {
315+ await navigator .clipboard .writeText (value );
316+ copiedFieldKey .value = key ;
317+
318+ if (copiedFieldResetTimer ) {
319+ clearTimeout (copiedFieldResetTimer );
320+ }
321+
322+ copiedFieldResetTimer = setTimeout (() => {
323+ if (copiedFieldKey .value === key ) {
324+ copiedFieldKey .value = null ;
325+ }
326+ }, 1600 );
327+ }
328+
329+ function copyLabel(key : string ) {
330+ return copiedFieldKey .value === key ? ' Copied' : ' Copy' ;
331+ }
244332 </script >
0 commit comments