package com.gzzm.lobster.llm;

/**
 * 流式响应处理器 / Streaming response handler.
 *
 * <p>adapter 在读到增量时回调 {@link #onDelta(String)}；
 * 完整 {@link #onComplete(LlmResponse)} 或 {@link #onError(Throwable)} 只会触发其一。
 *
 * <p>Exactly one of onComplete / onError will fire.
 */
public interface StreamingResponseHandler {

    /** 分片文本到达 / Incremental text chunk. */
    void onDelta(String delta);

    /**
     * 思考内容分片到达 / Incremental reasoning ("thinking") chunk.
     *
     * <p>thinking-mode 模型（DeepSeek-reasoner / Qwen-QwQ / GLM-Z1 等）会在 SSE 流里
     * 单独发 {@code delta.reasoning_content}；adapter 在累加保存的同时通过本回调
     * 把分片实时透传给上层，让 UI 能像 ChatGPT/Claude 桌面端一样渲染折叠的"思考过程"块.
     *
     * <p>默认 no-op 以保持向后兼容——非 thinking 模型 / 不关心思考过程的上层无需实现.
     */
    default void onReasoningDelta(String delta) { /* no-op */ }

    /** 完成一次 tool_calls 解析 / A tool call was parsed. */
    void onToolCall(ToolCall toolCall);

    /**
     * write_file.content argument delta for UI preview only.
     *
     * <p>This is not a real tool call and must not trigger tool execution.
     */
    default void onWriteFileContentDelta(String toolCallId, int toolIndex, String contentDelta) { /* no-op */ }

    /** 全部完成 / Response fully parsed. */
    void onComplete(LlmResponse response);

    /** 失败 / Failed. */
    void onError(Throwable error);

    /**
     * 上层取消信号 / Upper-layer cancellation signal.
     *
     * <p>adapter 的读流循环应每读一帧就 check 一次；返回 true 时主动 disconnect
     * 并以 {@link #onError(Throwable)} 结束，避免阻塞等当前 HTTP 调用自然结束。
     *
     * <p>Default false 保持向后兼容 —— 旧 adapter 不会因此变更行为。
     */
    default boolean isCancelled() {
        return false;
    }
}
