# com.innovaphone.assistant

This API is used for communication with a large language model (LLM) and text translation (HTML payload is also supported) against an externally hosted service.

## Messages

Question
GetModels

### Question

Transfers the specified question to the LLM in order to receive a response. You may send a single message (role: user) or multiples messages (role: system/assistant/user) using the same src as a single request to the LLM.
The service reassembles the messages with an equal src per session and sends the messages array: [message1, message2, ...] to the LLM. Very large messages which don't fit into a single Websocket message may be chunked
using the parameter complete to indicate wether or not the last message chunk was sent. e.g.

            { "Question", "message": { role: "user", content: "What is innovaphone?" }, "seq": 0, "complete": true;  "last": true, "src": "src0" }

or

            { "Question", "message": { "role": "system", "content": "You are very helpful" }, "seq": 0, "complete": true,  "src": "src1" }
            { "Question", "message": { "role": "user", "content": "What is innovaphone?" }, "seq": 1, "complete": true,  "src": "src1" }
            { "Question", "message": { "role": "assistant", "content": "Innovaphone is a telecomunications company!" }, "seq": 2, "complete": true,  "src": "src1" }
            { "Question", "message": { "role": "user", "content": "How many people work there?" }, "seq": 3, "complete": true,  "last": true, "src": "src1" }

    {
        mt:   "Question",
        message: { role: "user", content: "The actual question comes here..." },
        seq: 0,
        complete: true;
        last: true;
    }

#### Parameters

string mt | message type [mandatory]
object message | the message to be transfered [mandatory]
number seq | the sequence number of the message starting from 0 [mandatory]
boolean complete | if the message is not chunked or the message is the last chunk of a chunked messages set to true [optional/mandatory]
boolean last | needs to be set to true for the last message to be sent [optional/mandatory]
number temperature | a number between 0 and 1 which determines the creativity of the response (defaults to 0) [optional]
number max_tokens | limits the length of the response by specifying the maximum number of tokens (words and punctuation) to generate [optional]
number top_p | controls the probability threshold for generating tokens, ensuring that the generated tokens have a cumulative probability of at least the specified value [optional]
number n | specifies the number of chat completion choices to generate for each input message [optional]
string or array of strings stop | a string or array of strings that, if present, stops the generation process when the model outputs this token [optional]
number presence_penalty | penalizes the model for generating tokens that are already present in the conversation history, encouraging new content [optional]
number frequency_penalty | penalizes the model for generating repetitive tokens, thus reducing repetition in the responses [optional]
array of objects tools | provides function specifications to enable models to generate function arguments and invoke functions as part of the response [optional]
string tool_choice | forces the model to use a specific function or not use any function at all [optional]
number seed | sets the random seed for reproducibility, ensuring consistent outputs for the same input parameters [optional]

##### Note:

Not all parameters may be supported by your LLM provider! Adding them might throw a HTTP error.

#### Response

    {
        mt:        "QuestionResult",
        message:   { role: "assistant", content: "The answer to your question is....!" }
    }

#### Parameters

string mt | message type (is "QuestionResult")
object message | the response object of the LLM

#### Error Response

If you run into an error you will receive the following response.

    {
        mt:    "QuestionResult",
       message:   { content: "The actual error message" },
        error: true
    }

#### Parameters

string mt | message type (is "QuestionResult")
string object | English error message which can be shown to the User
bool error | labelling whether error was send. Only sent if true [optional]

### GetModels

Send to obtain all the available LLMs of the model service provider

    {
        mt:   "GetModels"
    }

#### Response

    {
        mt:        "GetModelsResult",
        message:   [{"id":"qwen2","object":"model","created":1756396382,"owned_by":"library"}, ... ]
    }

#### Parameters

string mt | message type (is "GetModelsResult")
array object | An array of objects of all the available models

## Example

You can consume the API com.innovaphone.assistant and send request to it. Inside the callback you can access the response text via recv.msg.message.content

        var assistantApi = start.consumeApi("com.innovaphone.assistant");

        let messages = [];

        messages.push({ role: "system", content: "You are very helpful!", complete: true, src:"src0" });
        messages.push({ role: "user", content: "What do you know about innovaphone?", complete: true, src:"src0" });
        messages.push({ role: "assistant", content: "innovaphone is a nice company!", complete: true, src:"src0" });
        messages.push({ role: "user", content: "What exactly can you tell about ", src:"src0" });
        messages.push({ role: "user", content: "their products?", complete: true, last:true, src:"src0" });

        let seq = 0;
        let reqBase = { api: "Assistant", mt: "Question" };

        let src = new assistantApi.Src(result);

        for (let i = 0; i < messages.length; i++) {
           const req = { ...reqBase };
           if (messages[i].content.length > WS_MAX_DATA_SIZE) {
              for (let start = 0; start < messages[i].content.length; start += WS_MAX_DATA_SIZE) {
                 const chunk = messages[i].content.substring(start, start + WS_MAX_DATA_SIZE);
                 req.message = { role: messages[i].role, content: chunk };
                 req.seq = seq++;
                 if (start + WS_MAX_DATA_SIZE >= messages[i].content.length) {
                    req.complete = true;
                    if (i == messages.length - 1) req.last = true;
                 }
                 src.send(req);
              }
           }
           else {
              req.message = messages[i];
              req.seq = seq++;
              req.complete = true;
              if (i == messages.length - 1) req.last = true;
              src.send(req);
           }
        }

        function result(recv) {
           console.log(recv.msg?.message?.content);
           src.close();
        }