(evt)
| 626 | |
| 627 | // ---- Interrupt Banner ---- |
| 628 | function renderInterruptBanner(evt) { |
| 629 | closeGroup(); |
| 630 | const wrapper = document.createElement('div'); |
| 631 | wrapper.style.cssText = 'position:relative;display:flex;align-items:center;margin:12px 0;overflow:hidden;'; |
| 632 | const line = document.createElement('div'); |
| 633 | line.style.cssText = 'position:absolute;left:0;right:0;top:50%;height:1px;background:var(--border);'; |
| 634 | wrapper.appendChild(line); |
| 635 | const el = document.createElement('div'); |
| 636 | const isTerminal = evt.source === 'terminal'; |
| 637 | el.className = 'interrupt-banner' + (isTerminal ? ' terminal-interrupt' : ' user-interrupt'); |
| 638 | const label = isTerminal ? '终端中断' : '用户中断'; |
| 639 | const icon = isTerminal |
| 640 | ? '<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><rect x="2" y="4" width="20" height="16" rx="2"/><path d="M7 15l3-3-3-3"/><line x1="13" y1="15" x2="17" y2="15"/></svg>' |
| 641 | : '<svg width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"><path d="M18 6L6 18M6 6l12 12"/></svg>'; |
| 642 | el.innerHTML = icon + '<span>' + label + '</span>'; |
| 643 | wrapper.appendChild(el); |
| 644 | $msgs.appendChild(wrapper); |
| 645 | } |
| 646 | |
| 647 | // ---- Cost Card ---- |
| 648 | function renderCostCard(raw) { |
no test coverage detected