/**
 * Observer that manages conversation context during LLM interactions.
 *
 * Handles:
 * - Starting and ending steps in the context
 * - Ending the turn on completion
 * - Releasing the context handle on completion/error/abort
 *
 * @example
 * ```typescript
 * const observer = new ContextObserver({
 *   contextHandle: await contextManager.acquireContext(contextId, ownerId),
 * });
 * ```
 */
export class ContextObserver {
    contextHandle;
    released = false;
    constructor(options) {
        this.contextHandle = options.contextHandle;
    }
    attach(events, _config) {
        events.on("step:finish", async (step, session) => {
            await this.onStepComplete(step, session);
        });
        events.on("stream:finish", (result, session) => {
            this.onStreamFinish(result, session);
        });
        events.on("session:complete", () => {
            this.release();
        });
        events.on("session:error", () => {
            this.release();
        });
        events.on("session:abort", () => {
            this.release();
        });
    }
    async onStepComplete(step, _session) {
        // Don't persist partial state when step ended due to an error (finishReason: "unknown").
        // Saving partial assistant messages from interrupted streams can cause issues on retry,
        // especially with extended thinking where the final assistant message must start with
        // a thinking block. If we save a partial message (text only, no thinking block),
        // all following requests will fail.
        if (step.finishReason === "unknown") {
            return;
        }
        if (step.response?.messages) {
            await this.contextHandle.context.endStep(step.response.messages, step.usage);
        }
        this.contextHandle.context.startStep();
    }
    onStreamFinish(result, _session) {
        this.contextHandle.context.endTurn(result.totalUsage);
    }
    release() {
        if (!this.released) {
            this.released = true;
            this.contextHandle.release();
        }
    }
}
//# sourceMappingURL=context.js.map