//!!! DO NOT EDIT THIS FILE, IT IS AUTO-GENERATED !!!//

import { Agent } from '../../Agent/Agent.class';
import { createSafeAccessor } from '../utils';
import { ComponentWrapper } from '../ComponentWrapper.class';
import { InputSettings, ComponentInput } from '../../types/SDKTypes';

export interface TGenAILLMSettings {
    name?: string;
    model: string;
    /** Prompt */
    prompt: string;
    /** Temperature */
    temperature?: number;
    /** Maximum Tokens */
    maxTokens?: number;
    /** Stop Sequences */
    stopSequences?: string;
    /** Top P */
    topP?: number;
    /** Top K */
    topK?: number;
    /** Frequency Penalty */
    frequencyPenalty?: number;
    /** Presence Penalty */
    presencePenalty?: number;
    /** Response Format */
    responseFormat?: 'json' | 'text';
    /** If true, the LLM response will be returned as is by the agent */
    passthrough?: boolean;
    /** If true, the component will use parent agent system prompt */
    useSystemPrompt?: boolean;
    /** If true, the component will use parent agent context window */
    useContextWindow?: boolean;
    /** The maximum number of messages to use from this component context window (if useContextWindow is true) */
    maxContextWindowLength?: number;
    /** If true, the component will use web search for additional context */
    useWebSearch?: boolean;
    /** Web Search Context Size */
    webSearchContextSize?: 'high' | 'medium' | 'low';
    /** Web Search City */
    webSearchCity?: string;
    /** Web Search Country */
    webSearchCountry?: string;
    /** Web Search Region */
    webSearchRegion?: string;
    /** Web Search Timezone */
    webSearchTimezone?: string;
    /** If true, the component will use xAI live search capabilities */
    useSearch?: boolean;
    /** Search Mode */
    searchMode?: 'auto' | 'on' | 'off';
    /** If true, include citations and sources in the response */
    returnCitations?: boolean;
    /** Max Search Results */
    maxSearchResults?: number;
    /** Search Data Sources */
    searchDataSources?: 'web' | 'x' | 'news' | 'rss';
    /** Search Country */
    searchCountry?: string;
    /** Excluded Websites */
    excludedWebsites?: string;
    /** Allowed Websites */
    allowedWebsites?: string;
    /** Included X Handles */
    includedXHandles?: string;
    /** Excluded X Handles */
    excludedXHandles?: string;
    /** Post Favorite Count */
    postFavoriteCount?: number;
    /** Post View Count */
    postViewCount?: number;
    /** RSS Link */
    link?: string;
    /** If true, enable safe search filtering */
    safeSearch?: boolean;
    /** From Date */
    fromDate?: string;
    /** To Date */
    toDate?: string;
    /** If true, the component will use reasoning capabilities for complex problem-solving */
    useReasoning?: boolean;
    /** Verbosity */
    verbosity?: 'low' | 'medium' | 'high';
    /** Controls the level of effort the model will put into reasoning */
    reasoningEffort?: 'none' | 'default' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max';
    /** Maximum Thinking Tokens */
    maxThinkingTokens?: number;
    /** RSS Link */
    rssLinks?: string;
}

export type TGenAILLMInputs = {
    /** An input that you can pass to the LLM */
    Input?: any;
    /** An attachment that you can pass to the LLM */
    Attachment?: ArrayBuffer | Uint8Array | string;
    [key: string]: any;
};

export type TGenAILLMOutputs = {
    Reply: any;
    [key: string]: any;
};

/**
 * Use this component to generate a responses from an LLM
 */
export function GenAILLM(settings?: TGenAILLMSettings, agent?: Agent) {    
    //const { name, ...settingsWithoutName } = settings || {};
    const dataObject: any = { 
        name: /*settings?.name || */'GenAILLM', 
        settings: {
            //...settingsWithoutName 
            ...settings
        }
    };
    const component = new ComponentWrapper(dataObject, agent);

    if (agent) {
        (agent.structure.components as ComponentWrapper[]).push(component);
        agent.sync();
    }
    
    const _out: TGenAILLMOutputs = createSafeAccessor({
        Reply: createSafeAccessor({}, component, 'Reply', {"default":true}),
    }, component, '');

    const _in: { [key: string]: ComponentInput } = {
        Input: {
            component,
            type: 'Any',
            optional: false,
            default: false,
        },
        Attachment: {
            component,
            type: 'Binary',
            optional: true,
            default: false,
        },
    };

    dataObject.outputs = _out;
    dataObject.inputs = _in;

    component.inputs(_in);

    const wrapper = {
        /** Component outputs - access via .out.OutputName */
        out: _out,        

        /** 
         * Create or Connect the component inputs 
         * if the input does not exist, it will be created
         * @examples 
         *    - component.in({ Input: source.out.data })
         *    - component.in({ Input: { type: 'string', source:source.out.data } })
         */        
        in: component.inputs.bind(component) as (inputs: TGenAILLMInputs) => void,
    };

    return wrapper;
}
