import { PROP_SESSION_REPLAY_ID } from "./core/constants.js";
import { Session } from "./session.js";

//#region src/bound-agent.ts
const CONTEXT_FIELDS = [
	"userId",
	"deviceId",
	"agentId",
	"parentAgentId",
	"customerOrgId",
	"agentVersion",
	"description",
	"context",
	"env",
	"sessionId",
	"traceId",
	"groups"
];
var BoundAgent = class BoundAgent {
	_ai;
	_defaults;
	constructor(ai, opts) {
		this._ai = ai;
		this._defaults = {
			userId: opts.userId ?? null,
			agentId: opts.agentId,
			parentAgentId: opts.parentAgentId ?? null,
			customerOrgId: opts.customerOrgId ?? null,
			agentVersion: opts.agentVersion ?? null,
			description: opts.description ?? null,
			context: opts.context ?? null,
			env: opts.env ?? null,
			sessionId: opts.sessionId ?? null,
			traceId: opts.traceId ?? null,
			groups: opts.groups ?? null,
			deviceId: opts.deviceId ?? null,
			browserSessionId: opts.browserSessionId ?? null
		};
	}
	get agentId() {
		return String(this._defaults.agentId);
	}
	get ai() {
		return this._ai;
	}
	child(agentId, overrides = {}) {
		const inherited = {
			userId: this._defaults.userId,
			env: this._defaults.env,
			customerOrgId: this._defaults.customerOrgId,
			agentVersion: this._defaults.agentVersion,
			sessionId: this._defaults.sessionId,
			traceId: this._defaults.traceId,
			groups: this._defaults.groups,
			deviceId: this._defaults.deviceId,
			browserSessionId: this._defaults.browserSessionId
		};
		const parentCtx = this._defaults.context;
		const childCtx = overrides.context ?? null;
		const overrideEntries = Object.entries(overrides).filter(([k]) => k !== "context");
		if (parentCtx || childCtx) {
			const merged = { ...parentCtx ?? {} };
			if (childCtx) Object.assign(merged, childCtx);
			inherited.context = merged;
		}
		for (const [k, v] of overrideEntries) if (v != null) inherited[k] = v;
		const { parentAgentId: inheritedParentAgentId, ...inheritedWithoutParent } = inherited;
		const explicitParent = inheritedParentAgentId ?? this._defaults.agentId;
		return new BoundAgent(this._ai, {
			agentId,
			parentAgentId: explicitParent,
			...inheritedWithoutParent
		});
	}
	_merge(kwargs, fields = CONTEXT_FIELDS) {
		const merged = { ...kwargs };
		for (const field of fields) if (merged[field] == null && this._defaults[field] != null) merged[field] = this._defaults[field];
		if (merged.browserSessionId == null && this._defaults.browserSessionId != null) merged.browserSessionId = this._defaults.browserSessionId;
		const deviceId = this._defaults.deviceId;
		const browserSessionId = this._defaults.browserSessionId;
		if (deviceId && browserSessionId) {
			const existingEp = merged.eventProperties;
			const ep = existingEp != null ? { ...existingEp } : {};
			if (!(PROP_SESSION_REPLAY_ID in ep)) {
				ep[PROP_SESSION_REPLAY_ID] = `${deviceId}/${browserSessionId}`;
				merged.eventProperties = ep;
			}
		}
		return merged;
	}
	trackUserMessage(content, opts = {}) {
		return this._ai.trackUserMessage({
			...this._merge(opts),
			content
		});
	}
	trackAiMessage(content, model, provider, latencyMs, opts = {}) {
		return this._ai.trackAiMessage({
			...this._merge(opts),
			content,
			model,
			provider,
			latencyMs
		});
	}
	trackToolCall(toolName, latencyMs, success, opts = {}) {
		return this._ai.trackToolCall({
			...this._merge(opts),
			toolName,
			latencyMs,
			success
		});
	}
	trackEmbedding(model, provider, latencyMs, opts = {}) {
		return this._ai.trackEmbedding({
			...this._merge(opts),
			model,
			provider,
			latencyMs
		});
	}
	trackSpan(spanName, latencyMs, opts = {}) {
		return this._ai.trackSpan({
			...this._merge(opts),
			spanName,
			latencyMs
		});
	}
	trackSessionEnd(opts = {}) {
		this._ai.trackSessionEnd(this._merge(opts));
	}
	trackSessionEnrichment(enrichments, opts = {}) {
		this._ai.trackSessionEnrichment({
			...this._merge(opts),
			enrichments
		});
	}
	score(name, value, targetId, opts = {}) {
		this._ai.score({
			...this._merge(opts),
			name,
			value,
			targetId
		});
	}
	/**
	* Create a {@link Session}.
	*
	* `idleTimeoutMinutes` hints to the enrichment pipeline how long to wait
	* before considering the session idle. Defaults to the pipeline default
	* (~30 min). Positive values up to 90 days (129600) are honored; larger
	* values are clamped to 90 days. Set to `-1` when you intend to end the
	* session explicitly: it is enriched early when an explicit
	* `[Agent] Session End` is emitted (e.g. on `run`/`end`), and otherwise
	* auto-closes after a 90-day inactivity backstop — so a session that is never
	* explicitly ended still flushes eventually rather than leaking open.
	*
	* @throws {RangeError} if `idleTimeoutMinutes` is a negative value other than
	*   the `-1` sentinel.
	*/
	session(opts = {}) {
		if (opts.idleTimeoutMinutes != null && opts.idleTimeoutMinutes < -1) throw new RangeError(`idleTimeoutMinutes must be >= 0, or -1 to rely on an explicit session end; got ${opts.idleTimeoutMinutes}`);
		return new Session(this, opts);
	}
	flush() {
		return this._ai.flush();
	}
	shutdown() {
		this._ai.shutdown();
	}
};

//#endregion
export { BoundAgent };
//# sourceMappingURL=bound-agent.js.map