Add ACP debug log with copy button in chat toolbar

This commit is contained in:
Anton A S 2026-03-15 17:45:14 +03:00
parent 206cb3742f
commit 83f7c53fee
2 changed files with 42 additions and 1 deletions

View file

@ -56,6 +56,24 @@ export function buildCrashChunks(
return { chunks, shouldNullSession: true }
}
interface AcpDebugEntry {
ts: number
type: string
data: unknown
}
export const acpDebugLog: AcpDebugEntry[] = []
export function getAcpDebugText(): string {
return acpDebugLog.map((e) =>
`[${new Date(e.ts).toISOString()}] ${e.type}\n${JSON.stringify(e.data, null, 2)}`
).join('\n\n---\n\n')
}
export function clearAcpDebugLog() {
acpDebugLog.length = 0
}
export class ACPChatTransport implements ChatTransport<UIMessage> {
private session: ACPSession | null = null
private agentDef: ACPAgentDef
@ -114,7 +132,11 @@ export class ACPChatTransport implements ChatTransport<UIMessage> {
session.onUpdate = (params) => {
if (closed) return
console.debug('[ACP update]', params.update.sessionUpdate, params.update)
acpDebugLog.push({
ts: Date.now(),
type: params.update.sessionUpdate,
data: params.update
})
const result = mapUpdate(params.update, textId, textStarted)
for (const chunk of result.chunks) {
controller.enqueue(chunk)

View file

@ -2,6 +2,7 @@
import { ScrollAreaRoot, ScrollAreaScrollbar, ScrollAreaThumb, ScrollAreaViewport } from 'reka-ui'
import { computed, markRaw, nextTick, ref, watch } from 'vue'
import { getAcpDebugText, clearAcpDebugLog } from '@/ai/acp-transport'
import { copyChatLog } from '@/ai/chat-debug'
import { clearToolLogEntries, didHitStepLimit } from '@/ai/tools'
import AcpPermissionDialog from '@/components/chat/AcpPermissionDialog.vue'
@ -24,6 +25,7 @@ ensureChat().then((c) => {
})
const messagesEnd = ref<HTMLDivElement>()
const debugCopied = ref(false)
const acpLogCopied = ref(false)
const initError = ref<string | null>(null)
const messages = computed(() => chat.value?.messages ?? [])
@ -86,10 +88,19 @@ async function handleCopyDebug() {
}, 1500)
}
async function handleCopyAcpLog() {
const text = getAcpDebugText()
if (!text) return
await navigator.clipboard.writeText(text)
acpLogCopied.value = true
setTimeout(() => { acpLogCopied.value = false }, 1500)
}
function handleClearChat() {
chat.value = null
resetChat()
clearToolLogEntries()
clearAcpDebugLog()
}
</script>
@ -170,6 +181,14 @@ function handleClearChat() {
<icon-lucide-check v-else class="size-3 text-green-400" />
{{ debugCopied ? 'Copied' : 'Copy log' }}
</button>
<button
class="flex items-center gap-1 rounded px-1.5 py-0.5 text-[10px] text-muted hover:bg-hover hover:text-surface"
@click="handleCopyAcpLog"
>
<icon-lucide-bug v-if="!acpLogCopied" class="size-3" />
<icon-lucide-check v-else class="size-3 text-green-400" />
{{ acpLogCopied ? 'Copied' : 'ACP log' }}
</button>
<button
class="flex items-center gap-1 rounded px-1.5 py-0.5 text-[10px] text-muted hover:bg-hover hover:text-surface"
@click="handleClearChat"