import { cloneJson } from './helpers';
class OllamaToolApprovalItem {
    constructor(params) {
        Object.defineProperty(this, "callId", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        Object.defineProperty(this, "toolName", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        Object.defineProperty(this, "arguments", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        Object.defineProperty(this, "serverId", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        Object.defineProperty(this, "serverName", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        Object.defineProperty(this, "rawItem", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        Object.defineProperty(this, "agent", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        this.callId = params.callId;
        this.toolName = params.toolName;
        this.arguments = params.arguments;
        this.serverId = params.serverId;
        this.serverName = params.serverName;
        this.agent = { name: 'Ollama' };
        this.rawItem = {
            id: params.callId,
            callId: params.callId,
            name: params.toolName,
            arguments: params.arguments,
            serverId: params.serverId,
            serverName: params.serverName,
            ...(params.metadata ?? {})
        };
    }
    toJSON() {
        return {
            rawItem: this.rawItem,
            agent: this.agent
        };
    }
}
export class OllamaRunState {
    constructor(params) {
        Object.defineProperty(this, "conversationSnapshot", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        Object.defineProperty(this, "calls", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        Object.defineProperty(this, "interruptions", {
            enumerable: true,
            configurable: true,
            writable: true,
            value: void 0
        });
        this.conversationSnapshot = cloneJson(params.conversation);
        this.calls = params.calls.map((entry) => ({ ...entry }));
        this.interruptions = this.calls
            .filter((entry) => entry.status === 'pending')
            .map((entry) => new OllamaToolApprovalItem({
            callId: entry.callId,
            toolName: entry.toolDisplayName,
            arguments: entry.arguments,
            serverId: entry.serverId,
            serverName: entry.serverName
        }));
    }
    toString() {
        const payload = {
            version: 1,
            conversation: cloneJson(this.conversationSnapshot),
            calls: this.calls.map((entry) => ({ ...entry }))
        };
        return JSON.stringify(payload);
    }
    static deserialize(serialized) {
        let parsed;
        try {
            parsed = JSON.parse(serialized);
        }
        catch (error) {
            const detail = error instanceof Error ? error.message : String(error);
            throw new Error(`Failed to parse Ollama run state: ${detail}`);
        }
        if (!parsed || parsed.version !== 1 || !Array.isArray(parsed.conversation) || !Array.isArray(parsed.calls)) {
            throw new Error('Unsupported Ollama run state payload');
        }
        return new OllamaRunState({
            conversation: parsed.conversation,
            calls: parsed.calls
        });
    }
    getInterruptions() {
        return this.interruptions.map((item) => item);
    }
    approve(interruption, options) {
        const item = this.resolveInterruption(interruption);
        const entry = this.calls.find((call) => call.callId === item.callId);
        if (entry) {
            entry.status = 'approved';
            entry.reason = typeof options?.reason === 'string' ? options.reason : entry.reason;
        }
    }
    reject(interruption, options) {
        const item = this.resolveInterruption(interruption);
        const entry = this.calls.find((call) => call.callId === item.callId);
        if (entry) {
            entry.status = 'rejected';
            entry.reason = typeof options?.reason === 'string' && options.reason.length > 0
                ? options.reason
                : 'User rejected the tool call';
        }
    }
    consumeResolvedCalls() {
        const approved = [];
        const rejected = [];
        for (const call of this.calls) {
            if (call.status === 'approved') {
                call.status = 'consumed';
                approved.push({ ...call });
            }
            else if (call.status === 'rejected') {
                call.status = 'consumed';
                rejected.push({ ...call });
            }
        }
        return { approved, rejected };
    }
    cloneConversation() {
        return cloneJson(this.conversationSnapshot);
    }
    resolveInterruption(interruption) {
        if (interruption instanceof OllamaToolApprovalItem) {
            return interruption;
        }
        const matched = this.interruptions.find((item) => item === interruption);
        if (matched) {
            return matched;
        }
        throw new Error('Unknown interruption provided to Ollama run state');
    }
}
