File size: 10,839 Bytes
c46e62c
eac7abb
 
81c3e38
2ff5a83
 
6d00d79
2da2d21
eac7abb
6200eb1
 
 
 
 
cbcd2cc
94776e3
e81181e
e3c7652
7750c4a
 
5f10bb4
 
cf46755
4cfe0e3
 
 
7750c4a
 
73e6552
4f66cb8
223eeb2
b0214e9
d3d9017
38e088b
be4b4f1
2be2108
f19c02a
4f66cb8
 
 
 
 
 
af4fe01
9349c88
5a8431a
9349c88
4f66cb8
5a8431a
4f66cb8
5b0a950
4cfe0e3
4f66cb8
5831362
af4fe01
eff544a
4f66cb8
 
 
 
 
 
 
 
 
 
 
73e6552
4f66cb8
8bda472
d3d9017
8bda472
d3d9017
9686f63
af4fe01
eac7abb
7f48e6b
 
f443a92
90fc8a2
d3d9017
06bc01e
d3d9017
9349c88
eac7abb
9349c88
 
b0214e9
eac7abb
cbcd2cc
d3d9017
b56edcd
d3d9017
eac7abb
b24691a
d3d9017
 
61f786b
 
 
 
 
 
4cfe0e3
 
0af403e
1e82d0f
 
 
 
5b0a950
f9183b0
0af403e
1e82d0f
 
5b0a950
 
59241c3
5b0a950
 
3b31d1e
4cfe0e3
9a88af5
 
494caf3
0c3d0b8
a6c802a
494caf3
 
5f10bb4
0c3d0b8
0b9036a
0c3d0b8
 
 
 
494caf3
0c3d0b8
f94dbca
81b3ebc
13939ef
950aabc
 
 
 
 
0c3d0b8
4344f5e
f41caa4
 
 
 
 
 
 
 
 
 
 
4344f5e
 
 
 
 
 
 
 
06bc01e
af4fe01
13939ef
 
5831362
d3d9017
13939ef
5831362
d3d9017
13939ef
5831362
af4fe01
13939ef
5831362
d3d9017
13939ef
 
d3d9017
af4fe01
2722c34
4cfe0e3
 
 
 
f053903
 
d3d9017
4cfe0e3
0af403e
 
567ed85
183919d
 
4944264
0e0ce96
531375b
d8a0832
31f8aa4
58195fb
9349c88
1a23014
183919d
5f834f9
b6c3de6
 
 
 
 
01d4994
bfe143d
183919d
31f8aa4
9349c88
58195fb
b6c3de6
0e0ce96
1a23014
183919d
3b31d1e
0e0ce96
534531a
1e82d0f
 
 
 
 
 
 
 
 
 
 
 
 
534531a
eac7abb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
import gradio as gr
# from transformers import pipeline
# from transformers.utils import logging
from huggingface_hub import InferenceClient
from llama_index.core import VectorStoreIndex, SimpleDirectoryReader
from llama_index.vector_stores.chroma import ChromaVectorStore
from llama_index.core.vector_stores import (MetadataFilters, ExactMatchFilter, )
from llama_index.embeddings.huggingface import HuggingFaceEmbedding
import torch
from llama_index.core import (
    VectorStoreIndex,
    Document,
    Settings,
)
from llama_index.llms.huggingface import (HuggingFaceLLM, )
from llama_index.llms.huggingface_api import (HuggingFaceInferenceAPI, )
from llama_index.core.base.llms.types import ChatMessage
from huggingface_hub import login
import chromadb as chromadb
from chromadb.utils import embedding_functions
import shutil
import os
from io import StringIO
from llama_index.core.memory import ChatMemoryBuffer

memory = ChatMemoryBuffer.from_defaults(token_limit=1500)
#

last = 0
CHROMA_DATA_PATH = "chroma_data/"
EMBED_MODEL =  "sentence-transformers/all-MiniLM-L6-v2" # "BAAI/bge-m3"
#LLM_NAME = "mistralai/Mistral-Nemo-Instruct-2407"
#LLM_NAME = "sswiss-ai/apertus-70b-instruct" # provider: publicai
#LLM_NAME = "openai/gpt-oss-20b"
LLM_NAME = "swiss-ai/apertus-8b-instruct"
#LLM_NAME = "aisingapore/Gemma-SEA-LION-v4-27B-IT"
#LLM_NAME = "W4D/YugoGPT-7B-Instruct-GGUF"
CHUNK_SIZE = 800
CHUNK_OVERLAP = 50
max_results = 3
min_len = 40
min_distance = 0.35
max_distance = 0.6
temperature = 0.7
max_tokens=5100
top_p=0.85
top_k=1000
frequency_penalty=0.0
repetition_penalty=1.12
presence_penalty=0.15
cs = "s0"
sp_flag = True

system_sr = "Zoveš se U-Chat AI asistent i pomažeš odgovorima korisniku usluga kompanije United Group. Korisnik postavlja pitanje ili problem na koji očekuje rešenje. "
# " Ako ne znaš odgovor, reci da ne znaš, ne izmišljaj ga."
system_sr += "Usluge kompanije United Group uključuju i kablovsku mrežu za digitalnu televiziju, pristup internetu, uređaj EON SMART BOX za TV sadržaj, kao i fiksnu telefoniju. "

chroma_client = chromadb.PersistentClient(CHROMA_DATA_PATH)
embedding_func = embedding_functions.SentenceTransformerEmbeddingFunction(
        model_name=EMBED_MODEL
    )

collection = chroma_client.get_or_create_collection(
        name="chroma_data",
        embedding_function=embedding_func,
        metadata={"hnsw:space": "cosine"},
    )
last = collection.count()

#
HF_TOKEN = os.getenv("HF_TOKEN")
#
login(token=(HF_TOKEN))

#system_prompt = system_sr

client = InferenceClient(LLM_NAME)

# "facebook/blenderbot-400M-distill",  facebook/blenderbot-400M-distill, stabilityai/stablelm-zephyr-3b, BAAI/bge-small-en-v1.5
Settings.llm = HuggingFaceInferenceAPI(model_name=LLM_NAME,
#                              device_map="auto",
#                              system_prompt = system_prompt,
                              context_window=4096,
                              max_new_tokens=3072,
#                              stopping_ids=[50278, 50279, 50277, 1, 0],
                              generate_kwargs={"temperature": temperature, "top_p":top_p, "repetition_penalty": repetition_penalty,
                                               "presence_penalty": presence_penalty, "frequency_penalty": frequency_penalty,
                                               "top_k": top_k, "do_sample": False },
#                              tokenizer_kwargs={"max_length": 4096},
                              tokenizer_name=LLM_NAME,
                              hf_token = HF_TOKEN,
                              src = "models",
                              provider="publicai",
                             )
# "BAAI/bge-m3"
Settings.embed_model = HuggingFaceEmbedding(model_name=EMBED_MODEL)
#documents = [Document(text="Content ..."),
#            ]
#index = VectorStoreIndex.from_documents(
#    documents,
#)
vector_store = ChromaVectorStore(chroma_collection=collection)
index = VectorStoreIndex.from_vector_store(vector_store, embed_model=Settings.embed_model)
chat_engine = index.as_chat_engine(chat_mode="condense_plus_context", memory=memory, verbose=True)
# best condense_question context condense_plus_context
#query_engine = index.as_query_engine(verbose=True)

def upload_file(filepath):
    documents = SimpleDirectoryReader(filepath).load_data()
    index = VectorStoreIndex.from_documents(documents)
    #query_engine = index.as_query_engine()
    #condense_question condense_plus_context
    chat_engine = index.as_chat_engine(verbose=True)
    return filepath

def resetChat():
    chat_engine.reset()
    print("Restarted!!!")
    return True

def rag(input_text, history, jezik): # , file):
    global sp_flag
#    if (btn):
#        resetChat()
#    print(history, input_text)
##    if (file):
    documents = []
#!!!    for f in file:
#!!!        documents += SimpleDirectoryReader(f).load_data()
#        f = file + "*.pdf"
##        pathname = os.path.dirname
#        shutil.copyfile(file.name, path)
##        print("pathname=", pathname)
##        print("basename=", os.path.basename(file))
##        print("filename=", file.name)        
##        documents = SimpleDirectoryReader(file).load_data()
#!!!        index2 = VectorStoreIndex.from_documents(documents)
##        query_engine = index2.as_query_engine()
#        return query_engine.query(input_text)
#        return history.append({"role": "assistant", "content": query_engine.query(input_text)})
##        return history + [[input_text, query_engine.query(input_text)]]
#        collection.add(
#            documents=documents,
#        ids=[f"id{last+i}" for i in range(len(documents))],
#        metadatas=[{"state": "s0", "next": "s0", "used": False, "source": 'None', "page": -1, "lang": jezik } for i in range(len(documents)) ]
#    )
##    else:
###    query_results = collection.query(
    #query_engine = index.as_query_engine(
    #    similarity_top_k=3,
    #    vector_store_query_mode="default",
    #    filters=MetadataFilters(
    #         filters=[
    #             ExactMatchFilter(key="lang", value=jezik),
    #        ]
    #    ),
    #    alpha=None,
    #    doc_ids=None,
    #)
    #query_results = index.query(
    #    query_texts = [ input_text ],
    #    n_results = max_results,
    #    where = { "lang": jezik },
    #    #where = { "$and": [ {"lang": jezik}, {"page": { "$nin": [ -1 ]}}]},
    #    #where = { "$and": [ {"$and": [ { "$or": [ {"state": self.cs },  { "page": { "$nin": [ -1 ] } } ] } , { "used": False } ] } ,
    #    #        {"lang": jezik } ] },
    #)
    #jezik = "N/A"
    system_prompt = ""
    match jezik:
        case 'hrvatski':
            o_jezik = 'na hrvatskom jeziku, gramatički točno.'
            system_prompt = system_sr + "Call centar telefon je 095 1000 444 za privatne i 095 1000 500 za poslovne korisnike. Stranica podrške je <https://tele mach.hr/podrska>." + "Odgovaraj isključivo " + o_jezik
        case 'slovenski':
            o_jezik = 'v slovenščini, slovnično pravilen.'
            system_prompt = system_sr + "Call centar i pomoč za fizične uporabnike: 070 700 700.stran za podporo je <https://telemach.si/pomoc>. " + "Odgovor isključivo " + o_jezik
        case 'srpski':
            o_jezik = 'na srpskom jeziku, gramatički ispravno.'
            system_prompt = system_sr + "Call centar telefon je 19900 za sve korisnike. Stranica podrške je <https://sbb.rs/podrska/>. " + "Odgovaraj isključivo " + o_jezik
        case 'makedonski':
            o_jezik = 'на македонски јазикот граматички точно.'
            system_prompt = system_sr + "Stranica podrške je https://mn.nettvplus.com/me/podrska/ za NetTV. " + "Oдговори исклучиво " + o_jezik
        case 'Eksperimentalna opcija':
            o_jezik = 'N/A'
            system_prompt = system_sr + "Call centar telefon je 12755 za Crnu Goru, 0800 31111 za BIH, 070 700 700 u Sloveniji, 19900 u Srbiji, 095 1000 444 za hrvatske korisnike. Odgovori na jeziku istom kao i u postavljenom pitanju ili problemu korisnika."
    print("jezik: "+o_jezik)
    system_prompt = system_prompt + " Sledi pitanje ili problem korisnika, sa kojim dalje komuniciraš: "
    if sp_flag:
        sp_flag = False
    else:
        system_prompt = ""
#        if (o_jezik!='N/A'):
#            input_text += " - odgovori " + o_jezik + "."
#    Settings.llm.system_prompt = system_prompt
    
    response = chat_engine.chat(str({"role": "user", "content": system_prompt + input_text})).response
#    response = query_engine.query(input_text)
    return response
# gr.Textbox(label="Pitanje:", lines=6),
# outputs=[gr.Textbox(label="Odgovor:", lines=6)], 
# ChatMessage(role="assistant", content="Kako Vam mogu pomoći?")
with gr.Blocks() as iface:
    ichat = gr.ChatInterface(fn=rag,        
        title="UChat",
        description="Postavite pitanje ili opišite problem koji imate - nakon promene jezika ili pre početka nove sesije sa agentom pritisnite dugme 'Briši sve - razgovor ispočetka'",
        chatbot=gr.Chatbot(placeholder="Kako Vam mogu pomoći?", type="tuples", label="Agent podrške", height=350),
        textbox=gr.Textbox(placeholder="Pitanje ili opis problema", container=False, scale=7),
        autofocus = True,
        theme="soft",
        examples = [
                    ["Ne radi mi internet", "srpski", ],
                    ["Možete li mi popraviti kompjuter koji koristi internet?", "srpski", ],
                    ["Ne radi mi daljinski upravljač, šta da radim?", "srpski", ],
                    ["EON daljinski upravljalnik mi ne deluje, kaj naj naredim?", "slovenski", ],
                    ["Мојот кабелски прием не работи, што треба да направам?", "makedonski", ],
        ],
        cache_examples=False,
        retry_btn=None,
        undo_btn=None,
        clear_btn="Briši sve - razgovor ispočetka",
        additional_inputs = [gr.Dropdown(["slovenski", "hrvatski", "srpski", "makedonski", "Eksperimentalna opcija"], value="srpski", label="Jezik", info="komunikacije"),
#                             gr.File()
                         ],
        additional_inputs_accordion="Jezik i ostale opcije",
    )
#    login_button = gr.LoginButton("Hugging Face login", size="lg")
    ichat.clear_btn.click(resetChat)

#with gr.Blocks() as iface:
#    gr.Markdown("Uchat")
#    file_out = gr.File()
#    with gr.Row():
#        with gr.Column(scale=1):
#            inp = gr.Textbox(label="Pitanje:", lines=6)
#            u = gr.UploadButton("Upload a file", file_count="single")
#        with gr.Column(scale=1):
#            out = gr.Textbox(label="Odgovor:", lines=6)
#            sub = gr.Button("Pokreni")
#
#    u.upload(upload_file, u, file_out)
#    sub.click(rag, inp, out)
    
iface.launch()