//#region src/tui/stream-assembler.ts
function composeDisplay(thinking, content, showThinking) {
	if (!showThinking || !thinking) return content;
	const thinkingBlock = `<thinking>\n${thinking}\n</thinking>\n\n`;
	return content ? `${thinkingBlock}${content}` : thinkingBlock;
}
var StreamAssembler = class {
	runs = /* @__PURE__ */ new Map();
	getOrCreate(runId) {
		let state = this.runs.get(runId);
		if (!state) {
			state = {
				thinkingText: "",
				contentText: "",
				displayText: ""
			};
			this.runs.set(runId, state);
		}
		return state;
	}
	/** Append a content token delta. Returns updated display text, or null if unchanged. */
	ingestToken(runId, delta, showThinking) {
		const state = this.getOrCreate(runId);
		state.contentText += delta;
		const next = composeDisplay(state.thinkingText, state.contentText, showThinking);
		if (next === state.displayText) return null;
		state.displayText = next;
		return next;
	}
	/** Update thinking content. Returns updated display text, or null if unchanged. */
	ingestThinking(runId, content, isDelta, showThinking) {
		const state = this.getOrCreate(runId);
		state.thinkingText = isDelta ? state.thinkingText + content : content;
		const next = composeDisplay(state.thinkingText, state.contentText, showThinking);
		if (next === state.displayText) return null;
		state.displayText = next;
		return next;
	}
	/** Finalize a run and return the final display text. */
	finalize(runId, showThinking) {
		const state = this.runs.get(runId);
		if (!state) return "";
		const final = composeDisplay(state.thinkingText, state.contentText, showThinking);
		this.runs.delete(runId);
		return final;
	}
	/** Get current display text for a run. */
	getDisplayText(runId) {
		return this.runs.get(runId)?.displayText ?? "";
	}
	/** Drop a run without finalizing. */
	drop(runId) {
		this.runs.delete(runId);
	}
	/** Clear all run state. */
	clear() {
		this.runs.clear();
	}
};
//#endregion
export { StreamAssembler };

//# sourceMappingURL=stream-assembler.js.map