manasdhir commited on
Commit
efa9d0b
·
1 Parent(s): 5d07afe

minor changes

Browse files
Files changed (6) hide show
  1. LLM.py +3 -3
  2. chunking.py +251 -64
  3. clean.py +13 -9
  4. content.txt +0 -0
  5. doc_anal.py +2 -2
  6. uv.lock +273 -0
LLM.py CHANGED
@@ -67,6 +67,6 @@ if __name__=="__main__":
67
  ]
68
  context=get_context_for_questions(questions)
69
  from chunking import word_count
70
- print(word_count(context[0]))
71
- #prompts=construct_prompts(questions,context)
72
- #print(generate_answers(prompts))
 
67
  ]
68
  context=get_context_for_questions(questions)
69
  from chunking import word_count
70
+ #print(word_count(context[0]))
71
+ prompts=construct_prompts(questions,context)
72
+ print(generate_answers(prompts))
chunking.py CHANGED
@@ -1,3 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import re
2
  from typing import List
3
 
@@ -10,28 +164,67 @@ def split_paragraphs(text: str) -> List[str]:
10
  """
11
  Split text by double newlines assuming paragraphs separated by blank lines.
12
  """
13
- paras = [p.strip() for p in text.split('\n\n') if p.strip()]
14
  return paras
15
 
16
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  def split_content_into_batches(
18
  content: str,
19
  max_words: int = 2000,
20
  batch_size: int = 16,
21
- overlap_words: int = 100 # number of words to overlap between chunk boundaries
22
  ):
23
  """
24
  Splits content by # (level 1), then groups level 2 subsections (##) into chunks with max_words,
25
  overlaps last subsection of previous chunk into next chunk, and batches chunks into batch_size.
26
-
27
- Prints the word count of final chunks and how many chunks were split by each level.
28
-
29
- Returns:
30
- List of batches, each is a list of chunk strings.
31
  """
32
 
33
- level_1_pattern = re.compile(r'^# (.+)', re.MULTILINE)
34
- level_2_pattern = re.compile(r'^## (.+)', re.MULTILINE)
35
 
36
  level_1_indexes = [(m.start(), m.end(), m.group(1)) for m in level_1_pattern.finditer(content)]
37
  ends = [pos[0] for pos in level_1_indexes[1:]] + [len(content)]
@@ -40,13 +233,10 @@ def split_content_into_batches(
40
 
41
  # Counters for debugging
42
  count_level_1_chunks = 0
43
- count_level_2_chunks = 0 # will count grouped chunks here
44
  count_paragraph_chunks = 0
45
 
46
  def get_word_slice(text: str, word_limit: int, from_end=False) -> str:
47
- """
48
- Utility to return first/last `word_limit` words of text.
49
- """
50
  words = text.strip().split()
51
  if from_end:
52
  return " ".join(words[-word_limit:])
@@ -61,93 +251,90 @@ def split_content_into_batches(
61
  section_wc = word_count(section_text)
62
 
63
  if section_wc <= max_words:
64
- # Whole section fits in one chunk, no grouping needed
65
  final_chunk = f"# {heading_text}\n{section_text}"
66
  chunks.append(final_chunk)
67
- print(f"Final chunk word count: {word_count(final_chunk)}")
68
  count_level_1_chunks += 1
69
  continue
70
 
71
- # Get all level 2 subsections within this level 1 section
72
  level_2_indexes = [(m.start(), m.end(), m.group(1)) for m in level_2_pattern.finditer(section_text)]
73
  if not level_2_indexes:
74
- # No subsections, fallback: split by paragraphs
75
  paragraphs = split_paragraphs(section_text)
76
  para_chunks = []
77
  current_chunk = ""
78
  for para in paragraphs:
79
- if word_count(current_chunk) + word_count(para) + 1 <= max_words:
80
- current_chunk += "\n\n" + para if current_chunk else para
 
81
  else:
82
- para_chunks.append(current_chunk)
 
83
  current_chunk = para
84
  if current_chunk:
85
- para_chunks.append(current_chunk)
86
  for pc in para_chunks:
87
  final_chunk = f"# {heading_text}\n{pc}"
88
  chunks.append(final_chunk)
89
- print(f"Final chunk word count: {word_count(final_chunk)}")
90
  count_paragraph_chunks += 1
91
  continue
92
 
93
- # Otherwise, group multiple level 2 subsections until max_words limit reached
94
  level_2_ends = [pos[0] for pos in level_2_indexes[1:]] + [len(section_text)]
95
 
96
- grouped_chunks = []
97
  current_chunk_subsections = []
98
  current_chunk_word_count = 0
99
 
100
  for j, (l2_start, l2_end, l2_heading_text) in enumerate(level_2_indexes):
101
  subsec_start = l2_end
102
  subsec_end = level_2_ends[j]
103
- subsec_text = section_text[subsec_start:subsec_end].strip()
104
- subsec_wc = word_count(subsec_text)
105
-
106
- # Prepare full subsection text (heading + content)
107
- full_subsec_text = f"## {l2_heading_text}\n{subsec_text}"
108
-
109
- # If adding this subsection exceeds limit, yield current chunk and start new chunk
110
- if current_chunk_word_count + subsec_wc > max_words and current_chunk_subsections:
111
- # Form chunk text concatenating all subsections added so far
112
- chunk_text = "\n\n".join(current_chunk_subsections)
113
- # Prepend level 1 heading
114
- chunk_text = f"# {heading_text}\n{chunk_text}"
115
- grouped_chunks.append(chunk_text)
116
- print(f"Final chunk word count: {word_count(chunk_text)}")
117
- count_level_2_chunks += 1
118
-
119
- # Prepare overlap: repeat last subsection (or last part of it) in next chunk
120
- overlap_text = current_chunk_subsections[-1]
121
- overlap_words_text = get_word_slice(overlap_text, overlap_words, from_end=True)
122
- overlap_chunk_text = f"## {l2_heading_text}\n{overlap_words_text}"
123
-
124
- # Start new chunk with overlap
125
- current_chunk_subsections = [overlap_chunk_text]
126
- current_chunk_word_count = word_count(overlap_words_text)
127
-
128
- # Add current subsection fresh after overlap
129
- current_chunk_subsections.append(full_subsec_text)
130
- current_chunk_word_count += subsec_wc
131
 
132
- else:
133
- # Add subsection to current chunk normally
134
- current_chunk_subsections.append(full_subsec_text)
135
- current_chunk_word_count += subsec_wc
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
136
 
137
- # Add the last chunk if any
138
  if current_chunk_subsections:
139
  chunk_text = "\n\n".join(current_chunk_subsections)
140
  chunk_text = f"# {heading_text}\n{chunk_text}"
141
- grouped_chunks.append(chunk_text)
142
- print(f"Final chunk word count: {word_count(chunk_text)}")
143
  count_level_2_chunks += 1
144
 
145
- chunks.extend(grouped_chunks)
 
146
 
147
- batches = [chunks[i:i + batch_size] for i in range(0, len(chunks), batch_size)]
 
 
 
 
 
148
 
149
- print(f"Chunks split by level 1 headings (#): {count_level_1_chunks}")
150
- print(f"Chunks split by grouped level 2 headings (##): {count_level_2_chunks}")
151
- print(f"Chunks split by paragraphs: {count_paragraph_chunks}")
 
152
 
153
  return batches
 
 
 
1
+ # import re
2
+ # from typing import List
3
+
4
+
5
+ # def word_count(text: str) -> int:
6
+ # return len(text.strip().split())
7
+
8
+
9
+ # def split_paragraphs(text: str) -> List[str]:
10
+ # """
11
+ # Split text by double newlines assuming paragraphs separated by blank lines.
12
+ # """
13
+ # paras = [p.strip() for p in text.split('\n\n') if p.strip()]
14
+ # return paras
15
+
16
+
17
+ # def split_content_into_batches(
18
+ # content: str,
19
+ # max_words: int = 2000,
20
+ # batch_size: int = 16,
21
+ # overlap_words: int = 100 # number of words to overlap between chunk boundaries
22
+ # ):
23
+ # """
24
+ # Splits content by # (level 1), then groups level 2 subsections (##) into chunks with max_words,
25
+ # overlaps last subsection of previous chunk into next chunk, and batches chunks into batch_size.
26
+
27
+ # Prints the word count of final chunks and how many chunks were split by each level.
28
+
29
+ # Returns:
30
+ # List of batches, each is a list of chunk strings.
31
+ # """
32
+
33
+ # level_1_pattern = re.compile(r'^# (.+)', re.MULTILINE)
34
+ # level_2_pattern = re.compile(r'^## (.+)', re.MULTILINE)
35
+
36
+ # level_1_indexes = [(m.start(), m.end(), m.group(1)) for m in level_1_pattern.finditer(content)]
37
+ # ends = [pos[0] for pos in level_1_indexes[1:]] + [len(content)]
38
+
39
+ # chunks = []
40
+
41
+ # # Counters for debugging
42
+ # count_level_1_chunks = 0
43
+ # count_level_2_chunks = 0 # will count grouped chunks here
44
+ # count_paragraph_chunks = 0
45
+
46
+ # def get_word_slice(text: str, word_limit: int, from_end=False) -> str:
47
+ # """
48
+ # Utility to return first/last `word_limit` words of text.
49
+ # """
50
+ # words = text.strip().split()
51
+ # if from_end:
52
+ # return " ".join(words[-word_limit:])
53
+ # else:
54
+ # return " ".join(words[:word_limit])
55
+
56
+ # for i, (start, heading_end, heading_text) in enumerate(level_1_indexes):
57
+ # section_start = heading_end
58
+ # section_end = ends[i]
59
+ # section_text = content[section_start:section_end].strip()
60
+
61
+ # section_wc = word_count(section_text)
62
+
63
+ # if section_wc <= max_words:
64
+ # # Whole section fits in one chunk, no grouping needed
65
+ # final_chunk = f"# {heading_text}\n{section_text}"
66
+ # chunks.append(final_chunk)
67
+ # print(f"Final chunk word count: {word_count(final_chunk)}")
68
+ # count_level_1_chunks += 1
69
+ # continue
70
+
71
+ # # Get all level 2 subsections within this level 1 section
72
+ # level_2_indexes = [(m.start(), m.end(), m.group(1)) for m in level_2_pattern.finditer(section_text)]
73
+ # if not level_2_indexes:
74
+ # # No subsections, fallback: split by paragraphs
75
+ # paragraphs = split_paragraphs(section_text)
76
+ # para_chunks = []
77
+ # current_chunk = ""
78
+ # for para in paragraphs:
79
+ # if word_count(current_chunk) + word_count(para) + 1 <= max_words:
80
+ # current_chunk += "\n\n" + para if current_chunk else para
81
+ # else:
82
+ # para_chunks.append(current_chunk)
83
+ # current_chunk = para
84
+ # if current_chunk:
85
+ # para_chunks.append(current_chunk)
86
+ # for pc in para_chunks:
87
+ # final_chunk = f"# {heading_text}\n{pc}"
88
+ # chunks.append(final_chunk)
89
+ # print(f"Final chunk word count: {word_count(final_chunk)}")
90
+ # count_paragraph_chunks += 1
91
+ # continue
92
+
93
+ # # Otherwise, group multiple level 2 subsections until max_words limit reached
94
+ # level_2_ends = [pos[0] for pos in level_2_indexes[1:]] + [len(section_text)]
95
+
96
+ # grouped_chunks = []
97
+ # current_chunk_subsections = []
98
+ # current_chunk_word_count = 0
99
+
100
+ # for j, (l2_start, l2_end, l2_heading_text) in enumerate(level_2_indexes):
101
+ # subsec_start = l2_end
102
+ # subsec_end = level_2_ends[j]
103
+ # subsec_text = section_text[subsec_start:subsec_end].strip()
104
+ # subsec_wc = word_count(subsec_text)
105
+
106
+ # # Prepare full subsection text (heading + content)
107
+ # full_subsec_text = f"## {l2_heading_text}\n{subsec_text}"
108
+
109
+ # # If adding this subsection exceeds limit, yield current chunk and start new chunk
110
+ # if current_chunk_word_count + subsec_wc > max_words and current_chunk_subsections:
111
+ # # Form chunk text concatenating all subsections added so far
112
+ # chunk_text = "\n\n".join(current_chunk_subsections)
113
+ # # Prepend level 1 heading
114
+ # chunk_text = f"# {heading_text}\n{chunk_text}"
115
+ # grouped_chunks.append(chunk_text)
116
+ # print(f"Final chunk word count: {word_count(chunk_text)}")
117
+ # count_level_2_chunks += 1
118
+
119
+ # # Prepare overlap: repeat last subsection (or last part of it) in next chunk
120
+ # overlap_text = current_chunk_subsections[-1]
121
+ # overlap_words_text = get_word_slice(overlap_text, overlap_words, from_end=True)
122
+ # overlap_chunk_text = f"## {l2_heading_text}\n{overlap_words_text}"
123
+
124
+ # # Start new chunk with overlap
125
+ # current_chunk_subsections = [overlap_chunk_text]
126
+ # current_chunk_word_count = word_count(overlap_words_text)
127
+
128
+ # # Add current subsection fresh after overlap
129
+ # current_chunk_subsections.append(full_subsec_text)
130
+ # current_chunk_word_count += subsec_wc
131
+
132
+ # else:
133
+ # # Add subsection to current chunk normally
134
+ # current_chunk_subsections.append(full_subsec_text)
135
+ # current_chunk_word_count += subsec_wc
136
+
137
+ # # Add the last chunk if any
138
+ # if current_chunk_subsections:
139
+ # chunk_text = "\n\n".join(current_chunk_subsections)
140
+ # chunk_text = f"# {heading_text}\n{chunk_text}"
141
+ # grouped_chunks.append(chunk_text)
142
+ # print(f"Final chunk word count: {word_count(chunk_text)}")
143
+ # count_level_2_chunks += 1
144
+
145
+ # chunks.extend(grouped_chunks)
146
+
147
+ # batches = [chunks[i:i + batch_size] for i in range(0, len(chunks), batch_size)]
148
+
149
+ # print(f"Chunks split by level 1 headings (#): {count_level_1_chunks}")
150
+ # print(f"Chunks split by grouped level 2 headings (##): {count_level_2_chunks}")
151
+ # print(f"Chunks split by paragraphs: {count_paragraph_chunks}")
152
+
153
+ # return batches
154
+
155
  import re
156
  from typing import List
157
 
 
164
  """
165
  Split text by double newlines assuming paragraphs separated by blank lines.
166
  """
167
+ paras = [p.strip() for p in text.split("\n\n") if p.strip()]
168
  return paras
169
 
170
 
171
+ def split_to_fit(text: str, max_words: int) -> List[str]:
172
+ """
173
+ Ensure text is broken into chunks each <= max_words by paragraph first, then sliding window.
174
+ """
175
+ words = text.strip().split()
176
+ if len(words) <= max_words:
177
+ return [" ".join(words)]
178
+ # Try paragraph-level
179
+ paras = split_paragraphs(text)
180
+ chunks = []
181
+ current = []
182
+ for para in paras:
183
+ para_words = para.strip().split()
184
+ if sum(len(p.split()) for p in current) + len(para_words) <= max_words:
185
+ current.append(para)
186
+ else:
187
+ if current:
188
+ chunks.append(" ".join(current))
189
+ # if single paragraph too big, fallback to word sliding
190
+ if len(para_words) > max_words:
191
+ step = max_words
192
+ for i in range(0, len(para_words), step):
193
+ part = " ".join(para_words[i : i + max_words])
194
+ chunks.append(part)
195
+ current = []
196
+ else:
197
+ current = [para]
198
+ if current:
199
+ chunks.append(" ".join(current))
200
+ # As a final fallback, split any remaining oversize
201
+ final = []
202
+ for c in chunks:
203
+ if word_count(c) <= max_words:
204
+ final.append(c)
205
+ else:
206
+ wc_words = c.strip().split()
207
+ step = max_words
208
+ for i in range(0, len(wc_words), step):
209
+ final.append(" ".join(wc_words[i : i + max_words]))
210
+ return final
211
+
212
+
213
  def split_content_into_batches(
214
  content: str,
215
  max_words: int = 2000,
216
  batch_size: int = 16,
217
+ overlap_words: int = 200, # number of words to overlap between chunk boundaries
218
  ):
219
  """
220
  Splits content by # (level 1), then groups level 2 subsections (##) into chunks with max_words,
221
  overlaps last subsection of previous chunk into next chunk, and batches chunks into batch_size.
222
+ Enforces strict cap: no chunk exceeds max_words.
223
+ Prints final word count of each chunk.
 
 
 
224
  """
225
 
226
+ level_1_pattern = re.compile(r"^# (.+)", re.MULTILINE)
227
+ level_2_pattern = re.compile(r"^## (.+)", re.MULTILINE)
228
 
229
  level_1_indexes = [(m.start(), m.end(), m.group(1)) for m in level_1_pattern.finditer(content)]
230
  ends = [pos[0] for pos in level_1_indexes[1:]] + [len(content)]
 
233
 
234
  # Counters for debugging
235
  count_level_1_chunks = 0
236
+ count_level_2_chunks = 0
237
  count_paragraph_chunks = 0
238
 
239
  def get_word_slice(text: str, word_limit: int, from_end=False) -> str:
 
 
 
240
  words = text.strip().split()
241
  if from_end:
242
  return " ".join(words[-word_limit:])
 
251
  section_wc = word_count(section_text)
252
 
253
  if section_wc <= max_words:
 
254
  final_chunk = f"# {heading_text}\n{section_text}"
255
  chunks.append(final_chunk)
 
256
  count_level_1_chunks += 1
257
  continue
258
 
 
259
  level_2_indexes = [(m.start(), m.end(), m.group(1)) for m in level_2_pattern.finditer(section_text)]
260
  if not level_2_indexes:
261
+ # Fallback: split by paragraphs, enforcing cap
262
  paragraphs = split_paragraphs(section_text)
263
  para_chunks = []
264
  current_chunk = ""
265
  for para in paragraphs:
266
+ candidate = f"{current_chunk}\n\n{para}" if current_chunk else para
267
+ if word_count(candidate) <= max_words:
268
+ current_chunk = candidate
269
  else:
270
+ if current_chunk:
271
+ para_chunks.extend(split_to_fit(current_chunk, max_words))
272
  current_chunk = para
273
  if current_chunk:
274
+ para_chunks.extend(split_to_fit(current_chunk, max_words))
275
  for pc in para_chunks:
276
  final_chunk = f"# {heading_text}\n{pc}"
277
  chunks.append(final_chunk)
 
278
  count_paragraph_chunks += 1
279
  continue
280
 
 
281
  level_2_ends = [pos[0] for pos in level_2_indexes[1:]] + [len(section_text)]
282
 
 
283
  current_chunk_subsections = []
284
  current_chunk_word_count = 0
285
 
286
  for j, (l2_start, l2_end, l2_heading_text) in enumerate(level_2_indexes):
287
  subsec_start = l2_end
288
  subsec_end = level_2_ends[j]
289
+ raw_subsec_text = section_text[subsec_start:subsec_end].strip()
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
290
 
291
+ # ensure subsections themselves don't violate cap
292
+ subsec_pieces = split_to_fit(raw_subsec_text, max_words)
293
+ for piece in subsec_pieces:
294
+ piece_wc = word_count(piece)
295
+ heading_with_piece = f"## {l2_heading_text}\n{piece}"
296
+
297
+ if current_chunk_word_count + piece_wc > max_words and current_chunk_subsections:
298
+ chunk_text = "\n\n".join(current_chunk_subsections)
299
+ chunk_text = f"# {heading_text}\n{chunk_text}"
300
+ for final_piece in split_to_fit(chunk_text, max_words):
301
+ chunks.append(final_piece)
302
+ count_level_2_chunks += 1
303
+
304
+ # overlap: take last subsection (or piece) and include tail
305
+ overlap_text = current_chunk_subsections[-1]
306
+ overlap_words_text = get_word_slice(overlap_text, overlap_words, from_end=True)
307
+ current_chunk_subsections = [overlap_words_text]
308
+ current_chunk_word_count = word_count(overlap_words_text)
309
+
310
+ current_chunk_subsections.append(heading_with_piece)
311
+ current_chunk_word_count += piece_wc
312
+ else:
313
+ current_chunk_subsections.append(heading_with_piece)
314
+ current_chunk_word_count += piece_wc
315
 
 
316
  if current_chunk_subsections:
317
  chunk_text = "\n\n".join(current_chunk_subsections)
318
  chunk_text = f"# {heading_text}\n{chunk_text}"
319
+ for final_piece in split_to_fit(chunk_text, max_words):
320
+ chunks.append(final_piece)
321
  count_level_2_chunks += 1
322
 
323
+ # Final batching
324
+ batches = [chunks[i : i + batch_size] for i in range(0, len(chunks), batch_size)]
325
 
326
+ # Print final word counts per chunk
327
+ for bi, batch in enumerate(batches, start=1):
328
+ print(f"\nBatch {bi}:")
329
+ for ci, chunk in enumerate(batch, start=1):
330
+ wc = word_count(chunk)
331
+ print(f" Chunk {ci} word count: {wc}")
332
 
333
+ print(f"\nSummary:")
334
+ print(f" Chunks split by level 1 headings (#): {count_level_1_chunks}")
335
+ print(f" Chunks split by grouped level 2 headings (##): {count_level_2_chunks}")
336
+ print(f" Chunks split by paragraphs: {count_paragraph_chunks}")
337
 
338
  return batches
339
+
340
+
clean.py CHANGED
@@ -104,8 +104,10 @@ def process_content(content: str) -> str:
104
  return content_cleaned
105
 
106
  if __name__ == "__main__":
 
107
  input_file = "content.txt"
108
  from chunking import split_content_into_batches
 
109
  # Read content from file
110
  with open(input_file, "r", encoding="utf-8") as f:
111
  original_content = f.read()
@@ -113,16 +115,18 @@ if __name__ == "__main__":
113
  # Convert HTML tables to markdown tables
114
  converted_content = process_content(original_content)
115
  content=split_content_into_batches(converted_content)
116
- print(len(content))
 
 
117
  # Print the converted content (or you could write it to a file if needed)
118
- from openai import AzureOpenAI
119
- from config import azure_open_ai_key, azure_open_ai_url
120
- from embedding_gen import embed_text_batches_azure
121
- client = AzureOpenAI(
122
- api_key=azure_open_ai_key,
123
- azure_endpoint=azure_open_ai_url,
124
- api_version="2023-05-15"
125
- )
126
  import time
127
  from qdrant_setup import batch_upsert_to_qdrant
128
  t1=time.time()
 
104
  return content_cleaned
105
 
106
  if __name__ == "__main__":
107
+ from pprint import pprint
108
  input_file = "content.txt"
109
  from chunking import split_content_into_batches
110
+ from embedding_gen import embed_text_batches_azure
111
  # Read content from file
112
  with open(input_file, "r", encoding="utf-8") as f:
113
  original_content = f.read()
 
115
  # Convert HTML tables to markdown tables
116
  converted_content = process_content(original_content)
117
  content=split_content_into_batches(converted_content)
118
+ # print(content)
119
+ # print(title)
120
+
121
  # Print the converted content (or you could write it to a file if needed)
122
+ # from openai import AzureOpenAI
123
+ # from config import azure_open_ai_key, azure_open_ai_url
124
+ # from embedding_gen import embed_text_batches_azure
125
+ # client = AzureOpenAI(
126
+ # api_key=azure_open_ai_key,
127
+ # azure_endpoint=azure_open_ai_url,
128
+ # api_version="2023-05-15"
129
+ # )
130
  import time
131
  from qdrant_setup import batch_upsert_to_qdrant
132
  t1=time.time()
content.txt ADDED
The diff for this file is too large to render. See raw diff
 
doc_anal.py CHANGED
@@ -115,7 +115,7 @@ if __name__ == "__main__":
115
  import time
116
  t1=time.time()
117
  analysis_results = client.analyze(
118
- source="https://hackrx.blob.core.windows.net/assets/policy.pdf?sv=2023-01-03&st=2025-07-04T09%3A11%3A24Z&se=2027-07-05T09%3A11%3A00Z&sr=b&sp=r&sig=N4a9OU0w0QXO6AOIBiu4bpl7AXvEZogeT%2FjUHNO7HzQ%3D"
119
  )
120
  t2=time.time()
121
  print("analysis_time",t2-t1)
@@ -139,7 +139,7 @@ if __name__ == "__main__":
139
 
140
  # Write the content text to a file
141
  content = analyze_result.get("content", "")
142
- with open("content.txt", "w", encoding="utf-8") as f_content:
143
  f_content.write(content)
144
 
145
  # Write a JSON dump of the tables extracted (if any)
 
115
  import time
116
  t1=time.time()
117
  analysis_results = client.analyze(
118
+ source="https://hackrx.blob.core.windows.net/assets/Arogya%20Sanjeevani%20Policy%20-%20CIN%20-%20U10200WB1906GOI001713%201.pdf?sv=2023-01-03&st=2025-07-21T08%3A29%3A02Z&se=2025-09-22T08%3A29%3A00Z&sr=b&sp=r&sig=nzrz1K9Iurt%2BBXom%2FB%2BMPTFMFP3PRnIvEsipAX10Ig4%3D"
119
  )
120
  t2=time.time()
121
  print("analysis_time",t2-t1)
 
139
 
140
  # Write the content text to a file
141
  content = analyze_result.get("content", "")
142
+ with open("content2.txt", "w", encoding="utf-8") as f_content:
143
  f_content.write(content)
144
 
145
  # Write a JSON dump of the tables extracted (if any)
uv.lock CHANGED
@@ -32,6 +32,7 @@ dependencies = [
32
  { name = "bs4" },
33
  { name = "dotenv" },
34
  { name = "fastapi" },
 
35
  { name = "openai" },
36
  { name = "pydantic" },
37
  { name = "qdrant-client" },
@@ -44,6 +45,7 @@ requires-dist = [
44
  { name = "bs4", specifier = ">=0.0.2" },
45
  { name = "dotenv", specifier = ">=0.9.9" },
46
  { name = "fastapi", specifier = ">=0.116.1" },
 
47
  { name = "openai", specifier = ">=1.97.1" },
48
  { name = "pydantic", specifier = ">=2.11.7" },
49
  { name = "qdrant-client", specifier = ">=1.15.0" },
@@ -85,6 +87,28 @@ wheels = [
85
  { url = "https://files.pythonhosted.org/packages/4f/52/34c6cf5bb9285074dc3531c437b3919e825d976fde097a7a73f79e726d03/certifi-2025.7.14-py3-none-any.whl", hash = "sha256:6b31f564a415d79ee77df69d757bb49a5bb53bd9f756cbbe24394ffd6fc1f4b2", size = 162722, upload-time = "2025-07-14T03:29:26.863Z" },
86
  ]
87
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
88
  [[package]]
89
  name = "charset-normalizer"
90
  version = "3.4.2"
@@ -162,6 +186,30 @@ wheels = [
162
  { url = "https://files.pythonhosted.org/packages/e5/47/d63c60f59a59467fda0f93f46335c9d18526d7071f025cb5b89d5353ea42/fastapi-0.116.1-py3-none-any.whl", hash = "sha256:c46ac7c312df840f0c9e220f7964bada936781bc4e2e6eb71f1c4d7553786565", size = 95631, upload-time = "2025-07-11T16:22:30.485Z" },
163
  ]
164
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
165
  [[package]]
166
  name = "grpcio"
167
  version = "1.74.0"
@@ -298,6 +346,93 @@ wheels = [
298
  { url = "https://files.pythonhosted.org/packages/b3/4a/4175a563579e884192ba6e81725fc0448b042024419be8d83aa8a80a3f44/jiter-0.10.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3aa96f2abba33dc77f79b4cf791840230375f9534e5fac927ccceb58c5e604a5", size = 354213, upload-time = "2025-05-18T19:04:41.894Z" },
299
  ]
300
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
301
  [[package]]
302
  name = "numpy"
303
  version = "2.3.2"
@@ -369,6 +504,49 @@ wheels = [
369
  { url = "https://files.pythonhosted.org/packages/ee/35/412a0e9c3f0d37c94ed764b8ac7adae2d834dbd20e69f6aca582118e0f55/openai-1.97.1-py3-none-any.whl", hash = "sha256:4e96bbdf672ec3d44968c9ea39d2c375891db1acc1794668d8149d5fa6000606", size = 764380, upload-time = "2025-07-22T13:10:10.689Z" },
370
  ]
371
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
372
  [[package]]
373
  name = "portalocker"
374
  version = "3.2.0"
@@ -395,6 +573,15 @@ wheels = [
395
  { url = "https://files.pythonhosted.org/packages/f7/af/ab3c51ab7507a7325e98ffe691d9495ee3d3aa5f589afad65ec920d39821/protobuf-6.31.1-py3-none-any.whl", hash = "sha256:720a6c7e6b77288b85063569baae8536671b39f15cc22037ec7045658d80489e", size = 168724, upload-time = "2025-05-28T19:25:53.926Z" },
396
  ]
397
 
 
 
 
 
 
 
 
 
 
398
  [[package]]
399
  name = "pydantic"
400
  version = "2.11.7"
@@ -460,6 +647,23 @@ wheels = [
460
  { url = "https://files.pythonhosted.org/packages/c0/d2/21af5c535501a7233e734b8af901574572da66fcc254cb35d0609c9080dd/pywin32-311-cp314-cp314-win_arm64.whl", hash = "sha256:a508e2d9025764a8270f93111a970e1d0fbfc33f4153b388bb649b7eec4f9b42", size = 8932540, upload-time = "2025-07-14T20:13:36.379Z" },
461
  ]
462
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
463
  [[package]]
464
  name = "qdrant-client"
465
  version = "1.15.0"
@@ -493,6 +697,18 @@ wheels = [
493
  { url = "https://files.pythonhosted.org/packages/7c/e4/56027c4a6b4ae70ca9de302488c5ca95ad4a39e190093d6c1a8ace08341b/requests-2.32.4-py3-none-any.whl", hash = "sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c", size = 64847, upload-time = "2025-06-09T16:43:05.728Z" },
494
  ]
495
 
 
 
 
 
 
 
 
 
 
 
 
 
496
  [[package]]
497
  name = "sniffio"
498
  version = "1.3.1"
@@ -511,6 +727,27 @@ wheels = [
511
  { url = "https://files.pythonhosted.org/packages/e7/9c/0e6afc12c269578be5c0c1c9f4b49a8d32770a080260c333ac04cc1c832d/soupsieve-2.7-py3-none-any.whl", hash = "sha256:6e60cc5c1ffaf1cebcc12e8188320b72071e922c2e897f737cadce79ad5d30c4", size = 36677, upload-time = "2025-04-20T18:50:07.196Z" },
512
  ]
513
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
514
  [[package]]
515
  name = "starlette"
516
  version = "0.47.2"
@@ -523,6 +760,15 @@ wheels = [
523
  { url = "https://files.pythonhosted.org/packages/f7/1f/b876b1f83aef204198a42dc101613fefccb32258e5428b5f9259677864b4/starlette-0.47.2-py3-none-any.whl", hash = "sha256:c5847e96134e5c5371ee9fac6fdf1a67336d5815e09eb2a01fdb57a351ef915b", size = 72984, upload-time = "2025-07-20T17:31:56.738Z" },
524
  ]
525
 
 
 
 
 
 
 
 
 
 
526
  [[package]]
527
  name = "tqdm"
528
  version = "4.67.1"
@@ -577,3 +823,30 @@ sdist = { url = "https://files.pythonhosted.org/packages/5e/42/e0e305207bb88c6b8
577
  wheels = [
578
  { url = "https://files.pythonhosted.org/packages/d2/e2/dc81b1bd1dcfe91735810265e9d26bc8ec5da45b4c0f6237e286819194c3/uvicorn-0.35.0-py3-none-any.whl", hash = "sha256:197535216b25ff9b785e29a0b79199f55222193d47f820816e7da751e9bc8d4a", size = 66406, upload-time = "2025-06-28T16:15:44.816Z" },
579
  ]
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
32
  { name = "bs4" },
33
  { name = "dotenv" },
34
  { name = "fastapi" },
35
+ { name = "langchain" },
36
  { name = "openai" },
37
  { name = "pydantic" },
38
  { name = "qdrant-client" },
 
45
  { name = "bs4", specifier = ">=0.0.2" },
46
  { name = "dotenv", specifier = ">=0.9.9" },
47
  { name = "fastapi", specifier = ">=0.116.1" },
48
+ { name = "langchain", specifier = ">=0.3.27" },
49
  { name = "openai", specifier = ">=1.97.1" },
50
  { name = "pydantic", specifier = ">=2.11.7" },
51
  { name = "qdrant-client", specifier = ">=1.15.0" },
 
87
  { url = "https://files.pythonhosted.org/packages/4f/52/34c6cf5bb9285074dc3531c437b3919e825d976fde097a7a73f79e726d03/certifi-2025.7.14-py3-none-any.whl", hash = "sha256:6b31f564a415d79ee77df69d757bb49a5bb53bd9f756cbbe24394ffd6fc1f4b2", size = 162722, upload-time = "2025-07-14T03:29:26.863Z" },
88
  ]
89
 
90
+ [[package]]
91
+ name = "cffi"
92
+ version = "1.17.1"
93
+ source = { registry = "https://pypi.org/simple" }
94
+ dependencies = [
95
+ { name = "pycparser" },
96
+ ]
97
+ sdist = { url = "https://files.pythonhosted.org/packages/fc/97/c783634659c2920c3fc70419e3af40972dbaf758daa229a7d6ea6135c90d/cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824", size = 516621, upload-time = "2024-09-04T20:45:21.852Z" }
98
+ wheels = [
99
+ { url = "https://files.pythonhosted.org/packages/8d/f8/dd6c246b148639254dad4d6803eb6a54e8c85c6e11ec9df2cffa87571dbe/cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e", size = 182989, upload-time = "2024-09-04T20:44:28.956Z" },
100
+ { url = "https://files.pythonhosted.org/packages/8b/f1/672d303ddf17c24fc83afd712316fda78dc6fce1cd53011b839483e1ecc8/cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2", size = 178802, upload-time = "2024-09-04T20:44:30.289Z" },
101
+ { url = "https://files.pythonhosted.org/packages/0e/2d/eab2e858a91fdff70533cab61dcff4a1f55ec60425832ddfdc9cd36bc8af/cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3", size = 454792, upload-time = "2024-09-04T20:44:32.01Z" },
102
+ { url = "https://files.pythonhosted.org/packages/75/b2/fbaec7c4455c604e29388d55599b99ebcc250a60050610fadde58932b7ee/cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683", size = 478893, upload-time = "2024-09-04T20:44:33.606Z" },
103
+ { url = "https://files.pythonhosted.org/packages/4f/b7/6e4a2162178bf1935c336d4da8a9352cccab4d3a5d7914065490f08c0690/cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5", size = 485810, upload-time = "2024-09-04T20:44:35.191Z" },
104
+ { url = "https://files.pythonhosted.org/packages/c7/8a/1d0e4a9c26e54746dc08c2c6c037889124d4f59dffd853a659fa545f1b40/cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4", size = 471200, upload-time = "2024-09-04T20:44:36.743Z" },
105
+ { url = "https://files.pythonhosted.org/packages/26/9f/1aab65a6c0db35f43c4d1b4f580e8df53914310afc10ae0397d29d697af4/cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd", size = 479447, upload-time = "2024-09-04T20:44:38.492Z" },
106
+ { url = "https://files.pythonhosted.org/packages/5f/e4/fb8b3dd8dc0e98edf1135ff067ae070bb32ef9d509d6cb0f538cd6f7483f/cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed", size = 484358, upload-time = "2024-09-04T20:44:40.046Z" },
107
+ { url = "https://files.pythonhosted.org/packages/f1/47/d7145bf2dc04684935d57d67dff9d6d795b2ba2796806bb109864be3a151/cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9", size = 488469, upload-time = "2024-09-04T20:44:41.616Z" },
108
+ { url = "https://files.pythonhosted.org/packages/bf/ee/f94057fa6426481d663b88637a9a10e859e492c73d0384514a17d78ee205/cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d", size = 172475, upload-time = "2024-09-04T20:44:43.733Z" },
109
+ { url = "https://files.pythonhosted.org/packages/7c/fc/6a8cb64e5f0324877d503c854da15d76c1e50eb722e320b15345c4d0c6de/cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a", size = 182009, upload-time = "2024-09-04T20:44:45.309Z" },
110
+ ]
111
+
112
  [[package]]
113
  name = "charset-normalizer"
114
  version = "3.4.2"
 
186
  { url = "https://files.pythonhosted.org/packages/e5/47/d63c60f59a59467fda0f93f46335c9d18526d7071f025cb5b89d5353ea42/fastapi-0.116.1-py3-none-any.whl", hash = "sha256:c46ac7c312df840f0c9e220f7964bada936781bc4e2e6eb71f1c4d7553786565", size = 95631, upload-time = "2025-07-11T16:22:30.485Z" },
187
  ]
188
 
189
+ [[package]]
190
+ name = "greenlet"
191
+ version = "3.2.3"
192
+ source = { registry = "https://pypi.org/simple" }
193
+ sdist = { url = "https://files.pythonhosted.org/packages/c9/92/bb85bd6e80148a4d2e0c59f7c0c2891029f8fd510183afc7d8d2feeed9b6/greenlet-3.2.3.tar.gz", hash = "sha256:8b0dd8ae4c0d6f5e54ee55ba935eeb3d735a9b58a8a1e5b5cbab64e01a39f365", size = 185752, upload-time = "2025-06-05T16:16:09.955Z" }
194
+ wheels = [
195
+ { url = "https://files.pythonhosted.org/packages/b1/cf/f5c0b23309070ae93de75c90d29300751a5aacefc0a3ed1b1d8edb28f08b/greenlet-3.2.3-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:500b8689aa9dd1ab26872a34084503aeddefcb438e2e7317b89b11eaea1901ad", size = 270732, upload-time = "2025-06-05T16:10:08.26Z" },
196
+ { url = "https://files.pythonhosted.org/packages/48/ae/91a957ba60482d3fecf9be49bc3948f341d706b52ddb9d83a70d42abd498/greenlet-3.2.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:a07d3472c2a93117af3b0136f246b2833fdc0b542d4a9799ae5f41c28323faef", size = 639033, upload-time = "2025-06-05T16:38:53.983Z" },
197
+ { url = "https://files.pythonhosted.org/packages/6f/df/20ffa66dd5a7a7beffa6451bdb7400d66251374ab40b99981478c69a67a8/greenlet-3.2.3-cp313-cp313-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:8704b3768d2f51150626962f4b9a9e4a17d2e37c8a8d9867bbd9fa4eb938d3b3", size = 652999, upload-time = "2025-06-05T16:41:37.89Z" },
198
+ { url = "https://files.pythonhosted.org/packages/51/b4/ebb2c8cb41e521f1d72bf0465f2f9a2fd803f674a88db228887e6847077e/greenlet-3.2.3-cp313-cp313-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:5035d77a27b7c62db6cf41cf786cfe2242644a7a337a0e155c80960598baab95", size = 647368, upload-time = "2025-06-05T16:48:21.467Z" },
199
+ { url = "https://files.pythonhosted.org/packages/8e/6a/1e1b5aa10dced4ae876a322155705257748108b7fd2e4fae3f2a091fe81a/greenlet-3.2.3-cp313-cp313-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:2d8aa5423cd4a396792f6d4580f88bdc6efcb9205891c9d40d20f6e670992efb", size = 650037, upload-time = "2025-06-05T16:13:06.402Z" },
200
+ { url = "https://files.pythonhosted.org/packages/26/f2/ad51331a157c7015c675702e2d5230c243695c788f8f75feba1af32b3617/greenlet-3.2.3-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2c724620a101f8170065d7dded3f962a2aea7a7dae133a009cada42847e04a7b", size = 608402, upload-time = "2025-06-05T16:12:51.91Z" },
201
+ { url = "https://files.pythonhosted.org/packages/26/bc/862bd2083e6b3aff23300900a956f4ea9a4059de337f5c8734346b9b34fc/greenlet-3.2.3-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:873abe55f134c48e1f2a6f53f7d1419192a3d1a4e873bace00499a4e45ea6af0", size = 1119577, upload-time = "2025-06-05T16:36:49.787Z" },
202
+ { url = "https://files.pythonhosted.org/packages/86/94/1fc0cc068cfde885170e01de40a619b00eaa8f2916bf3541744730ffb4c3/greenlet-3.2.3-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:024571bbce5f2c1cfff08bf3fbaa43bbc7444f580ae13b0099e95d0e6e67ed36", size = 1147121, upload-time = "2025-06-05T16:12:42.527Z" },
203
+ { url = "https://files.pythonhosted.org/packages/27/1a/199f9587e8cb08a0658f9c30f3799244307614148ffe8b1e3aa22f324dea/greenlet-3.2.3-cp313-cp313-win_amd64.whl", hash = "sha256:5195fb1e75e592dd04ce79881c8a22becdfa3e6f500e7feb059b1e6fdd54d3e3", size = 297603, upload-time = "2025-06-05T16:20:12.651Z" },
204
+ { url = "https://files.pythonhosted.org/packages/d8/ca/accd7aa5280eb92b70ed9e8f7fd79dc50a2c21d8c73b9a0856f5b564e222/greenlet-3.2.3-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:3d04332dddb10b4a211b68111dabaee2e1a073663d117dc10247b5b1642bac86", size = 271479, upload-time = "2025-06-05T16:10:47.525Z" },
205
+ { url = "https://files.pythonhosted.org/packages/55/71/01ed9895d9eb49223280ecc98a557585edfa56b3d0e965b9fa9f7f06b6d9/greenlet-3.2.3-cp314-cp314-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:8186162dffde068a465deab08fc72c767196895c39db26ab1c17c0b77a6d8b97", size = 683952, upload-time = "2025-06-05T16:38:55.125Z" },
206
+ { url = "https://files.pythonhosted.org/packages/ea/61/638c4bdf460c3c678a0a1ef4c200f347dff80719597e53b5edb2fb27ab54/greenlet-3.2.3-cp314-cp314-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:f4bfbaa6096b1b7a200024784217defedf46a07c2eee1a498e94a1b5f8ec5728", size = 696917, upload-time = "2025-06-05T16:41:38.959Z" },
207
+ { url = "https://files.pythonhosted.org/packages/22/cc/0bd1a7eb759d1f3e3cc2d1bc0f0b487ad3cc9f34d74da4b80f226fde4ec3/greenlet-3.2.3-cp314-cp314-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:ed6cfa9200484d234d8394c70f5492f144b20d4533f69262d530a1a082f6ee9a", size = 692443, upload-time = "2025-06-05T16:48:23.113Z" },
208
+ { url = "https://files.pythonhosted.org/packages/67/10/b2a4b63d3f08362662e89c103f7fe28894a51ae0bc890fabf37d1d780e52/greenlet-3.2.3-cp314-cp314-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:02b0df6f63cd15012bed5401b47829cfd2e97052dc89da3cfaf2c779124eb892", size = 692995, upload-time = "2025-06-05T16:13:07.972Z" },
209
+ { url = "https://files.pythonhosted.org/packages/5a/c6/ad82f148a4e3ce9564056453a71529732baf5448ad53fc323e37efe34f66/greenlet-3.2.3-cp314-cp314-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:86c2d68e87107c1792e2e8d5399acec2487a4e993ab76c792408e59394d52141", size = 655320, upload-time = "2025-06-05T16:12:53.453Z" },
210
+ { url = "https://files.pythonhosted.org/packages/5c/4f/aab73ecaa6b3086a4c89863d94cf26fa84cbff63f52ce9bc4342b3087a06/greenlet-3.2.3-cp314-cp314-win_amd64.whl", hash = "sha256:8c47aae8fbbfcf82cc13327ae802ba13c9c36753b67e760023fd116bc124a62a", size = 301236, upload-time = "2025-06-05T16:15:20.111Z" },
211
+ ]
212
+
213
  [[package]]
214
  name = "grpcio"
215
  version = "1.74.0"
 
346
  { url = "https://files.pythonhosted.org/packages/b3/4a/4175a563579e884192ba6e81725fc0448b042024419be8d83aa8a80a3f44/jiter-0.10.0-cp314-cp314t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3aa96f2abba33dc77f79b4cf791840230375f9534e5fac927ccceb58c5e604a5", size = 354213, upload-time = "2025-05-18T19:04:41.894Z" },
347
  ]
348
 
349
+ [[package]]
350
+ name = "jsonpatch"
351
+ version = "1.33"
352
+ source = { registry = "https://pypi.org/simple" }
353
+ dependencies = [
354
+ { name = "jsonpointer" },
355
+ ]
356
+ sdist = { url = "https://files.pythonhosted.org/packages/42/78/18813351fe5d63acad16aec57f94ec2b70a09e53ca98145589e185423873/jsonpatch-1.33.tar.gz", hash = "sha256:9fcd4009c41e6d12348b4a0ff2563ba56a2923a7dfee731d004e212e1ee5030c", size = 21699, upload-time = "2023-06-26T12:07:29.144Z" }
357
+ wheels = [
358
+ { url = "https://files.pythonhosted.org/packages/73/07/02e16ed01e04a374e644b575638ec7987ae846d25ad97bcc9945a3ee4b0e/jsonpatch-1.33-py2.py3-none-any.whl", hash = "sha256:0ae28c0cd062bbd8b8ecc26d7d164fbbea9652a1a3693f3b956c1eae5145dade", size = 12898, upload-time = "2023-06-16T21:01:28.466Z" },
359
+ ]
360
+
361
+ [[package]]
362
+ name = "jsonpointer"
363
+ version = "3.0.0"
364
+ source = { registry = "https://pypi.org/simple" }
365
+ sdist = { url = "https://files.pythonhosted.org/packages/6a/0a/eebeb1fa92507ea94016a2a790b93c2ae41a7e18778f85471dc54475ed25/jsonpointer-3.0.0.tar.gz", hash = "sha256:2b2d729f2091522d61c3b31f82e11870f60b68f43fbc705cb76bf4b832af59ef", size = 9114, upload-time = "2024-06-10T19:24:42.462Z" }
366
+ wheels = [
367
+ { url = "https://files.pythonhosted.org/packages/71/92/5e77f98553e9e75130c78900d000368476aed74276eb8ae8796f65f00918/jsonpointer-3.0.0-py2.py3-none-any.whl", hash = "sha256:13e088adc14fca8b6aa8177c044e12701e6ad4b28ff10e65f2267a90109c9942", size = 7595, upload-time = "2024-06-10T19:24:40.698Z" },
368
+ ]
369
+
370
+ [[package]]
371
+ name = "langchain"
372
+ version = "0.3.27"
373
+ source = { registry = "https://pypi.org/simple" }
374
+ dependencies = [
375
+ { name = "langchain-core" },
376
+ { name = "langchain-text-splitters" },
377
+ { name = "langsmith" },
378
+ { name = "pydantic" },
379
+ { name = "pyyaml" },
380
+ { name = "requests" },
381
+ { name = "sqlalchemy" },
382
+ ]
383
+ sdist = { url = "https://files.pythonhosted.org/packages/83/f6/f4f7f3a56626fe07e2bb330feb61254dbdf06c506e6b59a536a337da51cf/langchain-0.3.27.tar.gz", hash = "sha256:aa6f1e6274ff055d0fd36254176770f356ed0a8994297d1df47df341953cec62", size = 10233809, upload-time = "2025-07-24T14:42:32.959Z" }
384
+ wheels = [
385
+ { url = "https://files.pythonhosted.org/packages/f6/d5/4861816a95b2f6993f1360cfb605aacb015506ee2090433a71de9cca8477/langchain-0.3.27-py3-none-any.whl", hash = "sha256:7b20c4f338826acb148d885b20a73a16e410ede9ee4f19bb02011852d5f98798", size = 1018194, upload-time = "2025-07-24T14:42:30.23Z" },
386
+ ]
387
+
388
+ [[package]]
389
+ name = "langchain-core"
390
+ version = "0.3.72"
391
+ source = { registry = "https://pypi.org/simple" }
392
+ dependencies = [
393
+ { name = "jsonpatch" },
394
+ { name = "langsmith" },
395
+ { name = "packaging" },
396
+ { name = "pydantic" },
397
+ { name = "pyyaml" },
398
+ { name = "tenacity" },
399
+ { name = "typing-extensions" },
400
+ ]
401
+ sdist = { url = "https://files.pythonhosted.org/packages/8b/49/7568baeb96a57d3218cb5f1f113b142063679088fd3a0d0cae1feb0b3d36/langchain_core-0.3.72.tar.gz", hash = "sha256:4de3828909b3d7910c313242ab07b241294650f5cb6eac17738dd3638b1cd7de", size = 567227, upload-time = "2025-07-24T00:40:08.5Z" }
402
+ wheels = [
403
+ { url = "https://files.pythonhosted.org/packages/6e/7d/9f75023c478e3b854d67da31d721e39f0eb30ae969ec6e755430cb1c0fb5/langchain_core-0.3.72-py3-none-any.whl", hash = "sha256:9fa15d390600eb6b6544397a7aa84be9564939b6adf7a2b091179ea30405b240", size = 442806, upload-time = "2025-07-24T00:40:06.994Z" },
404
+ ]
405
+
406
+ [[package]]
407
+ name = "langchain-text-splitters"
408
+ version = "0.3.9"
409
+ source = { registry = "https://pypi.org/simple" }
410
+ dependencies = [
411
+ { name = "langchain-core" },
412
+ ]
413
+ sdist = { url = "https://files.pythonhosted.org/packages/91/52/d43ad77acae169210cc476cbc1e4ab37a701017c950211a11ab500fe7d7e/langchain_text_splitters-0.3.9.tar.gz", hash = "sha256:7cd1e5a3aaf609979583eeca2eb34177622570b8fa8f586a605c6b1c34e7ebdb", size = 45260, upload-time = "2025-07-24T14:38:45.14Z" }
414
+ wheels = [
415
+ { url = "https://files.pythonhosted.org/packages/e2/52/7638394b88bc15083fd2c3752a843784d9d2d110d68fed6437c8607fb749/langchain_text_splitters-0.3.9-py3-none-any.whl", hash = "sha256:cee0bb816211584ea79cc79927317c358543f40404bcfdd69e69ba3ccde54401", size = 33314, upload-time = "2025-07-24T14:38:43.953Z" },
416
+ ]
417
+
418
+ [[package]]
419
+ name = "langsmith"
420
+ version = "0.4.8"
421
+ source = { registry = "https://pypi.org/simple" }
422
+ dependencies = [
423
+ { name = "httpx" },
424
+ { name = "orjson", marker = "platform_python_implementation != 'PyPy'" },
425
+ { name = "packaging" },
426
+ { name = "pydantic" },
427
+ { name = "requests" },
428
+ { name = "requests-toolbelt" },
429
+ { name = "zstandard" },
430
+ ]
431
+ sdist = { url = "https://files.pythonhosted.org/packages/46/38/0da897697ce29fb78cdaacae2d0fa3a4bc2a0abf23f84f6ecd1947f79245/langsmith-0.4.8.tar.gz", hash = "sha256:50eccb744473dd6bd3e0fe024786e2196b1f8598f8defffce7ac31113d6c140f", size = 352414, upload-time = "2025-07-18T19:36:06.082Z" }
432
+ wheels = [
433
+ { url = "https://files.pythonhosted.org/packages/19/4f/481324462c44ce21443b833ad73ee51117031d41c16fec06cddbb7495b26/langsmith-0.4.8-py3-none-any.whl", hash = "sha256:ca2f6024ab9d2cd4d091b2e5b58a5d2cb0c354a0c84fe214145a89ad450abae0", size = 367975, upload-time = "2025-07-18T19:36:04.025Z" },
434
+ ]
435
+
436
  [[package]]
437
  name = "numpy"
438
  version = "2.3.2"
 
504
  { url = "https://files.pythonhosted.org/packages/ee/35/412a0e9c3f0d37c94ed764b8ac7adae2d834dbd20e69f6aca582118e0f55/openai-1.97.1-py3-none-any.whl", hash = "sha256:4e96bbdf672ec3d44968c9ea39d2c375891db1acc1794668d8149d5fa6000606", size = 764380, upload-time = "2025-07-22T13:10:10.689Z" },
505
  ]
506
 
507
+ [[package]]
508
+ name = "orjson"
509
+ version = "3.11.1"
510
+ source = { registry = "https://pypi.org/simple" }
511
+ sdist = { url = "https://files.pythonhosted.org/packages/19/3b/fd9ff8ff64ae3900f11554d5cfc835fb73e501e043c420ad32ec574fe27f/orjson-3.11.1.tar.gz", hash = "sha256:48d82770a5fd88778063604c566f9c7c71820270c9cc9338d25147cbf34afd96", size = 5393373, upload-time = "2025-07-25T14:33:52.898Z" }
512
+ wheels = [
513
+ { url = "https://files.pythonhosted.org/packages/c9/e9/880ef869e6f66279ce3a381a32afa0f34e29a94250146911eee029e56efc/orjson-3.11.1-cp313-cp313-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:53cfefe4af059e65aabe9683f76b9c88bf34b4341a77d329227c2424e0e59b0e", size = 240835, upload-time = "2025-07-25T14:32:54.507Z" },
514
+ { url = "https://files.pythonhosted.org/packages/f0/1f/52039ef3d03eeea21763b46bc99ebe11d9de8510c72b7b5569433084a17e/orjson-3.11.1-cp313-cp313-macosx_15_0_arm64.whl", hash = "sha256:93d5abed5a6f9e1b6f9b5bf6ed4423c11932b5447c2f7281d3b64e0f26c6d064", size = 129226, upload-time = "2025-07-25T14:32:55.908Z" },
515
+ { url = "https://files.pythonhosted.org/packages/ee/da/59fdffc9465a760be2cd3764ef9cd5535eec8f095419f972fddb123b6d0e/orjson-3.11.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5dbf06642f3db2966df504944cdd0eb68ca2717f0353bb20b20acd78109374a6", size = 132261, upload-time = "2025-07-25T14:32:57.538Z" },
516
+ { url = "https://files.pythonhosted.org/packages/bb/5c/8610911c7e969db7cf928c8baac4b2f1e68d314bc3057acf5ca64f758435/orjson-3.11.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:dddf4e78747fa7f2188273f84562017a3c4f0824485b78372513c1681ea7a894", size = 128614, upload-time = "2025-07-25T14:32:58.808Z" },
517
+ { url = "https://files.pythonhosted.org/packages/f7/a1/a1db9d4310d014c90f3b7e9b72c6fb162cba82c5f46d0b345669eaebdd3a/orjson-3.11.1-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fa3fe8653c9f57f0e16f008e43626485b6723b84b2f741f54d1258095b655912", size = 130968, upload-time = "2025-07-25T14:33:00.038Z" },
518
+ { url = "https://files.pythonhosted.org/packages/56/ff/11acd1fd7c38ea7a1b5d6bf582ae3da05931bee64620995eb08fd63c77fe/orjson-3.11.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6334d2382aff975a61f6f4d1c3daf39368b887c7de08f7c16c58f485dcf7adb2", size = 132439, upload-time = "2025-07-25T14:33:01.354Z" },
519
+ { url = "https://files.pythonhosted.org/packages/70/f9/bb564dd9450bf8725e034a8ad7f4ae9d4710a34caf63b85ce1c0c6d40af0/orjson-3.11.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a3d0855b643f259ee0cb76fe3df4c04483354409a520a902b067c674842eb6b8", size = 135299, upload-time = "2025-07-25T14:33:03.079Z" },
520
+ { url = "https://files.pythonhosted.org/packages/94/bb/c8eafe6051405e241dda3691db4d9132d3c3462d1d10a17f50837dd130b4/orjson-3.11.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0eacdfeefd0a79987926476eb16e0245546bedeb8febbbbcf4b653e79257a8e4", size = 131004, upload-time = "2025-07-25T14:33:04.416Z" },
521
+ { url = "https://files.pythonhosted.org/packages/a2/40/bed8d7dcf1bd2df8813bf010a25f645863a2f75e8e0ebdb2b55784cf1a62/orjson-3.11.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0ed07faf9e4873518c60480325dcbc16d17c59a165532cccfb409b4cdbaeff24", size = 130583, upload-time = "2025-07-25T14:33:05.768Z" },
522
+ { url = "https://files.pythonhosted.org/packages/57/e7/cfa2eb803ad52d74fbb5424a429b5be164e51d23f1d853e5e037173a5c48/orjson-3.11.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:d6d308dd578ae3658f62bb9eba54801533225823cd3248c902be1ebc79b5e014", size = 404218, upload-time = "2025-07-25T14:33:07.117Z" },
523
+ { url = "https://files.pythonhosted.org/packages/d5/21/bc703af5bc6e9c7e18dcf4404dcc4ec305ab9bb6c82d3aee5952c0c56abf/orjson-3.11.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c4aa13ca959ba6b15c0a98d3d204b850f9dc36c08c9ce422ffb024eb30d6e058", size = 146605, upload-time = "2025-07-25T14:33:08.55Z" },
524
+ { url = "https://files.pythonhosted.org/packages/8f/fe/d26a0150534c4965a06f556aa68bf3c3b82999d5d7b0facd3af7b390c4af/orjson-3.11.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:be3d0653322abc9b68e5bcdaee6cfd58fcbe9973740ab222b87f4d687232ab1f", size = 135434, upload-time = "2025-07-25T14:33:09.967Z" },
525
+ { url = "https://files.pythonhosted.org/packages/89/b6/1cb28365f08cbcffc464f8512320c6eb6db6a653f03d66de47ea3c19385f/orjson-3.11.1-cp313-cp313-win32.whl", hash = "sha256:4dd34e7e2518de8d7834268846f8cab7204364f427c56fb2251e098da86f5092", size = 136596, upload-time = "2025-07-25T14:33:11.333Z" },
526
+ { url = "https://files.pythonhosted.org/packages/f9/35/7870d0d3ed843652676d84d8a6038791113eacc85237b673b925802826b8/orjson-3.11.1-cp313-cp313-win_amd64.whl", hash = "sha256:d6895d32032b6362540e6d0694b19130bb4f2ad04694002dce7d8af588ca5f77", size = 131319, upload-time = "2025-07-25T14:33:12.614Z" },
527
+ { url = "https://files.pythonhosted.org/packages/b7/3e/5bcd50fd865eb664d4edfdaaaff51e333593ceb5695a22c0d0a0d2b187ba/orjson-3.11.1-cp313-cp313-win_arm64.whl", hash = "sha256:bb7c36d5d3570fcbb01d24fa447a21a7fe5a41141fd88e78f7994053cc4e28f4", size = 126613, upload-time = "2025-07-25T14:33:13.927Z" },
528
+ { url = "https://files.pythonhosted.org/packages/61/d8/0a5cd31ed100b4e569e143cb0cddefc21f0bcb8ce284f44bca0bb0e10f3d/orjson-3.11.1-cp314-cp314-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:7b71ef394327b3d0b39f6ea7ade2ecda2731a56c6a7cbf0d6a7301203b92a89b", size = 240819, upload-time = "2025-07-25T14:33:15.223Z" },
529
+ { url = "https://files.pythonhosted.org/packages/b9/95/7eb2c76c92192ceca16bc81845ff100bbb93f568b4b94d914b6a4da47d61/orjson-3.11.1-cp314-cp314-macosx_15_0_arm64.whl", hash = "sha256:77c0fe28ed659b62273995244ae2aa430e432c71f86e4573ab16caa2f2e3ca5e", size = 129218, upload-time = "2025-07-25T14:33:16.637Z" },
530
+ { url = "https://files.pythonhosted.org/packages/da/84/e6b67f301b18adbbc346882f456bea44daebbd032ba725dbd7b741e3a7f1/orjson-3.11.1-cp314-cp314-manylinux_2_34_aarch64.whl", hash = "sha256:1495692f1f1ba2467df429343388a0ed259382835922e124c0cfdd56b3d1f727", size = 132238, upload-time = "2025-07-25T14:33:17.934Z" },
531
+ { url = "https://files.pythonhosted.org/packages/84/78/a45a86e29d9b2f391f9d00b22da51bc4b46b86b788fd42df2c5fcf3e8005/orjson-3.11.1-cp314-cp314-manylinux_2_34_x86_64.whl", hash = "sha256:08c6a762fca63ca4dc04f66c48ea5d2428db55839fec996890e1bfaf057b658c", size = 130998, upload-time = "2025-07-25T14:33:19.282Z" },
532
+ { url = "https://files.pythonhosted.org/packages/ea/8f/6eb3ee6760d93b2ce996a8529164ee1f5bafbdf64b74c7314b68db622b32/orjson-3.11.1-cp314-cp314-musllinux_1_2_aarch64.whl", hash = "sha256:9e26794fe3976810b2c01fda29bd9ac7c91a3c1284b29cc9a383989f7b614037", size = 130559, upload-time = "2025-07-25T14:33:20.589Z" },
533
+ { url = "https://files.pythonhosted.org/packages/1b/78/9572ae94bdba6813917c9387e7834224c011ea6b4530ade07d718fd31598/orjson-3.11.1-cp314-cp314-musllinux_1_2_armv7l.whl", hash = "sha256:4b4b4f8f0b1d3ef8dc73e55363a0ffe012a42f4e2f1a140bf559698dca39b3fa", size = 404231, upload-time = "2025-07-25T14:33:22.019Z" },
534
+ { url = "https://files.pythonhosted.org/packages/1f/a3/68381ad0757e084927c5ee6cfdeab1c6c89405949ee493db557e60871c4c/orjson-3.11.1-cp314-cp314-musllinux_1_2_i686.whl", hash = "sha256:848be553ea35aa89bfefbed2e27c8a41244c862956ab8ba00dc0b27e84fd58de", size = 146658, upload-time = "2025-07-25T14:33:23.675Z" },
535
+ { url = "https://files.pythonhosted.org/packages/00/db/fac56acf77aab778296c3f541a3eec643266f28ecd71d6c0cba251e47655/orjson-3.11.1-cp314-cp314-musllinux_1_2_x86_64.whl", hash = "sha256:c964c29711a4b1df52f8d9966f015402a6cf87753a406c1c4405c407dd66fd45", size = 135443, upload-time = "2025-07-25T14:33:25.04Z" },
536
+ { url = "https://files.pythonhosted.org/packages/76/b1/326fa4b87426197ead61c1eec2eeb3babc9eb33b480ac1f93894e40c8c08/orjson-3.11.1-cp314-cp314-win32.whl", hash = "sha256:33aada2e6b6bc9c540d396528b91e666cedb383740fee6e6a917f561b390ecb1", size = 136643, upload-time = "2025-07-25T14:33:26.449Z" },
537
+ { url = "https://files.pythonhosted.org/packages/0f/8e/2987ae2109f3bfd39680f8a187d1bc09ad7f8fb019dcdc719b08c7242ade/orjson-3.11.1-cp314-cp314-win_amd64.whl", hash = "sha256:68e10fd804e44e36188b9952543e3fa22f5aa8394da1b5283ca2b423735c06e8", size = 131324, upload-time = "2025-07-25T14:33:27.896Z" },
538
+ { url = "https://files.pythonhosted.org/packages/21/5f/253e08e6974752b124fbf3a4de3ad53baa766b0cb4a333d47706d307e396/orjson-3.11.1-cp314-cp314-win_arm64.whl", hash = "sha256:f3cf6c07f8b32127d836be8e1c55d4f34843f7df346536da768e9f73f22078a1", size = 126605, upload-time = "2025-07-25T14:33:29.244Z" },
539
+ ]
540
+
541
+ [[package]]
542
+ name = "packaging"
543
+ version = "25.0"
544
+ source = { registry = "https://pypi.org/simple" }
545
+ sdist = { url = "https://files.pythonhosted.org/packages/a1/d4/1fc4078c65507b51b96ca8f8c3ba19e6a61c8253c72794544580a7b6c24d/packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f", size = 165727, upload-time = "2025-04-19T11:48:59.673Z" }
546
+ wheels = [
547
+ { url = "https://files.pythonhosted.org/packages/20/12/38679034af332785aac8774540895e234f4d07f7545804097de4b666afd8/packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484", size = 66469, upload-time = "2025-04-19T11:48:57.875Z" },
548
+ ]
549
+
550
  [[package]]
551
  name = "portalocker"
552
  version = "3.2.0"
 
573
  { url = "https://files.pythonhosted.org/packages/f7/af/ab3c51ab7507a7325e98ffe691d9495ee3d3aa5f589afad65ec920d39821/protobuf-6.31.1-py3-none-any.whl", hash = "sha256:720a6c7e6b77288b85063569baae8536671b39f15cc22037ec7045658d80489e", size = 168724, upload-time = "2025-05-28T19:25:53.926Z" },
574
  ]
575
 
576
+ [[package]]
577
+ name = "pycparser"
578
+ version = "2.22"
579
+ source = { registry = "https://pypi.org/simple" }
580
+ sdist = { url = "https://files.pythonhosted.org/packages/1d/b2/31537cf4b1ca988837256c910a668b553fceb8f069bedc4b1c826024b52c/pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6", size = 172736, upload-time = "2024-03-30T13:22:22.564Z" }
581
+ wheels = [
582
+ { url = "https://files.pythonhosted.org/packages/13/a3/a812df4e2dd5696d1f351d58b8fe16a405b234ad2886a0dab9183fb78109/pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc", size = 117552, upload-time = "2024-03-30T13:22:20.476Z" },
583
+ ]
584
+
585
  [[package]]
586
  name = "pydantic"
587
  version = "2.11.7"
 
647
  { url = "https://files.pythonhosted.org/packages/c0/d2/21af5c535501a7233e734b8af901574572da66fcc254cb35d0609c9080dd/pywin32-311-cp314-cp314-win_arm64.whl", hash = "sha256:a508e2d9025764a8270f93111a970e1d0fbfc33f4153b388bb649b7eec4f9b42", size = 8932540, upload-time = "2025-07-14T20:13:36.379Z" },
648
  ]
649
 
650
+ [[package]]
651
+ name = "pyyaml"
652
+ version = "6.0.2"
653
+ source = { registry = "https://pypi.org/simple" }
654
+ sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631, upload-time = "2024-08-06T20:33:50.674Z" }
655
+ wheels = [
656
+ { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309, upload-time = "2024-08-06T20:32:43.4Z" },
657
+ { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679, upload-time = "2024-08-06T20:32:44.801Z" },
658
+ { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428, upload-time = "2024-08-06T20:32:46.432Z" },
659
+ { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361, upload-time = "2024-08-06T20:32:51.188Z" },
660
+ { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523, upload-time = "2024-08-06T20:32:53.019Z" },
661
+ { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660, upload-time = "2024-08-06T20:32:54.708Z" },
662
+ { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597, upload-time = "2024-08-06T20:32:56.985Z" },
663
+ { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527, upload-time = "2024-08-06T20:33:03.001Z" },
664
+ { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload-time = "2024-08-06T20:33:04.33Z" },
665
+ ]
666
+
667
  [[package]]
668
  name = "qdrant-client"
669
  version = "1.15.0"
 
697
  { url = "https://files.pythonhosted.org/packages/7c/e4/56027c4a6b4ae70ca9de302488c5ca95ad4a39e190093d6c1a8ace08341b/requests-2.32.4-py3-none-any.whl", hash = "sha256:27babd3cda2a6d50b30443204ee89830707d396671944c998b5975b031ac2b2c", size = 64847, upload-time = "2025-06-09T16:43:05.728Z" },
698
  ]
699
 
700
+ [[package]]
701
+ name = "requests-toolbelt"
702
+ version = "1.0.0"
703
+ source = { registry = "https://pypi.org/simple" }
704
+ dependencies = [
705
+ { name = "requests" },
706
+ ]
707
+ sdist = { url = "https://files.pythonhosted.org/packages/f3/61/d7545dafb7ac2230c70d38d31cbfe4cc64f7144dc41f6e4e4b78ecd9f5bb/requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6", size = 206888, upload-time = "2023-05-01T04:11:33.229Z" }
708
+ wheels = [
709
+ { url = "https://files.pythonhosted.org/packages/3f/51/d4db610ef29373b879047326cbf6fa98b6c1969d6f6dc423279de2b1be2c/requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06", size = 54481, upload-time = "2023-05-01T04:11:28.427Z" },
710
+ ]
711
+
712
  [[package]]
713
  name = "sniffio"
714
  version = "1.3.1"
 
727
  { url = "https://files.pythonhosted.org/packages/e7/9c/0e6afc12c269578be5c0c1c9f4b49a8d32770a080260c333ac04cc1c832d/soupsieve-2.7-py3-none-any.whl", hash = "sha256:6e60cc5c1ffaf1cebcc12e8188320b72071e922c2e897f737cadce79ad5d30c4", size = 36677, upload-time = "2025-04-20T18:50:07.196Z" },
728
  ]
729
 
730
+ [[package]]
731
+ name = "sqlalchemy"
732
+ version = "2.0.42"
733
+ source = { registry = "https://pypi.org/simple" }
734
+ dependencies = [
735
+ { name = "greenlet", marker = "(python_full_version < '3.14' and platform_machine == 'AMD64') or (python_full_version < '3.14' and platform_machine == 'WIN32') or (python_full_version < '3.14' and platform_machine == 'aarch64') or (python_full_version < '3.14' and platform_machine == 'amd64') or (python_full_version < '3.14' and platform_machine == 'ppc64le') or (python_full_version < '3.14' and platform_machine == 'win32') or (python_full_version < '3.14' and platform_machine == 'x86_64')" },
736
+ { name = "typing-extensions" },
737
+ ]
738
+ sdist = { url = "https://files.pythonhosted.org/packages/5a/03/a0af991e3a43174d6b83fca4fb399745abceddd1171bdabae48ce877ff47/sqlalchemy-2.0.42.tar.gz", hash = "sha256:160bedd8a5c28765bd5be4dec2d881e109e33b34922e50a3b881a7681773ac5f", size = 9749972, upload-time = "2025-07-29T12:48:09.323Z" }
739
+ wheels = [
740
+ { url = "https://files.pythonhosted.org/packages/e9/7e/25d8c28b86730c9fb0e09156f601d7a96d1c634043bf8ba36513eb78887b/sqlalchemy-2.0.42-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:941804f55c7d507334da38133268e3f6e5b0340d584ba0f277dd884197f4ae8c", size = 2127905, upload-time = "2025-07-29T13:29:22.249Z" },
741
+ { url = "https://files.pythonhosted.org/packages/e5/a1/9d8c93434d1d983880d976400fcb7895a79576bd94dca61c3b7b90b1ed0d/sqlalchemy-2.0.42-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:95d3d06a968a760ce2aa6a5889fefcbdd53ca935735e0768e1db046ec08cbf01", size = 2115726, upload-time = "2025-07-29T13:29:23.496Z" },
742
+ { url = "https://files.pythonhosted.org/packages/a2/cc/d33646fcc24c87cc4e30a03556b611a4e7bcfa69a4c935bffb923e3c89f4/sqlalchemy-2.0.42-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4cf10396a8a700a0f38ccd220d940be529c8f64435c5d5b29375acab9267a6c9", size = 3246007, upload-time = "2025-07-29T13:26:44.166Z" },
743
+ { url = "https://files.pythonhosted.org/packages/67/08/4e6c533d4c7f5e7c4cbb6fe8a2c4e813202a40f05700d4009a44ec6e236d/sqlalchemy-2.0.42-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9cae6c2b05326d7c2c7c0519f323f90e0fb9e8afa783c6a05bb9ee92a90d0f04", size = 3250919, upload-time = "2025-07-29T13:22:33.74Z" },
744
+ { url = "https://files.pythonhosted.org/packages/5c/82/f680e9a636d217aece1b9a8030d18ad2b59b5e216e0c94e03ad86b344af3/sqlalchemy-2.0.42-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:f50f7b20677b23cfb35b6afcd8372b2feb348a38e3033f6447ee0704540be894", size = 3180546, upload-time = "2025-07-29T13:26:45.648Z" },
745
+ { url = "https://files.pythonhosted.org/packages/7d/a2/8c8f6325f153894afa3775584c429cc936353fb1db26eddb60a549d0ff4b/sqlalchemy-2.0.42-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:9d88a1c0d66d24e229e3938e1ef16ebdbd2bf4ced93af6eff55225f7465cf350", size = 3216683, upload-time = "2025-07-29T13:22:34.977Z" },
746
+ { url = "https://files.pythonhosted.org/packages/39/44/3a451d7fa4482a8ffdf364e803ddc2cfcafc1c4635fb366f169ecc2c3b11/sqlalchemy-2.0.42-cp313-cp313-win32.whl", hash = "sha256:45c842c94c9ad546c72225a0c0d1ae8ef3f7c212484be3d429715a062970e87f", size = 2093990, upload-time = "2025-07-29T13:16:13.036Z" },
747
+ { url = "https://files.pythonhosted.org/packages/4b/9e/9bce34f67aea0251c8ac104f7bdb2229d58fb2e86a4ad8807999c4bee34b/sqlalchemy-2.0.42-cp313-cp313-win_amd64.whl", hash = "sha256:eb9905f7f1e49fd57a7ed6269bc567fcbbdac9feadff20ad6bd7707266a91577", size = 2120473, upload-time = "2025-07-29T13:16:14.502Z" },
748
+ { url = "https://files.pythonhosted.org/packages/ee/55/ba2546ab09a6adebc521bf3974440dc1d8c06ed342cceb30ed62a8858835/sqlalchemy-2.0.42-py3-none-any.whl", hash = "sha256:defcdff7e661f0043daa381832af65d616e060ddb54d3fe4476f51df7eaa1835", size = 1922072, upload-time = "2025-07-29T13:09:17.061Z" },
749
+ ]
750
+
751
  [[package]]
752
  name = "starlette"
753
  version = "0.47.2"
 
760
  { url = "https://files.pythonhosted.org/packages/f7/1f/b876b1f83aef204198a42dc101613fefccb32258e5428b5f9259677864b4/starlette-0.47.2-py3-none-any.whl", hash = "sha256:c5847e96134e5c5371ee9fac6fdf1a67336d5815e09eb2a01fdb57a351ef915b", size = 72984, upload-time = "2025-07-20T17:31:56.738Z" },
761
  ]
762
 
763
+ [[package]]
764
+ name = "tenacity"
765
+ version = "9.1.2"
766
+ source = { registry = "https://pypi.org/simple" }
767
+ sdist = { url = "https://files.pythonhosted.org/packages/0a/d4/2b0cd0fe285e14b36db076e78c93766ff1d529d70408bd1d2a5a84f1d929/tenacity-9.1.2.tar.gz", hash = "sha256:1169d376c297e7de388d18b4481760d478b0e99a777cad3a9c86e556f4b697cb", size = 48036, upload-time = "2025-04-02T08:25:09.966Z" }
768
+ wheels = [
769
+ { url = "https://files.pythonhosted.org/packages/e5/30/643397144bfbfec6f6ef821f36f33e57d35946c44a2352d3c9f0ae847619/tenacity-9.1.2-py3-none-any.whl", hash = "sha256:f77bf36710d8b73a50b2dd155c97b870017ad21afe6ab300326b0371b3b05138", size = 28248, upload-time = "2025-04-02T08:25:07.678Z" },
770
+ ]
771
+
772
  [[package]]
773
  name = "tqdm"
774
  version = "4.67.1"
 
823
  wheels = [
824
  { url = "https://files.pythonhosted.org/packages/d2/e2/dc81b1bd1dcfe91735810265e9d26bc8ec5da45b4c0f6237e286819194c3/uvicorn-0.35.0-py3-none-any.whl", hash = "sha256:197535216b25ff9b785e29a0b79199f55222193d47f820816e7da751e9bc8d4a", size = 66406, upload-time = "2025-06-28T16:15:44.816Z" },
825
  ]
826
+
827
+ [[package]]
828
+ name = "zstandard"
829
+ version = "0.23.0"
830
+ source = { registry = "https://pypi.org/simple" }
831
+ dependencies = [
832
+ { name = "cffi", marker = "platform_python_implementation == 'PyPy'" },
833
+ ]
834
+ sdist = { url = "https://files.pythonhosted.org/packages/ed/f6/2ac0287b442160a89d726b17a9184a4c615bb5237db763791a7fd16d9df1/zstandard-0.23.0.tar.gz", hash = "sha256:b2d8c62d08e7255f68f7a740bae85b3c9b8e5466baa9cbf7f57f1cde0ac6bc09", size = 681701, upload-time = "2024-07-15T00:18:06.141Z" }
835
+ wheels = [
836
+ { url = "https://files.pythonhosted.org/packages/80/f1/8386f3f7c10261fe85fbc2c012fdb3d4db793b921c9abcc995d8da1b7a80/zstandard-0.23.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:576856e8594e6649aee06ddbfc738fec6a834f7c85bf7cadd1c53d4a58186ef9", size = 788975, upload-time = "2024-07-15T00:16:16.005Z" },
837
+ { url = "https://files.pythonhosted.org/packages/16/e8/cbf01077550b3e5dc86089035ff8f6fbbb312bc0983757c2d1117ebba242/zstandard-0.23.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:38302b78a850ff82656beaddeb0bb989a0322a8bbb1bf1ab10c17506681d772a", size = 633448, upload-time = "2024-07-15T00:16:17.897Z" },
838
+ { url = "https://files.pythonhosted.org/packages/06/27/4a1b4c267c29a464a161aeb2589aff212b4db653a1d96bffe3598f3f0d22/zstandard-0.23.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2240ddc86b74966c34554c49d00eaafa8200a18d3a5b6ffbf7da63b11d74ee2", size = 4945269, upload-time = "2024-07-15T00:16:20.136Z" },
839
+ { url = "https://files.pythonhosted.org/packages/7c/64/d99261cc57afd9ae65b707e38045ed8269fbdae73544fd2e4a4d50d0ed83/zstandard-0.23.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2ef230a8fd217a2015bc91b74f6b3b7d6522ba48be29ad4ea0ca3a3775bf7dd5", size = 5306228, upload-time = "2024-07-15T00:16:23.398Z" },
840
+ { url = "https://files.pythonhosted.org/packages/7a/cf/27b74c6f22541f0263016a0fd6369b1b7818941de639215c84e4e94b2a1c/zstandard-0.23.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:774d45b1fac1461f48698a9d4b5fa19a69d47ece02fa469825b442263f04021f", size = 5336891, upload-time = "2024-07-15T00:16:26.391Z" },
841
+ { url = "https://files.pythonhosted.org/packages/fa/18/89ac62eac46b69948bf35fcd90d37103f38722968e2981f752d69081ec4d/zstandard-0.23.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6f77fa49079891a4aab203d0b1744acc85577ed16d767b52fc089d83faf8d8ed", size = 5436310, upload-time = "2024-07-15T00:16:29.018Z" },
842
+ { url = "https://files.pythonhosted.org/packages/a8/a8/5ca5328ee568a873f5118d5b5f70d1f36c6387716efe2e369010289a5738/zstandard-0.23.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ac184f87ff521f4840e6ea0b10c0ec90c6b1dcd0bad2f1e4a9a1b4fa177982ea", size = 4859912, upload-time = "2024-07-15T00:16:31.871Z" },
843
+ { url = "https://files.pythonhosted.org/packages/ea/ca/3781059c95fd0868658b1cf0440edd832b942f84ae60685d0cfdb808bca1/zstandard-0.23.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:c363b53e257246a954ebc7c488304b5592b9c53fbe74d03bc1c64dda153fb847", size = 4936946, upload-time = "2024-07-15T00:16:34.593Z" },
844
+ { url = "https://files.pythonhosted.org/packages/ce/11/41a58986f809532742c2b832c53b74ba0e0a5dae7e8ab4642bf5876f35de/zstandard-0.23.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:e7792606d606c8df5277c32ccb58f29b9b8603bf83b48639b7aedf6df4fe8171", size = 5466994, upload-time = "2024-07-15T00:16:36.887Z" },
845
+ { url = "https://files.pythonhosted.org/packages/83/e3/97d84fe95edd38d7053af05159465d298c8b20cebe9ccb3d26783faa9094/zstandard-0.23.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a0817825b900fcd43ac5d05b8b3079937073d2b1ff9cf89427590718b70dd840", size = 4848681, upload-time = "2024-07-15T00:16:39.709Z" },
846
+ { url = "https://files.pythonhosted.org/packages/6e/99/cb1e63e931de15c88af26085e3f2d9af9ce53ccafac73b6e48418fd5a6e6/zstandard-0.23.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:9da6bc32faac9a293ddfdcb9108d4b20416219461e4ec64dfea8383cac186690", size = 4694239, upload-time = "2024-07-15T00:16:41.83Z" },
847
+ { url = "https://files.pythonhosted.org/packages/ab/50/b1e703016eebbc6501fc92f34db7b1c68e54e567ef39e6e59cf5fb6f2ec0/zstandard-0.23.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:fd7699e8fd9969f455ef2926221e0233f81a2542921471382e77a9e2f2b57f4b", size = 5200149, upload-time = "2024-07-15T00:16:44.287Z" },
848
+ { url = "https://files.pythonhosted.org/packages/aa/e0/932388630aaba70197c78bdb10cce2c91fae01a7e553b76ce85471aec690/zstandard-0.23.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d477ed829077cd945b01fc3115edd132c47e6540ddcd96ca169facff28173057", size = 5655392, upload-time = "2024-07-15T00:16:46.423Z" },
849
+ { url = "https://files.pythonhosted.org/packages/02/90/2633473864f67a15526324b007a9f96c96f56d5f32ef2a56cc12f9548723/zstandard-0.23.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa6ce8b52c5987b3e34d5674b0ab529a4602b632ebab0a93b07bfb4dfc8f8a33", size = 5191299, upload-time = "2024-07-15T00:16:49.053Z" },
850
+ { url = "https://files.pythonhosted.org/packages/b0/4c/315ca5c32da7e2dc3455f3b2caee5c8c2246074a61aac6ec3378a97b7136/zstandard-0.23.0-cp313-cp313-win32.whl", hash = "sha256:a9b07268d0c3ca5c170a385a0ab9fb7fdd9f5fd866be004c4ea39e44edce47dd", size = 430862, upload-time = "2024-07-15T00:16:51.003Z" },
851
+ { url = "https://files.pythonhosted.org/packages/a2/bf/c6aaba098e2d04781e8f4f7c0ba3c7aa73d00e4c436bcc0cf059a66691d1/zstandard-0.23.0-cp313-cp313-win_amd64.whl", hash = "sha256:f3513916e8c645d0610815c257cbfd3242adfd5c4cfa78be514e5a3ebb42a41b", size = 495578, upload-time = "2024-07-15T00:16:53.135Z" },
852
+ ]