dominiks commited on
Commit
2570365
·
verified ·
1 Parent(s): 2c0d7eb

Upload 3 files

Browse files
.gitattributes CHANGED
@@ -33,3 +33,4 @@ saved_model/**/* filter=lfs diff=lfs merge=lfs -text
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
 
 
33
  *.zip filter=lfs diff=lfs merge=lfs -text
34
  *.zst filter=lfs diff=lfs merge=lfs -text
35
  *tfevents* filter=lfs diff=lfs merge=lfs -text
36
+ NJ_opinions_modernbert_splitter.jsonl filter=lfs diff=lfs merge=lfs -text
NJ_caselaw_metadata.json ADDED
The diff for this file is too large to render. See raw diff
 
NJ_opinions_modernbert_splitter.jsonl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:7e4d9d8c12e6784a66dfb819ddc473b76420e5d198337cd10ac0e68b93ef3466
3
+ size 670176621
app.py CHANGED
@@ -7,7 +7,7 @@ import time
7
  import torch
8
  # from retrieval import *
9
  import os
10
- from transformers import AutoTokenizer, AutoModel, pipeline , AutoModelForSequenceClassification
11
  from sentence_transformers import SentenceTransformer
12
  import faiss
13
  import numpy as np
@@ -15,25 +15,483 @@ import pandas as pd
15
  import torch.nn.functional as F
16
  from datasets import concatenate_datasets, load_dataset, load_from_disk
17
  from huggingface_hub import hf_hub_download
18
- import random
19
  from contextual import ContextualAI
20
  from openai import AzureOpenAI
21
- from transformers import pipeline, set_seed
22
 
 
 
 
 
23
 
24
- generator = pipeline('text-generation', model='gpt2', device_map="auto")
25
 
26
- @spaces.GPU
27
- def respond(message, chat_history):
28
- bot_message = generator(message, max_length=10)[0]["generated_text"]
29
- chat_history.append({"role": "user", "content": message})
30
- chat_history.append({"role": "assistant", "content": bot_message})
31
- return "", chat_history
32
 
33
- with gr.Blocks() as demo:
34
- chatbot = gr.Chatbot(type="messages")
35
- msg = gr.Textbox()
36
- clear = gr.ClearButton([msg, chatbot])
37
- msg.submit(respond, [msg, chatbot], [msg, chatbot])
38
 
39
- demo.launch()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  import torch
8
  # from retrieval import *
9
  import os
10
+ from transformers import AutoTokenizer, AutoModel, pipeline , AutoModelForSequenceClassification, AutoModelForCausalLM
11
  from sentence_transformers import SentenceTransformer
12
  import faiss
13
  import numpy as np
 
15
  import torch.nn.functional as F
16
  from datasets import concatenate_datasets, load_dataset, load_from_disk
17
  from huggingface_hub import hf_hub_download
 
18
  from contextual import ContextualAI
19
  from openai import AzureOpenAI
20
+ from datetime import datetime
21
 
22
+ """
23
+ # to switch:
24
+ device to cuda
25
+ enable bfloat16
26
 
27
+ """
28
 
 
 
 
 
 
 
29
 
 
 
 
 
 
30
 
31
+ sandbox_api_key=os.getenv('AI_SANDBOX_KEY')
32
+ sandbox_endpoint="https://api-ai-sandbox.princeton.edu/"
33
+ sandbox_api_version="2024-02-01"
34
+
35
+ def text_prompt_call(model_to_be_used, system_prompt, user_prompt ):
36
+ client = AzureOpenAI(
37
+ api_key=sandbox_api_key,
38
+ azure_endpoint = sandbox_endpoint,
39
+ api_version=sandbox_api_version # current api version not in preview
40
+ )
41
+ response = client.chat.completions.create(
42
+ model=model_to_be_used,
43
+ temperature=0.7, # temperature = how creative/random the model is in generating response - 0 to 1 with 1 being most creative
44
+ max_tokens=1000, # max_tokens = token limit on context to send to the model
45
+ messages=[
46
+ {"role": "system", "content": system_prompt}, # describes model identity and purpose
47
+ {"role": "user", "content": user_prompt}, # user prompt
48
+ ]
49
+ )
50
+ return response.choices[0].message.content
51
+
52
+
53
+
54
+ api_key = os.getenv("contextual_apikey")
55
+ base_url = "https://api.contextual.ai/v1"
56
+ rerank_api_endpoint = f"{base_url}/rerank"
57
+ reranker = "ctxl-rerank-en-v1-instruct"
58
+
59
+
60
+
61
+
62
+ #client = ContextualAI (api_key = api_key, base_url = base_url)
63
+
64
+ """
65
+
66
+ documents = [i["text"] for i in results]
67
+ query = results[0]["query"]
68
+ metadata = [i["meta_data"] for i in results]
69
+ model = "ctxl-rerank-en-v1-instruct"
70
+
71
+ query = "Find me NJ App Division Court opinions on whether officers can always order a passenger out of a car?"
72
+
73
+ #instruction = "Prioritize internal sales documents over market analysis reports. More recent documents should be weighted higher. Enterprise portal content supersedes distributor communications."
74
+
75
+ rerank_response = client.rerank.create(
76
+ query = query,
77
+ instruction = instruction,
78
+ documents = documents,
79
+ metadata = metadata,
80
+ model = model
81
+ )
82
+
83
+ print(rerank_response.to_dict())
84
+ """
85
+
86
+ #instruction_model = AutoModelForCausalLM.from_pretrained("Qwen/Qwen2.5-7B-Instruct", torch_dtype=torch.bfloat16, device_map="auto")
87
+ #instruction_tokenizer = AutoTokenizer.from_pretrained("Qwen/Qwen2.5-7B-Instruct")
88
+
89
+ def update_instruction(query):
90
+ system_prompt_instructions = """You are given a query and an instruction. Modify the instruction to prioritize the types of documents the query specifies. If the query asks for specific details (e.g., court level, timeframe, citation importance), incorporate those details into the instruction while maintaining its original structure. If the query does not specify particular document preferences, return "not applicable."
91
+
92
+ Example 1
93
+
94
+ Query: Find me older appellate court opinions on whether officers can always order passengers out of a car.
95
+ Instruction: Prioritize older appellate court opinions
96
+
97
+ Example 2
98
+
99
+ Query: Show me recent Supreme Court rulings on digital privacy rights.
100
+ Output: Prioritize recent Supreme Court opinions.
101
+
102
+ Example 3
103
+
104
+ Query: Find legal opinions on self-defense laws.
105
+ Output: not applicable
106
+
107
+ Example 4
108
+ Query: Locate federal district court rulings from the last five years on employer vaccine mandates.
109
+ Output: Prioritize federal district court rulings from the last five years.
110
+
111
+ Example 5
112
+
113
+ Query: Show me influential appellate court decisions on contract interpretation.
114
+ Output: Prioritize influential appellate court decisions.
115
+
116
+ Example 6
117
+
118
+ Query: Find state supreme court cases that discuss the necessity of search warrants for vehicle searches.
119
+ Output: Prioritize state supreme court cases on search warrants for vehicle searches.
120
+
121
+ Example 7
122
+
123
+ Query: Show me legal opinions about landlord-tenant disputes.
124
+ Output: not applicable
125
+ """
126
+
127
+
128
+ """
129
+ messages = [{"role": "system", "content": system_prompt_instructions}]
130
+ messages.append({"role": "user", "content": "Query: " + query})
131
+ example = instruction_tokenizer.apply_chat_template(messages, add_generation_prompt = True, tokenize=True,pad_to_multiple_of=8, do_pan_and_scan=True, return_tensors="pt")
132
+ out = instruction_model.generate(example, max_new_tokens=50)
133
+ updated = instruction_tokenizer.decode(out[0])
134
+ updated = updated.split("<|im_start|>assistant")[-1].split("<|im_end|>")[0].strip()
135
+ """
136
+
137
+ updated = text_prompt_call("gpt-4o", system_prompt_instructions, query)
138
+
139
+ print ("UPDATED INSTRUCTION HERE", updated)
140
+ if updated == "not applicable":
141
+ return "Prioritize Supreme Court opinions or opinions from higher courts. More recent, highly cited and published documents should also be weighted higher."
142
+
143
+ return updated
144
+ # oh god
145
+
146
+
147
+
148
+
149
+
150
+
151
+ def rerank_with_contextual_AI(results):
152
+ instruction = "Prioritize Supreme Court opinions or opinions from higher courts. More recent, highly cited and published documents should also be weighted higher."
153
+ #instruction = rerank_instruction
154
+ query = results[0]["query"]
155
+ docs = [i["text"] for i in results]
156
+ metadata = [i["meta_data"] for i in results]
157
+
158
+ # rewrite instruction if applicable
159
+ instruction = update_instruction(query)
160
+
161
+ rerank_response = client.rerank.create(
162
+ query = query,
163
+ instruction = instruction,
164
+ documents = docs,
165
+ metadata = metadata,
166
+ model = reranker
167
+ ).to_dict()
168
+ print (rerank_response)
169
+ # {'results': [{'index': 3, 'relevance_score': 0.39700255}, {'index': 2, 'relevance_score': 0.38903061}, {'index': 10, 'relevance_score': 0.36989796}, {'index': 8, 'relevance_score': 0.36830357}, {'index': 1, 'relevance_score': 0.36415816}, {'index': 11, 'relevance_score': 0.35778061}, {'index': 0, 'relevance_score': 0.35586735}, {'index': 4, 'relevance_score': 0.32589286}, {'index': 12, 'relevance_score': 0.32589286}, {'index': 7, 'relevance_score': 0.30931122}, {'index': 9, 'relevance_score': 0.30739796}, {'index': 13, 'relevance_score': 0.29145408}, {'index': 5, 'relevance_score': 0.2755102}, {'index': 6, 'relevance_score': 0.27295918}]}
170
+
171
+ #ok, what next?
172
+ reranked_docs = []
173
+ for i in rerank_response["results"]:
174
+ reranked_docs.append(results[i["index"]])
175
+ reranked_docs[-1]["relevance_score"] = i["relevance_score"]
176
+ return reranked_docs
177
+
178
+ def format_metadata_for_reranking(metadata):
179
+ try:
180
+ out = metadata["case_name"] + ", " + metadata["court_short_name"] + ", " + "year: " + metadata["date_filed"] + " citation count: " + str(metadata["citation_count"]) + ", precedential status " + metadata["precedential_status"]
181
+ except:
182
+ out = ""
183
+ return out
184
+
185
+
186
+ def format_metadata_as_str(metadata):
187
+ try:
188
+ out = metadata["case_name"] + ", " + metadata["court_short_name"] + ", " + metadata["date_filed"] + ", precedential status " + metadata["precedential_status"]
189
+ except:
190
+ out = ""
191
+ return out
192
+
193
+ def show_user_query(user_message, history):
194
+ '''
195
+ Displays user query in the chatbot and removes from textbox.
196
+ :param user_message: user query inputted.
197
+ :param history: 2D array representing chatbot-user conversation.
198
+ :return:
199
+ '''
200
+ return "", history + [[user_message, None]]
201
+
202
+
203
+
204
+ def run_extractive_qa(query, contexts):
205
+ extracted_passages = extractive_qa([{"question": query, "context": context} for context in contexts])
206
+ return extracted_passages
207
+
208
+
209
+ @spaces.GPU(duration=15)
210
+ def respond_user_query(history):
211
+ '''
212
+ Overwrite the value of current pairing's history with generated text
213
+ and displays response character-by-character with some lag.
214
+ :param history: 2D array of chatbot history filled with user-bot interactions
215
+ :return: history updated with bot's latest message.
216
+ '''
217
+ start_time_global = time.time()
218
+
219
+ query = history[0][0]
220
+ start_time_global = time.time()
221
+
222
+ responses = run_retrieval(query)
223
+ print("--- run retrieval: %s seconds ---" % (time.time() - start_time_global))
224
+ #print (responses)
225
+
226
+ contexts = [individual_response["text"] for individual_response in responses][:NUM_RESULTS]
227
+ extracted_passages = run_extractive_qa(query, contexts)
228
+
229
+ for individual_response, extracted_passage in zip(responses, extracted_passages):
230
+ start, end = extracted_passage["start"], extracted_passage["end"]
231
+ # highlight text
232
+ text = individual_response["text"]
233
+ text = text[:start] + " **" + text[start:end] + "** " + text[end:]
234
+
235
+ # display queries in interface
236
+ formatted_response = "##### "
237
+ if individual_response["meta_data"]:
238
+ formatted_response += individual_response["meta_data"]
239
+ else:
240
+ formatted_response += individual_response["opinion_idx"]
241
+ formatted_response += "\n" + text + "\n\n"
242
+ history = history + [[None, formatted_response]]
243
+ print("--- Extractive QA: %s seconds ---" % (time.time() - start_time_global))
244
+
245
+ return [history, responses]
246
+
247
+ def switch_to_reviewing_framework():
248
+ '''
249
+ Replaces textbox for entering user query with annotator review select.
250
+ :return: updated visibility for textbox and radio button props.
251
+ '''
252
+ return gr.Textbox(visible=False), gr.Dataset(visible=False), gr.Textbox(visible=True, interactive=True), gr.Button(visible=True)
253
+
254
+ def reset_interface():
255
+ '''
256
+ Resets chatbot interface to original position where chatbot history,
257
+ reviewing is invisbile is empty and user input textbox is visible.
258
+ :return: textbox visibility, review radio button invisibility,
259
+ next_button invisibility, empty chatbot
260
+ '''
261
+
262
+ # remove tmp highlighted word documents
263
+ #for fn in os.listdir("tmp-docs"):
264
+ # os.remove(os.path.join("tmp-docs", fn))
265
+ return gr.Textbox(visible=True), gr.Button(visible=False), gr.Textbox(visible=False, value=""), None, gr.JSON(visible=False, value=[]), gr.Dataset(visible=True)
266
+
267
+ ###################################################
268
+ def mark_like(response_json, like_data: gr.LikeData):
269
+ index_of_msg_reviewed = like_data.index[0] - 1 # 0-indexing
270
+ # add liked information to res
271
+ response_json[index_of_msg_reviewed]["is_msg_liked"] = like_data.liked
272
+ return response_json
273
+
274
+ """
275
+ def save_json(name: str, greetings: str) -> None:
276
+
277
+ """
278
+ def register_review(history, additional_feedback, response_json):
279
+ '''
280
+ Writes user review to output file.
281
+ :param history: 2D array representing bot-user conversation so far.
282
+ :return: None, writes to output file.
283
+ '''
284
+
285
+ res = { "user_query": history[0][0],
286
+ "responses": response_json,
287
+ "timestamp": datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
288
+ "additional_feedback": additional_feedback
289
+ }
290
+ print (res)
291
+
292
+
293
+ # load search functionality here
294
+
295
+
296
+ def load_bm25():
297
+ stemmer = Stemmer.Stemmer("english")
298
+ retriever = bm25s.BM25.load("NJ_index_LLM_chunking", mmap=False)
299
+ return retriever, stemmer # titles
300
+
301
+ def run_bm25(query):
302
+ query_tokens = bm25s.tokenize(query, stemmer=stemmer)
303
+ results, scores = retriever.retrieve(query_tokens, k=5)
304
+ return results[0]
305
+
306
+ def load_faiss_index(embeddings):
307
+ nb, d = embeddings.shape # database size, dimension
308
+ faiss_index = faiss.IndexFlatL2(d) # build the index
309
+ faiss_index.add(embeddings) # add vectors to the index
310
+ return faiss_index
311
+
312
+ #@spaces.GPU(duration=10)
313
+ def run_dense_retrieval(query):
314
+ if "NV" in model_name:
315
+ query_prefix = "Instruct: Given a question, retrieve passages that answer the question\nQuery: "
316
+ max_length = 32768
317
+ print (query)
318
+ with torch.no_grad():
319
+ query_embeddings = model.encode([query], instruction=query_prefix, max_length=max_length)
320
+ query_embeddings = F.normalize(query_embeddings, p=2, dim=1)
321
+ query_embeddings = query_embeddings.cpu().numpy()
322
+ return query_embeddings
323
+
324
+
325
+ def load_NJ_caselaw():
326
+ if os.path.exists("/scratch/gpfs/ds8100/datasets/NJ_opinions_modernbert_splitter.jsonl"):
327
+ df = pd.read_json("/scratch/gpfs/ds8100/datasets/NJ_opinions_modernbert_splitter.jsonl", lines=True)
328
+ else:
329
+ df = pd.read_json("NJ_opinions_modernbert_splitter.jsonl", lines=True)
330
+ titles, chunks = [],[]
331
+
332
+ for i, row in df.iterrows():
333
+ texts = [i for i in row["texts"] if len(i.split()) > 25 and len(i.split()) < 750]
334
+ texts = [" ".join(i.strip().split()) for i in texts]
335
+ chunks.extend(texts)
336
+ titles.extend([row["id"]] * len(texts))
337
+ ids = list(range(len(titles)))
338
+ assert len(ids) == len(titles) == len(chunks)
339
+ return ids, titles, chunks
340
+
341
+
342
+ def run_retrieval(query):
343
+ query = " ".join(query.split())
344
+
345
+ print ("query", query)
346
+ """
347
+ indices_bm25 = run_bm25(query)
348
+ scores_embeddings, indices_embeddings = run_dense_retrieval(query)
349
+ indices = list(set(indices_bm25).union(indices_embeddings))
350
+ #docs = [{"id":i, "text":chunks[i]} for i in indices]
351
+ docs = [chunks[i] for i in indices]
352
+ results_reranking = rerank(query, docs, indices) #results = [{"doc":docs[i], "score":probs[i], "id":indices[i]} for i in argsort]
353
+ """
354
+ start_time = time.time()
355
+ query_embeddings = run_dense_retrieval(query)
356
+ print("--- Nvidia Embedding: %s seconds ---" % (time.time() - start_time))
357
+ D, I = faiss_index.search(query_embeddings, 45)
358
+ print("--- Faiss retrieval: %s seconds ---" % (time.time() - start_time))
359
+
360
+ scores_embeddings = D[0]
361
+ indices_embeddings = I[0]
362
+
363
+ docs = [chunks[i] for i in indices_embeddings]
364
+ results = [{"id":i, "score":j} for i,j in zip(indices_embeddings, scores_embeddings)]
365
+
366
+ out_dict = []
367
+ covered = set()
368
+ for item in results:
369
+ tmp = {}
370
+ index = item["id"]
371
+ tmp["query"] = query
372
+ tmp["index"] = index #indices[index]
373
+ tmp["NV_score"] = item["score"]
374
+ tmp["opinion_idx"] = str(titles[index])
375
+ # and htis helps
376
+ if tmp["opinion_idx"] in covered:
377
+ continue
378
+ covered.add(tmp["opinion_idx"])
379
+ if tmp["opinion_idx"] in metadata:
380
+ tmp["meta_data"] = format_metadata_for_reranking(metadata[tmp["opinion_idx"]])
381
+ else:
382
+ tmp["meta_data"] = ""
383
+ # so far so good
384
+ tmp["text"] = chunks[tmp["index"]]
385
+ out_dict.append(tmp)
386
+ print (out_dict)
387
+ # and now, rerank
388
+ #out_dict = out_dict[:NUM_RESULTS]
389
+ #out_dict = rerank_with_contextual_AI(out_dict)
390
+ return out_dict
391
+
392
+
393
+ NUM_RESULTS = 5
394
+ model_name = 'nvidia/NV-Embed-v2'
395
+
396
+ device = torch.device("cuda")
397
+ #device = torch.device("cpu")
398
+ #device = torch.device("mps")
399
+
400
+ extractive_qa = pipeline("question-answering", model="ai-law-society-lab/extractive-qa-model", tokenizer="FacebookAI/roberta-large", device_map="auto", token=os.getenv('hf_token'))
401
+ ids, titles, chunks = load_NJ_caselaw()
402
+
403
+ ds = load_dataset("ai-law-society-lab/NJ_embeddings", token=os.getenv('hf_token'))["train"]
404
+ ds = ds.with_format("np")
405
+ print (ds)
406
+ faiss_index = load_faiss_index(ds["embeddings"])
407
+
408
+ with open("NJ_caselaw_metadata.json") as f:
409
+ metadata = json.load(f)
410
+
411
+
412
+
413
+ def load_embeddings_model(model_name = "intfloat/e5-large-v2"):
414
+ # let's try to not rely on sentencetransformer at some point in the future?
415
+ if "NV" in model_name:
416
+ model = AutoModel.from_pretrained('nvidia/NV-Embed-v2', trust_remote_code=True, torch_dtype=torch.bfloat16, device_map="auto")
417
+ #model = AutoModel.from_pretrained('nvidia/NV-Embed-v2', trust_remote_code=True, torch_dtype=torch.float16, device_map="auto")
418
+ model.eval()
419
+ #model.to(device)
420
+ return model
421
+
422
+ if "NV" in model_name:
423
+ model = load_embeddings_model(model_name=model_name)
424
+
425
+
426
+ examples = ["Can officers always order a passenger out of a car?","Find me briefs about credential searches", "Can police search an impounded car without a warrant?", "State is arguing State v. Carty is not good law"]
427
+
428
+ css = """
429
+ .svelte-i3tvor {visibility: hidden}
430
+ .row.svelte-hrj4a0.unequal-height {
431
+ align-items: stretch !important
432
+ }
433
+ """
434
+
435
+ """
436
+ with gr.Blocks(css=css, theme = gr.themes.Monochrome(primary_hue="pink",)) as demo:
437
+ chatbot = gr.Chatbot(height="45vw", autoscroll=False)
438
+ query_textbox = gr.Textbox()
439
+ examples = gr.Examples(examples, query_textbox)
440
+ response_json = gr.JSON(visible=False, value=[])
441
+ chatbot.like(mark_like, response_json, response_json)
442
+
443
+ with gr.Row(visible=False, equal_height=True) as downloadable_file_row:
444
+ @gr.render(inputs=response_json)
445
+ def set_download_files(response_json):
446
+ seen_files = set()
447
+ for response in response_json:
448
+ if response["path_file"] not in seen_files:
449
+ # use metadata title if it exists
450
+ title = response["title"]
451
+ if response["meta_data"]:
452
+ title = response["meta_data"]
453
+ gr.DownloadButton(label="Download: " + title, value = response["path_file"], visible=True, size="sm")
454
+ seen_files.add(response["path_file"])
455
+
456
+ feedback_textbox = gr.Textbox(label="Additional feedback?", visible=False)
457
+ next_button = gr.Button(value="Submit Feedback", visible=False)
458
+
459
+ # Handle annotator query
460
+ query_textbox.submit(show_user_query, [query_textbox, chatbot], [query_textbox, chatbot], queue=False).then(
461
+ respond_user_query, chatbot, [chatbot, response_json]).then(
462
+ switch_to_reviewing_framework, None, [query_textbox, examples.dataset, downloadable_file_row, feedback_textbox, next_button]
463
+ )
464
+
465
+ # Handle page reset and review save in database
466
+ next_button.click(register_review, [chatbot, feedback_textbox, response_json], None).then(
467
+ reset_interface, None, [query_textbox, next_button, feedback_textbox, chatbot, downloadable_file_row, response_json, examples.dataset])
468
+ #next_button.click(register_review, [chatbot, feedback_textbox, response_json], None).then(
469
+ reset_interface, None, [query_textbox, next_button, feedback_textbox, chatbot, downloadable_file_row, response_json, examples.dataset])
470
+
471
+
472
+ # Launch application
473
+ demo.launch()
474
+ """
475
+ with gr.Blocks(css=css, theme = gr.themes.Monochrome(primary_hue="pink",)) as demo:
476
+ chatbot = gr.Chatbot(height="45vw", autoscroll=False)
477
+ query_textbox = gr.Textbox()
478
+ #rerank_instruction = gr.Textbox(label="Rerank Instruction Prompt", value="If not otherwise specified in the query, prioritize Supreme Court opinions or opinions from higher courts. More recent, highly cited and published documents should also be weighted higher, unless otherwise specified in the query.")
479
+ examples = gr.Examples(examples, query_textbox)
480
+ response_json = gr.JSON(visible=False, value=[])
481
+ print (response_json)
482
+ chatbot.like(mark_like, response_json, response_json)
483
+
484
+ feedback_textbox = gr.Textbox(label="Additional feedback?", visible=False)
485
+ next_button = gr.Button(value="Submit Feedback", visible=False)
486
+
487
+ query_textbox.submit(show_user_query, [query_textbox, chatbot], [query_textbox, chatbot], queue=False).then(
488
+ respond_user_query, chatbot, [chatbot, response_json]).then(
489
+ switch_to_reviewing_framework, None, [query_textbox, examples.dataset, feedback_textbox, next_button]
490
+ )
491
+
492
+ # Handle page reset and review save in database
493
+ next_button.click(register_review, [chatbot, feedback_textbox, response_json], None).then(
494
+ reset_interface, None, [query_textbox, next_button, feedback_textbox, chatbot, response_json, examples.dataset])
495
+
496
+ # Launch application
497
+ demo.launch()