sharepoint-knowledge 0.2.2__tar.gz → 0.2.3__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (21) hide show
  1. {sharepoint_knowledge-0.2.2 → sharepoint_knowledge-0.2.3}/PKG-INFO +2 -2
  2. {sharepoint_knowledge-0.2.2 → sharepoint_knowledge-0.2.3}/pyproject.toml +2 -2
  3. {sharepoint_knowledge-0.2.2 → sharepoint_knowledge-0.2.3}/src/sharepoint_knowledge/crawl_sp.py +11 -1
  4. {sharepoint_knowledge-0.2.2 → sharepoint_knowledge-0.2.3}/src/sharepoint_knowledge/server_sp.py +12 -7
  5. {sharepoint_knowledge-0.2.2 → sharepoint_knowledge-0.2.3}/src/sharepoint_knowledge.egg-info/PKG-INFO +2 -2
  6. {sharepoint_knowledge-0.2.2 → sharepoint_knowledge-0.2.3}/src/sharepoint_knowledge.egg-info/requires.txt +1 -1
  7. {sharepoint_knowledge-0.2.2 → sharepoint_knowledge-0.2.3}/README.md +0 -0
  8. {sharepoint_knowledge-0.2.2 → sharepoint_knowledge-0.2.3}/setup.cfg +0 -0
  9. {sharepoint_knowledge-0.2.2 → sharepoint_knowledge-0.2.3}/src/sharepoint_knowledge/__init__.py +0 -0
  10. {sharepoint_knowledge-0.2.2 → sharepoint_knowledge-0.2.3}/src/sharepoint_knowledge/auth_sp.py +0 -0
  11. {sharepoint_knowledge-0.2.2 → sharepoint_knowledge-0.2.3}/src/sharepoint_knowledge/cli_sp.py +0 -0
  12. {sharepoint_knowledge-0.2.2 → sharepoint_knowledge-0.2.3}/src/sharepoint_knowledge/client_sp.py +0 -0
  13. {sharepoint_knowledge-0.2.2 → sharepoint_knowledge-0.2.3}/src/sharepoint_knowledge/settings_sp.py +0 -0
  14. {sharepoint_knowledge-0.2.2 → sharepoint_knowledge-0.2.3}/src/sharepoint_knowledge.egg-info/SOURCES.txt +0 -0
  15. {sharepoint_knowledge-0.2.2 → sharepoint_knowledge-0.2.3}/src/sharepoint_knowledge.egg-info/dependency_links.txt +0 -0
  16. {sharepoint_knowledge-0.2.2 → sharepoint_knowledge-0.2.3}/src/sharepoint_knowledge.egg-info/entry_points.txt +0 -0
  17. {sharepoint_knowledge-0.2.2 → sharepoint_knowledge-0.2.3}/src/sharepoint_knowledge.egg-info/top_level.txt +0 -0
  18. {sharepoint_knowledge-0.2.2 → sharepoint_knowledge-0.2.3}/tests/test_agent_doc_consistency.py +0 -0
  19. {sharepoint_knowledge-0.2.2 → sharepoint_knowledge-0.2.3}/tests/test_client_sp.py +0 -0
  20. {sharepoint_knowledge-0.2.2 → sharepoint_knowledge-0.2.3}/tests/test_crawl_sp.py +0 -0
  21. {sharepoint_knowledge-0.2.2 → sharepoint_knowledge-0.2.3}/tests/test_server_flow_sp.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sharepoint-knowledge
3
- Version: 0.2.2
3
+ Version: 0.2.3
4
4
  Summary: SharePoint connector for the grounded-Q&A engine — site pages + document libraries, Entra device-code sign-in, local models, cited answers
5
5
  License: Apache-2.0
6
6
  Project-URL: Homepage, https://github.com/nkunal1992/agents
@@ -11,7 +11,7 @@ Requires-Dist: msal>=1.31
11
11
  Requires-Dist: httpx>=0.27
12
12
  Requires-Dist: mcp>=1.8
13
13
  Provides-Extra: models
14
- Requires-Dist: confluence-knowledge[models]>=0.5.2; extra == "models"
14
+ Requires-Dist: confluence-knowledge[models]>=0.5.3; extra == "models"
15
15
  Provides-Extra: dev
16
16
  Requires-Dist: pytest>=8.0; extra == "dev"
17
17
  Requires-Dist: ruff>=0.5; extra == "dev"
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "sharepoint-knowledge"
7
- version = "0.2.2"
7
+ version = "0.2.3"
8
8
  description = "SharePoint connector for the grounded-Q&A engine — site pages + document libraries, Entra device-code sign-in, local models, cited answers"
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.11"
@@ -18,7 +18,7 @@ dependencies = [
18
18
 
19
19
  [project.optional-dependencies]
20
20
  models = [
21
- "confluence-knowledge[models]>=0.5.2",
21
+ "confluence-knowledge[models]>=0.5.3",
22
22
  ]
23
23
  dev = [
24
24
  "pytest>=8.0",
@@ -197,6 +197,9 @@ class SPCrawler:
197
197
 
198
198
  queue: list[str] = job["queue"]
199
199
  errors: list[str] = job["errors"]
200
+ # deny/gone errors drop the item from the snapshot; transient
201
+ # failures keep the previously-indexed content
202
+ keep_failed: set[str] = set()
200
203
  # Mid-crawl model change: already-embedded pages live in the OLD
201
204
  # vector space — finishing would publish mixed dims. Wipe + fail;
202
205
  # start_crawl rebuilds under the new model.
@@ -264,6 +267,13 @@ class SPCrawler:
264
267
  continue
265
268
  except AccessError as e:
266
269
  errors.append(f"{entry}: {e}")
270
+ if not any(m in str(e) for m in
271
+ ("401", "403", "404", "permission", "not found")):
272
+ # seen stores the built page_id — page: / file: prefixed
273
+ last = entry.split(":")[-1]
274
+ keep_failed.add(
275
+ f"page:{last}" if entry.startswith("page:")
276
+ else f"file:{last}")
267
277
  continue
268
278
  pid = page["page_id"]
269
279
  if pid in seen:
@@ -285,7 +295,7 @@ class SPCrawler:
285
295
  seen.add(pid)
286
296
 
287
297
  self._checkpoint(job_id, queue, errors, seen, levels, warns)
288
- self.index.publish(seen)
298
+ self.index.publish(seen | keep_failed)
289
299
  self.index.set_model_id(_MODEL_ID)
290
300
  self.index.save_job(job_id, "done" if not queue else "running",
291
301
  queue, errors)
@@ -30,7 +30,7 @@ from .settings_sp import APP_NAME, SPProfile, graph_base, home, index_root, work
30
30
  mcp = FastMCP("sharepoint-knowledge")
31
31
 
32
32
  _scopes: dict[str, dict] = {}
33
- _evidence_sets: dict[str, list[dict]] = {}
33
+ _evidence_sets: dict[str, dict] = {} # set_id → {scope, ev}
34
34
  _indexes: dict[str, Index] = {}
35
35
  _clients: dict[str, object] = {}
36
36
  _EMBEDDER = None
@@ -311,7 +311,10 @@ def search(scope_handle: str, question: str) -> dict:
311
311
  "— run start_crawl once to rebuild it, then search again"}
312
312
  ev = retrieve(idx, question, _embedder(), _reranker(), sparse=_sparse())
313
313
  set_id = f"ev:{len(_evidence_sets)}:{s['key'][:8]}"
314
- _evidence_sets[set_id] = ev
314
+ # bound the session cache — sets are never reused after the turn ends
315
+ while len(_evidence_sets) >= 32:
316
+ _evidence_sets.pop(next(iter(_evidence_sets)))
317
+ _evidence_sets[set_id] = {"scope": s["key"], "ev": ev}
315
318
  return {
316
319
  "evidence_set": set_id,
317
320
  "coverage": _coverage(idx),
@@ -319,7 +322,9 @@ def search(scope_handle: str, question: str) -> dict:
319
322
  "evidence": [
320
323
  {"chunk_id": e["chunk_id"], "page_title": e["page_title"],
321
324
  "page_url": e["page_url"], "heading": e["heading"],
322
- "score": e.get("rerank_score"), "text": e["text"][:2000]}
325
+ "score": e.get("rerank_score"), "text": e["text"][:12000],
326
+ "low_confidence": e.get("low_confidence", False),
327
+ "truncated": len(e["text"]) > 12000}
323
328
  for e in ev
324
329
  ],
325
330
  }
@@ -345,12 +350,12 @@ def get_evidence(scope_handle: str, chunk_ids: list[str]) -> dict:
345
350
  @mcp.tool()
346
351
  def verify_citations(scope_handle: str, evidence_set: str,
347
352
  mappings: list[dict]) -> dict:
348
- _scope(scope_handle)
349
- ev = _evidence_sets.get(evidence_set)
350
- if ev is None or not evidence_set.endswith(_scopes[scope_handle]["key"][:8]):
353
+ s = _scope(scope_handle)
354
+ rec = _evidence_sets.get(evidence_set)
355
+ if rec is None or rec["scope"] != s["key"]:
351
356
  raise SecurityException(
352
357
  "unknown or cross-scope evidence set — run search again and cite its evidence_set")
353
- return check_citations(ev, mappings)
358
+ return check_citations(rec["ev"], mappings)
354
359
 
355
360
 
356
361
  def main() -> None:
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: sharepoint-knowledge
3
- Version: 0.2.2
3
+ Version: 0.2.3
4
4
  Summary: SharePoint connector for the grounded-Q&A engine — site pages + document libraries, Entra device-code sign-in, local models, cited answers
5
5
  License: Apache-2.0
6
6
  Project-URL: Homepage, https://github.com/nkunal1992/agents
@@ -11,7 +11,7 @@ Requires-Dist: msal>=1.31
11
11
  Requires-Dist: httpx>=0.27
12
12
  Requires-Dist: mcp>=1.8
13
13
  Provides-Extra: models
14
- Requires-Dist: confluence-knowledge[models]>=0.5.2; extra == "models"
14
+ Requires-Dist: confluence-knowledge[models]>=0.5.3; extra == "models"
15
15
  Provides-Extra: dev
16
16
  Requires-Dist: pytest>=8.0; extra == "dev"
17
17
  Requires-Dist: ruff>=0.5; extra == "dev"
@@ -12,4 +12,4 @@ openpyxl>=3.1
12
12
  pypdf>=5.0
13
13
 
14
14
  [models]
15
- confluence-knowledge[models]>=0.5.2
15
+ confluence-knowledge[models]>=0.5.3