Ctrl K
ComunidadGuías…

src/server/mcp-progress.ts

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
import type { McpProgressReporter } from 'edge.libx.js/build/main.js';
import type { WsEvent } from './claude.ts';

const THROTTLE_MS = 1000;

/**
 * Map agent stream events to MCP progress via `report` (from captureMcpProgress()).
 * Throttles to ~1/s; terminal events (done/error) always flush. `report` is a no-op
 * when the client didn't request progress, so this is always safe to wire up.
 */
export function makeProgressEmitter(report: McpProgressReporter): (ev: WsEvent) => void {
  let lastSentAt = 0;
  return (ev) => {
    const message = eventToMessage(ev);
    if (!message) return;
    const terminal = ev.type === 'done' || ev.type === 'error';
    const now = Date.now();
    if (!terminal && now - lastSentAt < THROTTLE_MS) return;
    lastSentAt = now;
    report(message);
  };
}

function eventToMessage(ev: WsEvent): string {
  switch (ev.type) {
    case 'thinking_delta':
      return prefixed('💭', ev.text);
    case 'text_delta':
      return prefixed('💬', ev.text);
    case 'tool_use':
      return `🔧 ${ev.tool}`;
    case 'done':
      return '✓ done';
    case 'error':
      return prefixed('⚠️', ev.message) || '⚠️ error';
    default:
      return '';
  }
}

/** First non-empty line of `v`, clipped to 80 chars, with an icon — or '' if blank. */
function prefixed(icon: string, v: unknown): string {
  const line = (String(v ?? '').trim().split('\n').find((l) => l.trim()) ?? '').slice(0, 80);
  return line ? `${icon} ${line}` : '';
}