georgeek commited on
Commit
b4d9fb1
·
1 Parent(s): 0ea4bb9

two models

Browse files
bill.py → One_model.py RENAMED
File without changes
billPdf.py DELETED
@@ -1,216 +0,0 @@
1
- #!/usr/bin/env -S poetry run python
2
-
3
- import os
4
- import json
5
- #import pdfplumber
6
- import streamlit as st
7
- from openai import OpenAI
8
-
9
- client = OpenAI()
10
-
11
- def load_user_data(user_id):
12
- file_path = os.path.join("data", "user_data", f"user_data_{user_id}.json")
13
- if not os.path.exists(file_path):
14
- return {}
15
- with open(file_path, "r") as file:
16
- return json.load(file)
17
-
18
- def parse_pdf_to_json(pdf_path):
19
- user_id = {}
20
- serie_factura = {}
21
- data_factura = {}
22
- costuri = {}
23
- with pdfplumber.open(pdf_path, ) as pdf:
24
- for page in pdf.pages:
25
- text = page.extract_text()
26
- if text:
27
- lines = text.split('\n')
28
-
29
- # Process each line and look for specific categories
30
- for line in lines:
31
- # Check for 'Data emiterii facturii'
32
- if 'Data facturii' in line:
33
- date = line.split()[-1]
34
- data_factura['Data factura'] = date
35
-
36
- # Check for 'Serie factură'
37
- if 'rul facturii:' in line:
38
- serie = line.split()[-1]
39
- serie_factura['Serie numar'] = serie
40
-
41
- # Check for 'Cont client'
42
- if 'Cont client' in line:
43
- cont = line.split()[-1]
44
- user_id['Cont client'] = cont
45
-
46
- # Check for 'Valoare facturată fără TVA'
47
- if 'Sold precedent' in line:
48
- value = line.split()[-2].replace(',', '.') # Extract and convert to float
49
- costuri['Sold precedent'] = value
50
-
51
- # Check for 'Total bază de impozitare TVA'
52
- elif 'din sold precedent' in line:
53
- value = line.split()[-2].replace(',', '.') # Extract and convert to float
54
- costuri['Total platit din sold precedent'] = value
55
-
56
- # Check for 'TVA'
57
- elif 'TVA' in line and '%' in line:
58
- value = line.split()[-2].replace(',', '.') # Extract and convert to float
59
- costuri['TVA'] = value
60
-
61
- # Check for 'Dobânzi penalizatoare'
62
- elif 'Abonamente' in line:
63
- value = line.split()[-2].replace(',', '.') # Extract and convert to float
64
- costuri['Abonamente si extraopiuni'] = value
65
-
66
- # Check for 'TOTAL DE PLATĂ FACTURĂ CURENTĂ'
67
- elif 'Total factura curenta fara TVA' in line:
68
- value = float(line.split()[-2].replace(',', '.')) # Extract and convert to float
69
- costuri['Total factura curenta fara TVA'] = value
70
-
71
- # Check for 'Sold Cont Contract'
72
- elif 'Servicii utilizate' in line:
73
- value = line.split()[-2].replace(',', '.') # Extract and convert to float
74
- costuri['Servicii utilizate'] = value
75
-
76
- # Check for 'Compensatii'
77
- elif 'Rate terminal' in line:
78
- value = float(line.split()[-2].replace(',', '.')) # Extract and convert to float
79
- costuri['Rate terminal'] = value
80
-
81
- # Check for 'TVA 19,00%'
82
- elif 'TVA 19,00%' in line:
83
- value = float(line.split()[-2].replace(',', '.')) # Extract and convert to float
84
- costuri['TVA'] = value
85
-
86
- # Check for 'Compensatii'
87
- elif 'Total factura curenta' in line:
88
- value = float(line.split()[-2].replace(',', '.')) # Extract and convert to float
89
- costuri['Total factura curenta'] = value
90
-
91
- return costuri
92
-
93
- def check_related_keys(question, user_id):
94
- user_data = load_user_data(user_id)
95
- bill_keys = set()
96
- for bill in user_data.get("bills", []):
97
- bill_keys.update(bill.keys())
98
- return [key for key in bill_keys if key.lower() in question.lower()]
99
-
100
- def process_query(query, user_id):
101
- user_data = load_user_data(user_id)
102
- bill_info = user_data.get("bills", [])
103
- related_keys = check_related_keys(query, user_id)
104
- related_keys_str = ", ".join(related_keys) if related_keys else "N/A"
105
-
106
- if related_keys_str != "N/A":
107
- context = (
108
- f"Citeste informatiile despre costrurile in lei facturate din dictionar: {bill_info} "
109
- f"si raspunde la intrebarea: '{query}' dar numai cu info legate de: {related_keys_str}"
110
- )
111
- else:
112
- context = (
113
- f"Citeste informatiile despre costrurile in lei facturate din dictionar: {bill_info} "
114
- f"si raspunde la intrebarea: '{query}' dar numai cu info legate de factura"
115
- )
116
-
117
- max_input_length = 550
118
- st.write(f"Context:\n{context}")
119
- st.write(f"Context size: {len(context)} characters")
120
-
121
- if len(context) > max_input_length:
122
- st.warning("Prea multe caractere în context, solicitarea nu va fi trimisă.")
123
- return None
124
-
125
- return context
126
-
127
- def main():
128
-
129
- st.title("Telecom Bill Chat with LLM Agent")
130
-
131
- if "user_id" not in st.session_state:
132
- st.session_state.user_id = None
133
-
134
- user_id = st.sidebar.text_input("Introdu numărul de telefon:")
135
- if user_id and user_id != st.session_state.user_id:
136
- data = load_user_data(user_id)
137
- if data:
138
- st.session_state.user_id = user_id
139
- st.success("Utilizator găsit!")
140
- else:
141
- st.warning("Nu am găsit date pentru acest ID. Încărcați o factură PDF la nevoie.")
142
- st.session_state.user_id = user_id
143
-
144
- uploaded_file = st.file_uploader("Încarcă factura PDF", type="pdf")
145
- if uploaded_file and st.session_state.user_id:
146
- bill_data = parse_pdf_to_json(uploaded_file)
147
- existing_data = load_user_data(st.session_state.user_id)
148
- if "bills" not in existing_data:
149
- existing_data["bills"] = []
150
- existing_data["bills"].append(bill_data)
151
- file_path = os.path.join("data", "user_data", f"user_data_{st.session_state['user_id']}.json")
152
- os.makedirs(os.path.dirname(file_path), exist_ok=True)
153
- with open(file_path, "w") as file:
154
- json.dump(existing_data, file)
155
- st.success("Factura a fost încărcată și salvată cu succes!")
156
-
157
- if st.session_state.user_id:
158
- data = load_user_data(st.session_state.user_id)
159
- st.write(f"Phone Number: {st.session_state.user_id}")
160
- st.write("Facturi existente:")
161
- for bill in data.get("bills", []):
162
- st.write(bill)
163
- else:
164
- st.info("Introduceți un ID și/sau încărcați o factură PDF pentru a continua.")
165
-
166
- # Initialize conversation in the session state
167
- # "context_prompt_added" indicates whether we've added the specialized "bill info" context yet.
168
- if "messages" not in st.session_state:
169
- st.session_state["messages"] = [
170
- {"role": "assistant", "content": "Cu ce te pot ajuta?"}
171
- ]
172
- if "context_prompt_added" not in st.session_state:
173
- st.session_state.context_prompt_added = False
174
-
175
- st.write("---")
176
- st.subheader("Chat")
177
-
178
- for msg in st.session_state["messages"]:
179
- st.chat_message(msg["role"]).write(msg["content"])
180
-
181
- if prompt := st.chat_input("Introduceți întrebarea aici:"):
182
- if not st.session_state.user_id:
183
- st.error("Trebuie să introduceți un număr de telefon valid sau să încărcați date.")
184
- return
185
-
186
- # If the context prompt hasn't been added yet, build & inject it once;
187
- # otherwise, just add the user's raw question.
188
- if not st.session_state.context_prompt_added:
189
- final_prompt = process_query(prompt, st.session_state["user_id"])
190
- if final_prompt is None:
191
- st.stop()
192
- st.session_state["messages"].append({"role": "user", "content": final_prompt})
193
- st.session_state.context_prompt_added = True
194
- else:
195
- st.session_state["messages"].append({"role": "user", "content": prompt})
196
-
197
- # Display the latest user message in the chat
198
- st.chat_message("user").write(st.session_state["messages"][-1]["content"])
199
-
200
- # Now call GPT-4 with the entire conversation
201
- completion = client.chat.completions.create(
202
- model="gpt-4",
203
- messages=st.session_state["messages"]
204
- )
205
- response_text = completion.choices[0].message.content.strip()
206
-
207
- st.session_state["messages"].append({"role": "assistant", "content": response_text})
208
- st.chat_message("assistant").write(response_text)
209
-
210
- if hasattr(completion, "usage"):
211
- st.write("Prompt tokens:", completion.usage.prompt_tokens)
212
- st.write("Completion tokens:", completion.usage.completion_tokens)
213
- st.write("Total tokens:", completion.usage.total_tokens)
214
-
215
- if __name__ == "__main__":
216
- main()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
logs/conversation_logs.json CHANGED
@@ -58,5 +58,53 @@
58
  "total_tokens": 1229
59
  },
60
  "cost": 0.018435
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
  }
62
  ]
 
58
  "total_tokens": 1229
59
  },
60
  "cost": 0.018435
61
+ },
62
+ {
63
+ "timestamp": "2025-01-16T10:54:40.132782",
64
+ "user_id": "0724077190",
65
+ "user_query": "cat am de plata",
66
+ "assistant_response": "Pentru a te ajuta, am nevoie de mai multe informa\u021bii despre contextul pl\u0103\u021bii. Este vorba despre o factur\u0103, un credit, un serviciu de telecomunica\u021bii sau altceva? Te rog s\u0103-mi oferi detalii suplimentare pentru a putea oferi un r\u0103spuns corect.",
67
+ "tokens": {
68
+ "prompt_tokens": 22,
69
+ "completion_tokens": 69,
70
+ "total_tokens": 91
71
+ },
72
+ "cost": 0.001365
73
+ },
74
+ {
75
+ "timestamp": "2025-01-16T11:50:17.716138",
76
+ "user_id": "0724077190",
77
+ "user_query": "nu e cam mult?",
78
+ "assistant_response": "Analiz\u00e2nd informa\u021biile furnizate privind factura, observ\u0103m urm\u0103toarele detalii:\n\n1. **Total factur\u0103 curent\u0103:** 104,93 lei\n2. **TVA 19%:** 16,75 lei\n3. **Total rate terminal:** 5.445,53 lei\n4. **Abonamente \u0219i extraop\u021biuni:** 91,17 lei\n5. **Reduceri:** -2,99 lei\n6. **Rest plat\u0103:** -5.073,74 lei\n7. **Sold precedent:** -5.073,74 lei\n8. **Total de plat\u0103:** 476,72 lei\n\nPrincipalul factor care face suma facturii mare este valoarea considerabil\u0103 pentru \"Rate terminal\", care este 5.445,53 lei. Aceasta este o sum\u0103 semnificativ\u0103 \u00een totalul facturii, dar se pare c\u0103 a fost acoperit\u0103 par\u021bial de ajust\u0103rile \u0219i soldul precedent, rezult\u00e2nd \u00eentr-un \"Total de plat\u0103\" de 476,72 lei.\n\nDac\u0103 aceast\u0103 sum\u0103 vi se pare mare, ar putea fi util s\u0103 reevalua\u021bi planurile tarifare \u0219i ratele terminalului pentru o reducere poten\u021bial\u0103 a costurilor viitoare. De asemenea, verificarea detaliat\u0103 a sumelor pentru terminale \u0219i beneficiile sau reducerile aplicate poate oferi o perspectiv\u0103 mai clar\u0103 asupra factorilor care contribuie la totalul de plat\u0103.",
79
+ "tokens": {
80
+ "prompt_tokens": 835,
81
+ "completion_tokens": 313,
82
+ "total_tokens": 1148
83
+ },
84
+ "cost": 0.03444
85
+ },
86
+ {
87
+ "timestamp": "2025-01-16T11:50:17.730726",
88
+ "user_id": "0724077190",
89
+ "user_query": "nu e cam mult?",
90
+ "assistant_response": "Factura are un total de plata de 476.72 lei, iar costurile suplimentare se ridic\u0103 la 5445.53 lei. De asemenea, exist\u0103 o serie de reduceri \u0219i corec\u021bii la costurile utilizatorilor care afecteaz\u0103 suma total\u0103. Chiar dac\u0103 sumele par semnificative, acestea sunt influen\u021bate de diverse categorii de costuri, inclusiv ratele terminale \u0219i abonamentele. A\u0219adar, \u00een contextul totalului de plat\u0103, s-ar putea spune c\u0103 suma este relativ mare, dar trebuie analizat\u0103 \u00een func\u021bie de serviciile \u0219i produsele incluse.",
91
+ "tokens": {
92
+ "prompt_tokens": 835,
93
+ "completion_tokens": 133,
94
+ "total_tokens": 968
95
+ },
96
+ "cost": 0.014519999999999998
97
+ },
98
+ {
99
+ "timestamp": "2025-01-16T11:53:39.957975",
100
+ "user_id": "0724077190",
101
+ "user_query": "dar pe umere care costa mai mult?",
102
+ "assistant_response": "Pe baza informa\u021biilor furnizate \u00een factur\u0103:\n\n1. **Total Rate Terminal:** 5.445,53 lei\n2. **Abonamente \u0219i Extraop\u021biuni:** 91,17 lei (incluz\u00e2nd costuri \u0219i reduceri)\n\nDin aceste date, reiese c\u0103 **ratele terminale**, cu o valoare semnificativ\u0103 de 5.445,53 lei, cost\u0103 mult mai mult comparativ cu **abonamentele \u0219i extraop\u021biunile** care totalizeaz\u0103 91,17 lei (dup\u0103 aplicarea reducerilor).\n\nA\u0219adar, costul pe ratele terminale este semnificativ mai mare dec\u00e2t costurile pentru abonamente \u0219i extraop\u021biuni.",
103
+ "tokens": {
104
+ "prompt_tokens": 1300,
105
+ "completion_tokens": 152,
106
+ "total_tokens": 1452
107
+ },
108
+ "cost": 0.021779999999999997
109
  }
110
  ]
pages/Two_models.py ADDED
@@ -0,0 +1,306 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env -S poetry run python
2
+
3
+ import os
4
+ import json
5
+ import streamlit as st
6
+ from openai import OpenAI
7
+ from dotenv import load_dotenv
8
+
9
+ # Load environment variables from .env file
10
+ load_dotenv()
11
+
12
+ # Get the OpenAI API key from environment variables
13
+ api_key = os.getenv("OPENAI_API_KEY")
14
+ if not api_key:
15
+ raise ValueError("The OPENAI_API_KEY environment variable is not set.")
16
+
17
+ client = OpenAI()
18
+
19
+
20
+ def load_user_data(user_id):
21
+ file_path = os.path.join(os.getcwd(), "data", "user_data", f"user_data_{user_id}.json")
22
+ #st.write(f"Loading user data from: {file_path}")
23
+ #st.write(f"Current working directory: {os.getcwd()}")
24
+
25
+ #Verify if the file exists
26
+ if not os.path.exists(file_path):
27
+ #st.write("File does not exist.")
28
+ return {}
29
+
30
+ try:
31
+ with open(file_path, "r") as file:
32
+ data = json.load(file)
33
+ #st.write(f"Loaded data: {data}")
34
+ return data
35
+ except json.JSONDecodeError:
36
+ st.write("Error decoding JSON.")
37
+ return {}
38
+ except Exception as e:
39
+ st.write(f"An error occurred: {e}")
40
+ return {}
41
+
42
+
43
+ def save_user_data(user_id, data):
44
+ file_path = os.path.join("data", "user_data", f"user_data_{user_id}.json")
45
+ os.makedirs(os.path.dirname(file_path), exist_ok=True)
46
+ with open(file_path, "w") as file:
47
+ json.dump(data, file)
48
+
49
+ def parseBill(data):
50
+ billDate = data.get("billDate")
51
+ billNo = data.get("billNo")
52
+ amountDue = data.get("amountDue")
53
+ extraCharge = data.get("extraCharge")
54
+ taxItems = data.get("taxItem", [])
55
+ subscribers = data.get("subscribers", [])
56
+
57
+ totalBillCosts = [{"categorie": t.get("cat"), "amount": t.get("amt")} for t in taxItems]
58
+ subscriberCosts = []
59
+ categories = set()
60
+ names = set()
61
+
62
+ for sub in subscribers:
63
+ logicalResource = sub.get("logicalResource")
64
+ billSummaryItems = sub.get("billSummaryItem", [])
65
+ for item in billSummaryItems:
66
+ try:
67
+ categories.add(item["cat"]),
68
+ names.add(item["name"])
69
+ except KeyError:
70
+ continue
71
+
72
+ subscriberCosts.append({
73
+ "Numar telefon": logicalResource,
74
+ "Categorie cost": item["cat"],
75
+ "Cost": item["name"],
76
+ "Valoare": item["amt"]
77
+ })
78
+
79
+
80
+ return {
81
+ "Data factura": billDate,
82
+ "Serie numar factura": billNo,
83
+ "De plata": amountDue,
84
+ "Costuri suplimentare": extraCharge,
85
+ "Total plata factura": totalBillCosts,
86
+ "Costuri utilizatori": subscriberCosts,
87
+ "Categorii": list(categories),
88
+ "Costuri": list(names)
89
+ }
90
+
91
+ def check_related_keys(question, user_id):
92
+ user_data = load_user_data(user_id)
93
+ categories = set()
94
+ for bill in user_data.get("bills", []):
95
+ categories.update(bill.get("Categorii", []))
96
+ st.write(f"Categorii: {categories}")
97
+ return [category for category in categories if category.lower() in question.lower()]
98
+
99
+ def process_query(query, user_id, model_name):
100
+ user_data = load_user_data(user_id)
101
+ bill_info = user_data.get("bills", [])
102
+ related_keys = check_related_keys(query, user_id)
103
+ related_keys_str = ", ".join(related_keys) if related_keys else "N/A"
104
+
105
+ if related_keys_str != "N/A":
106
+ context = (
107
+ f"Citeste informatiile despre costurile in lei facturate din json: {bill_info} "
108
+ f"si raspunde la intrebarea: '{query}' dar numai cu info legate de: {related_keys_str}"
109
+ )
110
+ else:
111
+ context = (
112
+ f"Citeste informatiile despre costrurile in lei facturate din json: {bill_info} "
113
+ f"si raspunde la intrebarea: '{query}' dar numai cu info legate de factura"
114
+ )
115
+
116
+ max_input_length = 5550
117
+ #st.write(f"Context:\n{context}")
118
+ st.write(f"Context size: {len(context)} characters")
119
+
120
+ if len(context) > max_input_length:
121
+ st.warning("Prea multe caractere în context, solicitarea nu va fi trimisă.")
122
+ return None
123
+
124
+ # Update this part to run the chosen model
125
+ if model_name == "gpt-4o-mini":
126
+ # Code to run model 4o mini
127
+ st.write("Running model GPT-4o-mini")
128
+ elif model_name == "gpt-4o":
129
+ # Code to run model 4o
130
+ st.write("Running model GPT-4o")
131
+
132
+ return context
133
+
134
+ # import the datetime class from the datetime module
135
+ from datetime import datetime
136
+ def log_conversation(user_id, user_query, assistant_response, tokens, cost):
137
+ log_entry = {
138
+ "timestamp": datetime.now().isoformat(),
139
+ "user_id": user_id,
140
+ "user_query": user_query,
141
+ "assistant_response": assistant_response,
142
+ "tokens": tokens,
143
+ "cost": cost
144
+ }
145
+ log_file_path = os.path.join("logs", "conversation_logs.json")
146
+ os.makedirs(os.path.dirname(log_file_path), exist_ok=True)
147
+ if os.path.exists(log_file_path):
148
+ with open(log_file_path, "r") as log_file:
149
+ logs = json.load(log_file)
150
+ else:
151
+ logs = []
152
+ logs.append(log_entry)
153
+ with open(log_file_path, "w") as log_file:
154
+ json.dump(logs, log_file, indent=4)
155
+
156
+
157
+ def main():
158
+ st.title("Bill info LLM Agent (OpenAI)")
159
+ st.image("https://miro.medium.com/v2/resize:fit:100/format:webp/1*NfE0G4nEj4xX7Z_8dSx83g.png")
160
+
161
+ # Create a sidebar menu to choose between models
162
+ model_name = st.sidebar.selectbox("Choose OpenAI Model", ["gpt-4o-mini", "gpt-4o"])
163
+ if "user_id" not in st.session_state:
164
+ st.session_state.user_id = None
165
+
166
+ user_id = st.sidebar.text_input("Introdu numărul de telefon:", placeholder="Incearca 0724077190")
167
+
168
+ # use a predefined user_id for testing
169
+
170
+
171
+
172
+ # display the user data if the user_id is set
173
+ #st.write(f"User ID: {user_id}")
174
+
175
+ st.session_state.user_data = None
176
+
177
+ if user_id and user_id != st.session_state.user_id:
178
+ data = load_user_data(user_id)
179
+ st.session_state.user_data = data
180
+ if data:
181
+ st.session_state.user_id = user_id
182
+ st.success("Utilizator găsit!")
183
+ st.write(f"Numar telefon: {st.session_state.user_id}")
184
+ st.session_state.user_data = data
185
+
186
+ else:
187
+ st.warning("Nu am găsit date pentru acest ID.")
188
+ st.warning("Încărcați o factură json.")
189
+ st.session_state.user_id = user_id
190
+ st.session_state.user_data = None
191
+
192
+ # If the user has no data yet Show the upload (st.file_uploader...) dialog ,
193
+ # If the user has stored data in data\user_data\"user_data{user_id}.json, display the existing bills data - st.write(bill) but compacted
194
+ if st.session_state.user_data:
195
+ st.write("Facturi existente (extras):")
196
+ for bill in st.session_state.user_data.get("bills", []):
197
+ st.write({
198
+ "Data factura": bill.get("Data factura"),
199
+ "Serie numar factura": bill.get("Serie numar factura"),
200
+ "De plata": bill.get("De plata"),
201
+ "Costuri suplimentare": bill.get("Costuri suplimentare")
202
+ })
203
+ if not st.session_state.user_data:
204
+ uploaded_file = st.file_uploader("Incarca factura", type="json")
205
+ if uploaded_file and st.session_state.user_id:
206
+ bill_data = json.load(uploaded_file)
207
+ parsed_bill = parseBill(bill_data)
208
+ existing_data = load_user_data(st.session_state.user_id)
209
+
210
+ # Check if the billNo already exists in the existing data
211
+ existing_bill_nos = [bill.get("Data factura") for bill in existing_data.get("bills", [])]
212
+ if parsed_bill.get("Data factura") in existing_bill_nos:
213
+ st.warning("Factură existentă.")
214
+ else:
215
+ if "bills" not in existing_data:
216
+ existing_data["bills"] = []
217
+ existing_data["bills"].append(parsed_bill)
218
+ save_user_data(st.session_state.user_id, existing_data)
219
+ st.success("Factura a fost încărcată și salvată cu succes!")
220
+
221
+
222
+
223
+ # Initialize conversation in the session state
224
+ # "context_prompt_added" indicates whether we've added the specialized "bill info" context yet.
225
+ if "messages" not in st.session_state:
226
+ st.session_state["messages"] = [
227
+ {"role": "assistant", "content": "Cu ce te pot ajuta?"}
228
+ ]
229
+ if "context_prompt_added" not in st.session_state:
230
+ st.session_state.context_prompt_added = False
231
+
232
+ st.write("---")
233
+ st.subheader("Chat")
234
+
235
+
236
+ for msg in st.session_state["messages"]:
237
+ st.chat_message(msg["role"]).write(msg["content"])
238
+
239
+ if prompt := st.chat_input("Introduceți întrebarea aici:"):
240
+ if not st.session_state.user_id:
241
+ st.error("Trebuie să introduci un număr de telefon valid sau să încarci date.")
242
+ return
243
+
244
+ # If the context prompt hasn't been added yet, build & inject it once;
245
+ # otherwise, just add the user's raw question.
246
+ if not st.session_state.context_prompt_added:
247
+ final_prompt = process_query(prompt, st.session_state["user_id"], "gpt-4o")
248
+ if final_prompt is None:
249
+ st.stop()
250
+ st.session_state["messages"].append({"role": "user", "content": final_prompt})
251
+ st.session_state.context_prompt_added = True
252
+ else:
253
+ st.session_state["messages"].append({"role": "user", "content": prompt})
254
+
255
+ # Display the latest user message in the chat
256
+ st.chat_message("user").write(st.session_state["messages"][-1]["content"])
257
+
258
+ # Display the related keys
259
+ related_keys = check_related_keys(prompt, st.session_state["user_id"])
260
+ st.write("Focus pe entitatile:", related_keys)
261
+
262
+ # Call GPT-4o model
263
+ completion_4o = client.chat.completions.create(
264
+ model="gpt-4o",
265
+ messages=st.session_state["messages"]
266
+ )
267
+ response_text_4o = completion_4o.choices[0].message.content.strip()
268
+
269
+ # Call GPT-4o-mini model
270
+ completion_4o_mini = client.chat.completions.create(
271
+ model="gpt-4o-mini",
272
+ messages=st.session_state["messages"]
273
+ )
274
+ response_text_4o_mini = completion_4o_mini.choices[0].message.content.strip()
275
+
276
+ st.session_state["messages"].append({"role": "assistant", "content": response_text_4o})
277
+ st.session_state["messages"].append({"role": "assistant", "content": response_text_4o_mini})
278
+
279
+ col1, col2 = st.columns(2)
280
+ with col1:
281
+ st.subheader("GPT-4o")
282
+ st.chat_message("assistant").write(response_text_4o)
283
+ # Log the conversation for GPT-4o
284
+ if hasattr(completion_4o, "usage"):
285
+ prompt_tokens_4o = completion_4o.usage.prompt_tokens
286
+ completion_tokens_4o = completion_4o.usage.completion_tokens
287
+ total_tokens_4o = completion_4o.usage.total_tokens
288
+ st.write("GPT-4o Prompt tokens:", prompt_tokens_4o)
289
+ st.write("GPT-4o Completion tokens:", completion_tokens_4o)
290
+ st.write("GPT-4o Total tokens:", total_tokens_4o)
291
+ with col2:
292
+ st.subheader("GPT-4o-mini")
293
+ st.chat_message("assistant").write(response_text_4o_mini)
294
+ if hasattr(completion_4o_mini, "usage"):
295
+ prompt_tokens_4o_mini = completion_4o_mini.usage.prompt_tokens
296
+ completion_tokens_4o_mini = completion_4o_mini.usage.completion_tokens
297
+ total_tokens_4o_mini = completion_4o_mini.usage.total_tokens
298
+ st.write("GPT-4o-mini Prompt tokens:", prompt_tokens_4o_mini)
299
+ st.write("GPT-4o-mini Completion tokens:", completion_tokens_4o_mini)
300
+ st.write("GPT-4o-mini Total tokens:", total_tokens_4o_mini)
301
+
302
+
303
+
304
+
305
+ if __name__ == "__main__":
306
+ main()