/**
 * Cheap token estimator used by the summarizer triggers and the
 * working-window cap.
 *
 * `len / 4` is the standard back-of-envelope for English text under
 * GPT/Claude tokenizers; on CJK it under-counts (closer to len * 0.6)
 * and on code it over-counts. Good enough for "do we summarize yet?"
 * gating — the real token count comes back from the provider after
 * each call and can be used to recalibrate.
 *
 * No tiktoken dep on purpose: this runs inside lib/ which loads under
 * tsx standalone, and we don't want native or wasm baggage on the cold
 * path.
 */

export function estimateTokens(input: unknown): number {
  if (input == null) return 0;
  const s = typeof input === 'string' ? input : safeStringify(input);
  return Math.ceil(s.length / 4);
}

function safeStringify(v: unknown): string {
  try {
    return JSON.stringify(v) ?? '';
  } catch {
    return String(v);
  }
}
