import { c as createSseStream, S as SSE_HEADERS, e as encodeSseFrame } from './http-CoxxIFTY.js';
import { a as getBrainDb, g as getTasksDb, c as getConduitDb } from './connections2-D22b0xbS.js';
import './paths-2M_UxD_H.js';
import 'node:fs';
import 'node:path';
import 'node:os';
import 'node:events';
import 'node:diagnostics_channel';
import 'fs';
import 'events';
import 'util';
import 'path';
import 'assert';
import 'worker_threads';
import 'module';
import 'node:url';
import 'url';
import 'buffer';
import 'node:module';
import 'node:child_process';
import 'node:crypto';
import 'node:process';
import 'node:async_hooks';
import './dist4-CiQ5cizO.js';
import './dual-scope-db-ATrwq0LH.js';
import './indexes-aYlULWG3.js';
import './utils-BvHPJOVk.js';
import './adapters-D2gEs_5L.js';
import './registry2-BSyCTA3q.js';
import './data-accessor-CVbz8X_7.js';
import './tasks-CnwUAUXf.js';
import './conduit-Ca_OFWR_.js';
import './unique-constraint-BM-Apx1H.js';
import './chunk-DDP5xfzh.js';
import './sqlite-Dsbe0wec.js';
import './memory-schema-Bi7cChwo.js';
import './agent-registry-BtE5uhMO.js';
import './nexus-sqlite2-DgTuv9BQ.js';
import './nexus-schema2-BEd-ol6e.js';
import './logger-ChCwlV5k.js';
import 'node:sqlite';
import './lock-BoHF25mx.js';
import './index-IVoIz4D5.js';
import 'constants';
import 'stream';
import 'node:fs/promises';
import 'jsonc-parser';
import '@cleocode/cant';
import 'node:util';
import 'node:buffer';
import 'child_process';
import './branch-lock-qP1EkZ7p.js';
import './src2-DK8DKufK.js';
import 'llmtxt/identity';
import './sessions-j73dkbCI.js';
import './index-Ca4C2M45.js';
import './mvi-helpers-BNsJ8ZpQ.js';
import './session-store-OwQWMSf_.js';
import './session-manifest-ZHrj54LR.js';
import './storage-B9UA3BHR.js';
import './config-B0nEjgSh.js';
import './json-DXl7iDYg.js';
import './data-safety-central-vmfu_Y4J.js';
import './sqlite-data-accessor-C59wZ0zp.js';
import './cross-db-cleanup-C_FLyd-6.js';
import './query-ops-BDMaTdYw.js';
import 'node:net';
import './src3-CMSGYxDI.js';
import './local-model-fit2-J1xCIhC_.js';
import './credential-pool-B04qO8at.js';
import './catalog-model-resolver2-Cexk2TN0.js';
import './role-resolver-DF9BQ_U6.js';
import './identity2-DeAB5RXE.js';
import './role-executor-C4-3bmgC.js';
import 'node:stream';
import 'crypto';
import 'os';
import 'node:http2';
import 'fs/promises';
import './models-catalog-DG3aPok8.js';
import './catalog-resolver2-c0qfF34B.js';
import './providers-CmIcBfg-.js';
import './brain-maintenance-bSR6GwAG.js';
import './graph-auto-populate2-DYsUNGSL.js';
import './temporal-supersession-BZ46j30w.js';
import './typed-query-l1D_QElt.js';
import './llm-backend-resolver-BPbvttS4.js';
import '@ai-sdk/provider-utils';
import './observer-reflector2-D8nxuglX.js';
import './learnings2-2m2p7lzT.js';
import './memory-accessor2-BzlgmY-Z.js';
import './quality-scoring-CCPuRQmJ.js';
import './patterns2-DYKfsbwN.js';
import './graph-memory-bridge2-C7Y32Mk4.js';
import './sigil2-DftKm7Um.js';
import './services-Dlf3Gefq.js';
import './audit4-S87oN-BC.js';
import 'process';
import './cleo-home-BCqJ5rg1.js';

//#region src/routes/api/brain/stream/+server.ts
/** How often (ms) to poll source tables for new rows. */
var POLL_INTERVAL_MS = 1e3;
/** How often (ms) to send a heartbeat to prevent connection drop. */
var HEARTBEAT_INTERVAL_MS = 3e4;
/** Max chars for message preview in message.send events. */
var MESSAGE_PREVIEW_LEN = 120;
/**
* Serialises a `BrainStreamEvent` to the `data: …\n\n` SSE wire format.
*
* Delegates to the shared `encodeSseFrame` primitive from the gateway HTTP
* adapter (R3-T6 · T11450) so this Studio stream and every gateway-routed SSE
* stream share one tested encoder. A `data:`-only frame (no `event:` field) is
* byte-identical to the prior handwritten `data: <json>\n\n` form, preserving
* the observable wire exactly.
*
* @param event - The event to encode.
* @returns SSE-formatted string ready for the stream.
*/
function sseEncode(event) {
	return encodeSseFrame({ data: event });
}
/**
* Initialises watermarks from the current state of all source tables.
* This prevents replaying historical rows when a client first connects.
*
* @param ctx - Active project context for resolving per-project DB paths.
* @returns Initial watermark state.
*/
function initWatermarks(ctx) {
	const state = {
		lastObsRowid: 0,
		edgeWeights: /* @__PURE__ */ new Map(),
		lastTaskRowid: 0,
		taskStatuses: /* @__PURE__ */ new Map(),
		lastMsgRowid: 0
	};
	try {
		const brainDb = getBrainDb(ctx);
		if (brainDb) {
			state.lastObsRowid = brainDb.prepare("SELECT COALESCE(MAX(rowid), 0) AS max_rowid FROM brain_observations").get()?.max_rowid ?? 0;
			const edges = brainDb.prepare("SELECT from_id, to_id, weight FROM brain_page_edges").all();
			for (const e of edges) state.edgeWeights.set(`${e.from_id}|${e.to_id}`, e.weight);
		}
	} catch {}
	try {
		const tasksDb = getTasksDb(ctx);
		if (tasksDb) {
			state.lastTaskRowid = tasksDb.prepare("SELECT COALESCE(MAX(rowid), 0) AS max_rowid FROM tasks").get()?.max_rowid ?? 0;
			const rows = tasksDb.prepare("SELECT id, status FROM tasks").all();
			for (const r of rows) state.taskStatuses.set(r.id, r.status);
		}
	} catch {}
	try {
		const conduitDb = getConduitDb(ctx);
		if (conduitDb) state.lastMsgRowid = conduitDb.prepare("SELECT COALESCE(MAX(rowid), 0) AS max_rowid FROM conduit_messages").get()?.max_rowid ?? 0;
	} catch {}
	return state;
}
/**
* Checks brain_observations for rows inserted since the last poll.
*
* @param state - Current watermark state (mutated on new rows).
* @param ctx - Active project context for resolving brain.db path.
* @returns Array of `node.create` events to emit.
*/
function detectNewObservations(state, ctx) {
	const events = [];
	try {
		const db = getBrainDb(ctx);
		if (!db) return events;
		const rows = db.prepare(`SELECT rowid, id, title, quality_score, memory_tier, created_at, source_session_id
         FROM brain_observations
         WHERE rowid > ?
         ORDER BY rowid ASC`).all(state.lastObsRowid);
		for (const row of rows) {
			state.lastObsRowid = row.rowid;
			const node = {
				id: `brain:${row.id}`,
				kind: "observation",
				substrate: "brain",
				label: row.title,
				weight: row.quality_score ?? void 0,
				createdAt: row.created_at,
				meta: {
					memory_tier: row.memory_tier,
					created_at: row.created_at,
					source_session_id: row.source_session_id
				}
			};
			events.push({
				type: "node.create",
				node,
				ts: (/* @__PURE__ */ new Date()).toISOString()
			});
		}
	} catch {}
	return events;
}
/**
* Checks brain_page_edges for rows whose weight changed since last poll.
*
* Compares against the in-memory weight snapshot. Both newly added edges
* (not in snapshot) and existing edges with a changed weight are emitted.
*
* @param state - Current watermark state (mutated on weight changes).
* @param ctx - Active project context for resolving brain.db path.
* @returns Array of `edge.strengthen` events to emit.
*/
function detectEdgeWeightChanges(state, ctx) {
	const events = [];
	try {
		const db = getBrainDb(ctx);
		if (!db) return events;
		const rows = db.prepare(`SELECT from_id, to_id, edge_type, weight, updated_at
         FROM brain_page_edges`).all();
		for (const row of rows) {
			const key = `${row.from_id}|${row.to_id}`;
			const prevWeight = state.edgeWeights.get(key);
			if (prevWeight === void 0 || prevWeight !== row.weight) {
				state.edgeWeights.set(key, row.weight);
				if (prevWeight !== void 0) events.push({
					type: "edge.strengthen",
					fromId: `brain:${row.from_id}`,
					toId: `brain:${row.to_id}`,
					edgeType: row.edge_type,
					weight: row.weight,
					ts: (/* @__PURE__ */ new Date()).toISOString()
				});
			}
		}
	} catch {}
	return events;
}
/**
* Checks the tasks table for rows whose status changed since last poll.
*
* Uses rowid watermark to detect new tasks, then status-map diff for
* tasks already seen.
*
* @param state - Current watermark state (mutated on changes).
* @param ctx - Active project context for resolving tasks.db path.
* @returns Array of `task.status` events to emit.
*/
function detectTaskStatusChanges(state, ctx) {
	const events = [];
	try {
		const db = getTasksDb(ctx);
		if (!db) return events;
		const newRows = db.prepare(`SELECT rowid, id, status, updated_at
         FROM tasks
         WHERE rowid > ?
         ORDER BY rowid ASC`).all(state.lastTaskRowid);
		for (const row of newRows) {
			state.lastTaskRowid = row.rowid;
			state.taskStatuses.set(row.id, row.status);
			events.push({
				type: "task.status",
				taskId: row.id,
				status: row.status,
				ts: (/* @__PURE__ */ new Date()).toISOString()
			});
		}
		if (state.taskStatuses.size > 0) {
			const ids = [...state.taskStatuses.keys()];
			const placeholders = ids.map(() => "?").join(",");
			const existingRows = db.prepare(`SELECT id, status FROM tasks WHERE id IN (${placeholders})`).all(...ids);
			for (const row of existingRows) {
				const prev = state.taskStatuses.get(row.id);
				if (prev !== void 0 && prev !== row.status) {
					state.taskStatuses.set(row.id, row.status);
					events.push({
						type: "task.status",
						taskId: row.id,
						status: row.status,
						ts: (/* @__PURE__ */ new Date()).toISOString()
					});
				}
			}
		}
	} catch {}
	return events;
}
/**
* Checks conduit messages for rows inserted since the last poll.
*
* @param state - Current watermark state (mutated on new rows).
* @param ctx - Active project context for resolving conduit.db path.
* @returns Array of `message.send` events to emit.
*/
function detectNewMessages(state, ctx) {
	const events = [];
	try {
		const db = getConduitDb(ctx);
		if (!db) return events;
		const rows = db.prepare(`SELECT rowid, id, content, from_agent_id, to_agent_id, created_at
         FROM conduit_messages
         WHERE rowid > ?
         ORDER BY rowid ASC`).all(state.lastMsgRowid);
		for (const row of rows) {
			state.lastMsgRowid = row.rowid;
			const preview = row.content.length > MESSAGE_PREVIEW_LEN ? `${row.content.slice(0, MESSAGE_PREVIEW_LEN)}…` : row.content;
			events.push({
				type: "message.send",
				messageId: row.id,
				fromAgentId: row.from_agent_id ?? "",
				toAgentId: row.to_agent_id ?? "",
				preview,
				ts: (/* @__PURE__ */ new Date()).toISOString()
			});
		}
	} catch {}
	return events;
}
var GET = ({ locals, request }) => {
	const signal = request.signal;
	const projectCtx = locals.projectCtx;
	const stream = createSseStream((emitter) => {
		/** Emit one BrainStreamEvent on the wire (drops after close, never throws). */
		function emit(event) {
			emitter.sendRaw(sseEncode(event));
		}
		const watermarks = initWatermarks(projectCtx);
		emit({
			type: "hello",
			ts: (/* @__PURE__ */ new Date()).toISOString()
		});
		const heartbeatTimer = setInterval(() => {
			if (emitter.closed) {
				clearInterval(heartbeatTimer);
				return;
			}
			emit({
				type: "heartbeat",
				ts: (/* @__PURE__ */ new Date()).toISOString()
			});
		}, HEARTBEAT_INTERVAL_MS);
		const pollTimer = setInterval(() => {
			if (emitter.closed) {
				clearInterval(pollTimer);
				return;
			}
			const events = [
				...detectNewObservations(watermarks, projectCtx),
				...detectEdgeWeightChanges(watermarks, projectCtx),
				...detectTaskStatusChanges(watermarks, projectCtx),
				...detectNewMessages(watermarks, projectCtx)
			];
			for (const event of events) {
				if (emitter.closed) break;
				emit(event);
			}
		}, POLL_INTERVAL_MS);
		return () => {
			clearInterval(heartbeatTimer);
			clearInterval(pollTimer);
		};
	}, signal);
	return new Response(stream, { headers: { ...SSE_HEADERS } });
};

export { GET };
//# sourceMappingURL=_server.ts-Dcg-1qkW.js.map
