Maia Pelletier commited on
Commit
588cdee
·
1 Parent(s): 3f60e32

add links for PDFs

Browse files
app.py CHANGED
@@ -262,17 +262,20 @@ Answer:"""
262
  )
263
  if meta.get("type") == "url" and meta.get("source"):
264
  context_index_to_url[i] = meta["source"]
 
 
265
 
266
  # Generate response using chat/comversational API (Mistral instruct uses this)
267
  try:
268
  response_text = self._generate_with_chat(prompt, max_new_tokens=512)
269
  if response_text:
270
  # Resolve [Context N] to actual source labels in the body
271
- # First, expand grouped "Context N, M" forms (without brackets) to individual [Context N] tags
 
272
  def _expand_grouped_context(m):
273
  indices = [int(x.strip()) for x in re.split(r'[,\s]+', m.group(1)) if x.strip().isdigit()]
274
  return " ".join(f"[Context {idx}]" for idx in indices)
275
- response_text = re.sub(r'\bContext\s+([\d][,\s\d]*)', _expand_grouped_context, response_text)
276
  # Now replace all [Context N] with source labels/links
277
  for i, source_label in context_index_to_source.items():
278
  url = context_index_to_url.get(i)
 
262
  )
263
  if meta.get("type") == "url" and meta.get("source"):
264
  context_index_to_url[i] = meta["source"]
265
+ elif meta.get("url"):
266
+ context_index_to_url[i] = meta["url"]
267
 
268
  # Generate response using chat/comversational API (Mistral instruct uses this)
269
  try:
270
  response_text = self._generate_with_chat(prompt, max_new_tokens=512)
271
  if response_text:
272
  # Resolve [Context N] to actual source labels in the body
273
+ # Expand bare/grouped "Context N, M" forms to individual [Context N] tags.
274
+ # Use negative lookbehind (?<!\[) so already-bracketed [Context N] are not double-wrapped.
275
  def _expand_grouped_context(m):
276
  indices = [int(x.strip()) for x in re.split(r'[,\s]+', m.group(1)) if x.strip().isdigit()]
277
  return " ".join(f"[Context {idx}]" for idx in indices)
278
+ response_text = re.sub(r'(?<!\[)\bContext\s+([\d][,\s\d]*)', _expand_grouped_context, response_text)
279
  # Now replace all [Context N] with source labels/links
280
  for i, source_label in context_index_to_source.items():
281
  url = context_index_to_url.get(i)
data/vector_store/documents.pkl CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:91f5564b211362f8521a1f7941a4f346d97d46dfba2e83d8ca58cb81a77df864
3
- size 874711
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:0ba58f4cd0cf25aec81a1c328e116e6276dd5648819412e80a9d9cbf9e9a109a
3
+ size 879299
data/vector_store/embeddings.pkl CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:a043f7bc5e7b5f5a2880cc6d5389fb277f9529eac26612880828b241970d2b9f
3
  size 4390028
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:d6ad8b4a984849be946ed42dc015bc669d4882712e89318f72ea65e4fbc1d79a
3
  size 4390028
data/vector_store/index.faiss CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:73c8f7fdb095c972962c80cc05f36a80bec95d374736c8e762f165621185d9f8
3
  size 4389933
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:06988afb211c9b69be9e929e45c1b13dbf48cb0b9549b30b24e9f15d78aadcbb
3
  size 4389933
ingest_documents.py CHANGED
@@ -17,6 +17,13 @@ URLS = [
17
  "https://cog.ca/faqs/"
18
  ]
19
 
 
 
 
 
 
 
 
20
 
21
  def main():
22
  """Main ingestion function."""
@@ -61,7 +68,7 @@ def main():
61
  print("=" * 60)
62
 
63
  try:
64
- documents = ingestion.process_documents(pdf_paths=pdf_paths, urls=urls)
65
  print(f"\n[SUCCESS] Successfully processed {len(documents)} document chunks")
66
 
67
  # Build vector store
 
17
  "https://cog.ca/faqs/"
18
  ]
19
 
20
+ # Optional: map PDF filenames to their publicly hosted URLs so references are hyperlinked.
21
+ # Keys are bare filenames (no path), values are the public URL for that PDF.
22
+ PDF_URLS = {
23
+ "Organic production systems - General principles and management standards.pdf": "https://publications.gc.ca/collections/collection_2026/ongc-cgsb/P29-32-310-2026-eng.pdf",
24
+ # "another-doc.pdf": "https://example.com/another-doc.pdf",
25
+ }
26
+
27
 
28
  def main():
29
  """Main ingestion function."""
 
68
  print("=" * 60)
69
 
70
  try:
71
+ documents = ingestion.process_documents(pdf_paths=pdf_paths, urls=urls, pdf_urls=PDF_URLS)
72
  print(f"\n[SUCCESS] Successfully processed {len(documents)} document chunks")
73
 
74
  # Build vector store
ingestion.py CHANGED
@@ -115,20 +115,22 @@ class DocumentIngestion:
115
  except Exception as e:
116
  raise Exception(f"Error reading URL {url}: {str(e)}")
117
 
118
- def process_documents(self, pdf_paths: List[str] = None, urls: List[str] = None) -> List[Dict]:
119
  """
120
  Process PDFs and URLs into chunks.
121
-
122
  Args:
123
  pdf_paths: List of PDF file paths
124
  urls: List of URLs to process
125
-
 
126
  Returns:
127
  List of document chunks with metadata
128
  """
129
  all_texts = []
130
  all_metadata = []
131
-
 
132
  # Process PDFs
133
  if pdf_paths:
134
  for pdf_path in pdf_paths:
@@ -138,14 +140,19 @@ class DocumentIngestion:
138
  document_title = self.get_pdf_document_title(pdf_path)
139
  text = self.read_pdf(pdf_path)
140
  chunks = self.text_splitter.split_text(text)
 
 
141
  for i, chunk in enumerate(chunks):
142
  all_texts.append(chunk)
143
- all_metadata.append({
144
  'source': pdf_path,
145
  'document_title': document_title,
146
  'type': 'pdf',
147
  'chunk_index': i
148
- })
 
 
 
149
 
150
  # Process URLs
151
  if urls:
 
115
  except Exception as e:
116
  raise Exception(f"Error reading URL {url}: {str(e)}")
117
 
118
+ def process_documents(self, pdf_paths: List[str] = None, urls: List[str] = None, pdf_urls: Dict[str, str] = None) -> List[Dict]:
119
  """
120
  Process PDFs and URLs into chunks.
121
+
122
  Args:
123
  pdf_paths: List of PDF file paths
124
  urls: List of URLs to process
125
+ pdf_urls: Optional dict mapping PDF filenames to their public URLs (for hyperlinking references)
126
+
127
  Returns:
128
  List of document chunks with metadata
129
  """
130
  all_texts = []
131
  all_metadata = []
132
+ pdf_urls = pdf_urls or {}
133
+
134
  # Process PDFs
135
  if pdf_paths:
136
  for pdf_path in pdf_paths:
 
140
  document_title = self.get_pdf_document_title(pdf_path)
141
  text = self.read_pdf(pdf_path)
142
  chunks = self.text_splitter.split_text(text)
143
+ filename = os.path.basename(pdf_path)
144
+ public_url = pdf_urls.get(filename)
145
  for i, chunk in enumerate(chunks):
146
  all_texts.append(chunk)
147
+ meta = {
148
  'source': pdf_path,
149
  'document_title': document_title,
150
  'type': 'pdf',
151
  'chunk_index': i
152
+ }
153
+ if public_url:
154
+ meta['url'] = public_url
155
+ all_metadata.append(meta)
156
 
157
  # Process URLs
158
  if urls: