Skip to content

GML-2163-UI-GAP: surface rebuild stage in UI during long ECC phases - add progres… - #47

Merged
chengbiao-jin merged 3 commits into
release_2.0.1from
GML-2163-UI-GAP
Jul 22, 2026
Merged

GML-2163-UI-GAP: surface rebuild stage in UI during long ECC phases - add progres…#47
chengbiao-jin merged 3 commits into
release_2.0.1from
GML-2163-UI-GAP

Conversation

@prinskumar-tigergraph

@prinskumar-tigergraph prinskumar-tigergraph commented Jul 13, 2026

Copy link
Copy Markdown
Contributor

User description

callbacks to embed, extract, summarize_communities; cache last ECC status to fix unknown time on timeout


PR Type

Bug fix, Enhancement


Description

  • Surface long-running rebuild progress

  • Preserve ECC status during timeouts

  • Propagate progress callbacks across phases


Diagram Walkthrough

flowchart LR
  ecc["ECC rebuild phases"]
  callbacks["Progress callbacks"]
  ui["UI rebuild status"]
  cache["Last status cache"]
  timeout["Timeout fallback"]

  ecc -- "emits updates" --> callbacks
  callbacks -- "updates stage text" --> ui
  ui -- "stores running status" --> cache
  timeout -- "uses cached stage" --> ui
Loading

File Walkthrough

Relevant files
Enhancement
graph_rag.py
Add rebuild progress callbacks to GraphRAG phases               

ecc/app/graphrag/graph_rag.py

  • Adds optional progress callbacks to embed.
  • Adds optional progress callbacks to extract.
  • Adds optional progress callbacks to summarize_communities.
  • Passes progress callbacks through rebuild task creation.
+22/-5   
Bug fix
ui.py
Cache ECC rebuild status for timeout fallback                       

graphrag/app/routers/ui.py

  • Adds _last_ecc_status_cache per graph.
  • Caches successful running ECC status responses.
  • Clears cached status on completion or timeout.
  • Returns cached stage data when status polling times out.
+16/-2   

@tg-pr-agent

tg-pr-agent Bot commented Jul 13, 2026

Copy link
Copy Markdown

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 2 🔵🔵⚪⚪⚪
🧪 No relevant tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Status Loss

The timeout fallback expands the cached ECC response but then unconditionally overwrites status with unknown, which may defeat the goal of preserving the last known status/stage during timeouts. Consider preserving cached status when present and only defaulting to unknown when no cached value exists.

cached = _last_ecc_status_cache.get(graphname, {})
return {
    **cached,
    "graphname": graphname,
    "is_running": True,
    "status": "unknown",
    "error": "ECC is busy processing, status check timed out. Rebuild likely still in progress."
Cache Scope

_last_ecc_status_cache is an in-memory module-level cache populated only by the background monitor. In multi-worker deployments, restarts, or requests routed to a different process, timeout fallback may still return no prior started_at or stage. Validate whether this is sufficient for the UI or whether shared/persistent status storage is needed.

# Cache the last successful ECC status response per graph so the UI
# still sees started_at and stage when ECC is too busy to respond.
_last_ecc_status_cache: dict = {}
Callback Errors

Progress callback exceptions are silently swallowed, which can hide UI update failures and make rebuild progress appear stalled without diagnostics. Consider at least logging callback failures at debug or warning level.

if progress is not None:
    try:
        progress(f"Embedding documents ({n_embed} embedded so far)")
    except Exception:
        pass

Comment thread ecc/app/graphrag/graph_rag.py Outdated
Comment on lines +369 to +373
if progress is not None:
try:
progress(f"Embedding documents ({n_embed} embedded so far)")
except Exception:
pass

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: If progress is an async callback, calling it without awaiting will silently skip the UI update and emit an un-awaited coroutine warning. Capture the return value and await it when it is a coroutine; apply the same pattern to the new progress(...) calls in extract and summarize_communities. [possible issue, importance: 6]

Suggested change
if progress is not None:
try:
progress(f"Embedding documents ({n_embed} embedded so far)")
except Exception:
pass
if progress is not None:
try:
result = progress(f"Embedding documents ({n_embed} embedded so far)")
if asyncio.iscoroutine(result):
await result
except Exception:
pass

Comment on lines 2305 to 2306
except Exception as e:
LogWriter.error(f"Error during ECC rebuild monitoring for {graphname}: {e}")

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: _last_ecc_status_cache is only cleared on normal completion and timeout, so an unexpected monitor failure can leave stale running status for the graph. Clear the cache in finally before releasing the rebuild lock so later timeout fallbacks do not report an old rebuild as active. [possible issue, importance: 7]

New proposed code:
 except Exception as e:
     LogWriter.error(f"Error during ECC rebuild monitoring for {graphname}: {e}")
     import traceback
     LogWriter.error(traceback.format_exc())
 finally:
+    _last_ecc_status_cache.pop(graphname, None)
     # Release lock only after ALL stages complete (or timeout/error)
     release_rebuild_lock(graphname)
     LogWriter.info(f"Released global rebuild lock for {graphname}")

Comment thread graphrag/app/routers/ui.py Outdated
Comment on lines 2359 to 2364
cached = _last_ecc_status_cache.get(graphname, {})
return {
**cached,
"graphname": graphname,
"is_running": True,
"status": "unknown",

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggestion: This always overwrites the cached status with "unknown", which can hide the last known rebuild phase from the UI during ECC timeouts. Preserve the cached status when available and only fall back to "unknown" when the cache has no status. [general, importance: 7]

New proposed code:
 cached = _last_ecc_status_cache.get(graphname, {})
 return {
     **cached,
     "graphname": graphname,
     "is_running": True,
-    "status": "unknown",
+    "status": cached.get("status", "unknown"),
     "error": "ECC is busy processing, status check timed out. Rebuild likely still in progress."
 }

@prinskumar-tigergraph prinskumar-tigergraph changed the title fix: surface rebuild stage in UI during long ECC phases - add progres… GML-2163-UI-GAP: surface rebuild stage in UI during long ECC phases - add progres… Jul 13, 2026
…s callbacks to embed, extract, summarize_communities; cache last ECC status to fix unknown time on timeout
Expose progress_current/total/pct from ECC and render a bar in KGAdmin so the UI shows real progress while chunking documents, without wiping the bar when stream_docs finishes early.
@chengbiao-jin
chengbiao-jin merged commit e5fbad4 into release_2.0.1 Jul 22, 2026
@chengbiao-jin
chengbiao-jin deleted the GML-2163-UI-GAP branch July 22, 2026 19:06
chengbiao-jin added a commit that referenced this pull request Jul 24, 2026
* GML-2088: Add regression evaluation pipeline and Apple_SEQ_10 dataset

Add evaluator.py with Planned/Reactive/Classic agent support via --agent flag
Add run_eval.sh, setup_graph.py, run_setup.sh, run_load.sh for eval workflow
Add Apple_SEQ_10 dataset (questions, answers, 4 AAPL PDFs, exported graph)
Fix agent_hallucination_check.py: langchain import updated to langchain_core
Update docker-compose.yml: volume mounts for regression and test_questions
Update requirements.txt: add deepeval==4.0.7, pin click>=8.0.0,<8.4.0

* GML-2164 Fix incorrect OpenAI label in GenAI and Groq instantiation logs (#50)

Co-authored-by: Prins Kumar <prins.kumar@agivant.com>

* GML-2163-UI-GAP: surface rebuild stage in UI during long ECC phases - add progres… (#47)

* fix: surface rebuild stage in UI during long ECC phases - add progress callbacks to embed, extract, summarize_communities; cache last ECC status to fix unknown time on timeout

* fix: clear ECC status cache in finally and preserve cached status on timeout

* feat: show document-level chunking progress during rebuild

Expose progress_current/total/pct from ECC and render a bar in KGAdmin so the UI shows real progress while chunking documents, without wiping the bar when stream_docs finishes early.

---------

Co-authored-by: Prins Kumar <prins.kumar@agivant.com>

* Parse model responses returned as structured content blocks

- Classic chat reads the answer from providers that return content as blocks
  (Gemini 3+ and other reasoning models) instead of failing to parse it
- Raise the LangChain dependency floors to the 1.x versions this release builds on

Refs: GML-2165, GML-2137

* Keep the regression hallucination grader out of the production agent

- Restore the agent's hallucination check to its 2.0.0 form
- Move the graded 0-1 confidence grader into the regression evaluation suite

Refs: GML-2088

* Harden community summarization and show rebuild progress

- Fail fast when the language model is unreachable during community
  summarization, so a knowledge-graph rebuild no longer hangs.
- Leave a clear placeholder for community summaries that could not be
  generated so they can be regenerated once the model is reachable.
- Show per-stage rebuild progress: a document-processing bar, the
  community-detection level, and a community-summarization bar.
- End a rebuild with a warning when some community summaries could not
  be generated, instead of reporting a plain success.
- Bump release to 2.0.1 and update README and CHANGELOG.

Refs: GML-2163

* Relicense from Apache 2.0 to AGPL-3.0

- Replace the LICENSE file with the full AGPL-3.0 text.
- Update every source-file license header to the AGPL-3.0 notice.
- Document the license change in the README and CHANGELOG.

Refs: GML-2166

* Simplify AGPL license headers and update release notes

- Replace the verbose GNU notice in source headers with a concise
  reference to the AGPL-3.0 license and the LICENSE file.
- Note the relicense in the README release log and trim the 2.0.1 entry.

Refs: GML-2166

* Copy regression test files into the container on demand

- Remove the bind mounts of the regression code and test_questions from
  the default compose, so a normal deployment carries no test artifacts.
- The regression run scripts now copy those files into the running
  container before a run and copy eval results back out.

Refs: GML-2088

* Expand AGPL license headers with warranty disclaimer

- Restore the AGPL warranty disclaimer and license-copy notice in source
  file headers, with the opening reworded to omit the "free software"
  phrasing.

Refs: GML-2166

* Silence dependency deprecation warnings at startup

- Migrate the graphrag app from FastAPI on_event handlers to a lifespan
  handler (the ECC app already used lifespan).
- Import the sunset langchain-experimental graph transformer lazily, so
  the warning only fires if that extractor is actually used.
- Drop the deprecated useCert argument when cloning TigerGraph connections.

Refs: GML-2137

* Deprecate the graphrag entity-extractor option

- Mark the `graphrag` extractor mode as deprecated in the README; it
  relies on the sunset langchain-experimental package and is superseded
  by the default `llm` extractor. Code retained for now.

Refs: GML-2137

---------

Co-authored-by: Prins Kumar <prins.kumar@agivant.com>
Co-authored-by: prinskumar-tigergraph <prins.kumar@tigergraph.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants