Skip to content

GML-2022 Release 1.4.0 for schema-aware knowledge graph ingestion and query#39

Merged
chengbiao-jin merged 79 commits into
mainfrom
release_1.4.0
May 16, 2026
Merged

GML-2022 Release 1.4.0 for schema-aware knowledge graph ingestion and query#39
chengbiao-jin merged 79 commits into
mainfrom
release_1.4.0

Conversation

@chengbiao-jin
Copy link
Copy Markdown
Collaborator

@chengbiao-jin chengbiao-jin commented May 15, 2026

PR Type

Enhancement, Tests


Description

  • Add schema-aware ingest foundation

    • Parse, diff, preview, and apply schemas
    • Persist type metadata and schema text
    • Install retrievers from live schema
  • Expand LLM prompt customization

    • Add built-in fallback prompt templates
    • Support shared top-level prompt_path
    • Add schema extraction and retriever prompts
  • Improve embedding store lifecycle

    • Add async background initialization
    • Cache per-graph embedding stores
    • Rebuild stores on config reload
  • Strengthen observability and validation

    • Collect per-request LLM token usage
    • Skip redundant GDS installs
    • Add broad ingest and prompt tests

Diagram Walkthrough

flowchart LR
  a["Sample docs or pasted GSQL"] -- "extract / parse" --> b["SchemaProposal"]
  b -- "diff and apply" --> c["TigerGraph schema"]
  b -- "upsert descriptions" --> d["Type metadata"]
  c -- "render live schema" --> e["AllowedSchema"]
  e -- "install" --> f["Domain retrievers"]
  g["Prompt path + fallback prompts"] -- "guide" --> h["LLM tools"]
  i["Embedding store cache"] -- "serve per graph" --> h
  h -- "record usage" --> j["Trace logs / token tracking"]
Loading

File Walkthrough

Relevant files
Enhancement
19 files
schema_utils.py
Add full schema proposal and apply pipeline                           
+1872/-0
base_llm.py
Add usage collection and fallback prompt templates             
+454/-103
config.py
Propagate prompt paths and cache embedding stores               
+160/-4 
tigergraph_embedding_store.py
Avoid redundant GDS installs and quieter logging                 
+50/-6   
schema_extraction.py
Add schema extraction support from sample documents           
+345/-0 
retriever_render.py
Render and install retrievers from domain schema                 
+236/-0 
prompt_validation.py
Add prompt validation utilities                                                   
+142/-0 
graphrag_stream_entity_community_pairs.gsql
Add query to stream entity community pairs                             
+21/-0   
graphrag_delete_all_communities.gsql
Add query to clear community data                                               
+21/-0   
graphrag_stream_all_ids.gsql
Add query to stream graph identifiers                                       
+17/-0   
method_selector.py
Add LLM-based retrieval method selector                                   
+300/-0 
ui.py
Add UI endpoints for schema and prompts                                   
+1194/-126
LLMEntityRelationshipExtractor.py
Wire extractor to domain schema controls                                 
+266/-141
workers.py
Update ECC workers for schema-aware ingest                             
+374/-66
util.py
Support schema-aware ECC utility flow                                       
+318/-16
graph_rag.py
Integrate schema-aware graph ingestion behavior                   
+165/-34
text_extractors.py
Expand document extraction for CSV and Excel                         
+194/-47
agent_graph.py
Integrate retriever selection and trace data                         
+233/-11
agent.py
Capture node usage and tracing details                                     
+124/-8 
Tests
1 files
test_schema_utils.py
Add unit coverage for schema utilities                                     
+1399/-0
Additional files
101 files
CHANGELOG.md +88/-0   
README.md +8/-0     
VERSION +1/-1     
graphrag_louvain_communities.gsql +2/-1     
graphrag_louvain_init.gsql +2/-7     
modularity.gsql +2/-1     
stream_community.gsql +2/-1     
SupportAI_Schema.gsql +2/-3     
create_entity_type_relationships.gsql +0/-20   
Content_Similarity_Search.gsql +3/-3     
Content_Similarity_Vector_Search.gsql +8/-8     
GraphRAG_Hybrid_Search.gsql +9/-3     
GraphRAG_Hybrid_Search_Display.gsql +5/-3     
GraphRAG_Hybrid_Vector_Search.gsql +5/-3     
aws_bedrock_service.py +79/-1   
prometheus_metrics.py +5/-0     
chatbot_response.txt +0/-17   
community_summarization.txt +0/-11   
entity_relationship_extraction.txt +0/-24   
generate_cypher.txt +0/-85   
generate_function.txt +0/-27   
graphrag_scoring.txt +0/-7     
map_question_to_schema.txt +0/-14   
generate_function.txt +0/-14   
map_question_to_schema.txt +0/-19   
entity_relationship_extraction.txt +0/-24   
generate_function.txt +0/-29   
map_question_to_schema.txt +0/-17   
chatbot_response.txt +0/-29   
community_summarization.txt +0/-11   
entity_relationship_extraction.txt +0/-24   
generate_cypher.txt +0/-85   
generate_function.txt +0/-27   
graphrag_scoring.txt +0/-7     
map_question_to_schema.txt +0/-14   
community_summarization.txt +0/-11   
entity_relationship_extraction.txt +0/-24   
generate_function.txt +0/-33   
map_question_to_schema.txt +0/-14   
chatbot_response.txt +0/-17   
community_summarization.txt +0/-11   
entity_relationship_extraction.txt +0/-24   
generate_cypher.txt +0/-84   
generate_function.txt +0/-24   
graphrag_scoring.txt +0/-7     
map_question_to_schema.txt +0/-15   
question_expansion.txt +0/-6     
generate_function.txt +0/-24   
map_question_to_schema.txt +0/-15   
chatbot_response.txt +0/-17   
community_summarization.txt +0/-11   
entity_relationship_extraction.txt +0/-24   
generate_cypher.txt +0/-85   
generate_function.txt +0/-27   
graphrag_scoring.txt +0/-7     
map_question_to_schema.txt +0/-15   
question_expansion.txt +0/-6     
requirements.txt +2/-0     
image_data_extractor.py +44/-5   
docker-compose.yml +5/-3     
nginx.conf +8/-0     
Dockerfile +4/-1     
ecc_util.py +2/-2     
eventual_consistency_checker.py +4/-18   
community_summarizer.py +1/-1     
main.py +59/-8   
supportai_init.py +7/-5     
util.py +5/-4     
workers.py +16/-38 
.npmrc +2/-0     
Dockerfile +9/-1     
package.json +10/-3   
ActionProvider.tsx +28/-3   
Bot.tsx +16/-6   
ConfigScopeToggle.tsx +1/-1     
CustomChatMessage.tsx +93/-1   
Interact.tsx +58/-15 
ModeToggle.tsx +32/-9   
SideMenu.tsx +33/-7   
alert-dialog.tsx +48/-0   
tag-input.tsx +186/-0 
useAlert.tsx +34/-0   
useIdleTimeout.ts +13/-0   
index.css +13/-1   
main.tsx +6/-0     
Chat.tsx +103/-4 
Setup.tsx +34/-8   
TraceLogs.tsx +1018/-0
CustomizePrompts.tsx +47/-41 
GraphRAGConfig.tsx +308/-51
IngestGraph.tsx +122/-28
KGAdmin.tsx +1868/-55
LLMConfig.tsx +2/-2     
SetupLayout.tsx +25/-3   
safeJson.ts +18/-0   
Dockerfile +8/-2     
inquiryai.py +28/-25 
supportai.py +21/-16 
BaseRetriever.py +9/-3     
supportai_ingest.py +11/-52 
Additional files not shown

chengbiao-jin and others added 30 commits April 14, 2026 22:07
Schema-aware ingest
- Add Initialize Knowledge Graph flow with optional schema generation
  from samples or pasted GSQL, reviewable in a form-mode editor
- Populate declared domain vertex / edge instances during extraction;
  opt-in strict mode drops non-schema extractions
- Add typed-relationship metadata layer (EntityType / RelationshipType)
  carrying per-type definitions used by retrievers and the chat agent;
  auto-fills from extracted types when no domain schema is declared
- Surface domain vertex type labels in retrieval LLM context
- Thread schema definitions into LLM prompts for query generation and
  extraction; permissive parser accepts UNDIRECTED edges
- Add E2E test covering the schema-aware initialization and ingest path

Prompt management
- Centralize all customizable prompts as in-code defaults
- Make schema-extraction prompt customizable via the /prompts API
- Lift prompt_path to global llm_config scope
- Validate and escape user-customized prompts server-side
- Add E2E test covering the customizable-prompt round-trip

Startup / runtime
- Async embedding-store initialization
- Parallel image description with concurrency knob
- Skip redundant GDS install when already present
- Auto-default Bedrock max_tokens per model family so large prompts
  do not truncate
- Surface TigerGraph version mismatch as a clear startup error
- Embedding-store status check returns HTTP 503 on failure

Reliability
- Detect real GSQL failures in schema-change apply
### **User description**
## Trace Logs UI

Adds a **"View Trace"** link on bot responses that opens a detailed
Trace Logs page showing:
- Original user query
- Timing overview (total duration, tool execution, LLM thinking)
- All LangGraph agent nodes executed with per-node duration
- Source citations with cited/considered status
- Visual timeline of the execution flow

**Backend**: Instrumented the LangGraph `stream()` loop in `agent.py` to
capture each node's name and execution time into
`query_sources.agent_steps`.

**Frontend**: New `TraceLogs.tsx` page with tabs (Logs, Tool Calls,
Citations, Timeline), wired via "View Trace" link in chat messages.


___

### **PR Type**
Enhancement


___

### **Description**
- Instrument agent to capture step timings

- Add Trace Logs page with tabs

- Pass user query and agent steps

- Add "View Trace" link in chat


___

### Diagram Walkthrough


```mermaid
flowchart LR
  agentPy["Backend agent.py streams nodes"]
  capture["Capture durations as agent_steps"]
  answerAug["Augment answer.query_sources.agent_steps"]
  ws["WebSocket message to UI"]
  attach["Attach userQuery in ActionProvider"]
  viewLink["Chat 'View Trace' button"]
  route["/trace route"]
  tracePage["TraceLogs page (Logs/Tools/Citations/Timeline)"]

  agentPy -- "measure durations" --> capture
  capture -- "attach to answer" --> answerAug
  answerAug -- "send" --> ws
  ws -- "enrich with userQuery" --> attach
  attach -- "render" --> viewLink
  viewLink -- "navigate" --> route
  route -- "display" --> tracePage
```



<details> <summary><h3> File Walkthrough</h3></summary>

<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><table>
<tr>
  <td>
    <details>
<summary><strong>agent.py</strong><dd><code>Capture and attach agent
node timings</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

graphrag/app/agent/agent.py

<ul><li>Measure per-node durations during stream<br> <li> Accumulate
<code>agent_steps</code> with node and seconds<br> <li> Log executed
node with duration<br> <li> Attach <code>agent_steps</code> to
<code>answer.query_sources</code></ul>


</details>


  </td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/33/files#diff-21b6ee06c77f665fd7772366a70c1d9861d4c82cfed32bc423ac7e72607f1b19">+19/-3</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>ActionProvider.tsx</strong><dd><code>Propagate user
query into bot messages</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

graphrag-ui/src/actions/ActionProvider.tsx

<ul><li>Track last user query via <code>useRef</code><br> <li> Store
query on send (default/questions)<br> <li> Attach <code>userQuery</code>
to incoming message data<br> <li> Adjust imports to include
<code>useRef</code></ul>


</details>


  </td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/33/files#diff-16b0b36230dcfb45e19728a1b279229508bff3de49bbaf794e3c88d3cffe6f51">+7/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>CustomChatMessage.tsx</strong><dd><code>Add View Trace
action in chat messages</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

graphrag-ui/src/components/CustomChatMessage.tsx

<ul><li>Add "View Trace" button with icon<br> <li> Navigate to
<code>/trace</code> with state payload<br> <li> Show when
<code>query_sources</code> present</ul>


</details>


  </td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/33/files#diff-cfff26097e20241baca29ca937bc99de30994552ea521f60b571632c99d837f1">+14/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>main.tsx</strong><dd><code>Register Trace Logs
route</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

graphrag-ui/src/main.tsx

- Import new `TraceLogs` page
- Register protected `/trace` route


</details>


  </td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/33/files#diff-e82a3eb03a96f5d8bc1e29c14b6080b9eb7d437436c438b0664c6cf50e4e8a64">+5/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td>
    <details>
<summary><strong>TraceLogs.tsx</strong><dd><code>Implement Trace Logs
page with tabs</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></summary>
<hr>

graphrag-ui/src/pages/TraceLogs.tsx

<ul><li>New Trace Logs page and UI<br> <li> Build trace from
<code>message.query_sources</code><br> <li> Tabs: Logs, Tool Calls,
Citations, Timeline<br> <li> Download trace JSON and copy content</ul>


</details>


  </td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/33/files#diff-2a9285146cff9a154ea772e645cd33d63dd0c045ddaeecfe0168698d95f6c0f7">+697/-0</a>&nbsp;
</td>

</tr>
</table></td></tr></tr></tbody></table>

</details>

___
Added the UI message in case of CSV/XLSX.
XLSX text extraction logic added in the text-extractor file.
chengbiao-jin and others added 23 commits May 7, 2026 16:26
Two new recovery paths that reduce "I'm sorry" responses while staying
honest about failure: structured-data retries now fall through to vector
search, and a chunk-based retriever that returns fewer than top_k
results auto-tries a different method.
generate_function previously passed empty results straight to answer
generation, which risked hallucinated narratives. Mirrors the existing
generate_cypher contract: empty result is a generation failure that
triggers rewrite-retry, and after retries are exhausted the cross-lane
vector fallback takes over.
Cross-lane fallback is gated by graphrag_config.enable_router_fallback
(default true). Operators can opt out per-graph for deployments that
prefer the strict apology path over a vector-search recovery attempt.
Surfaces the cross-lane fallback toggle as a checkbox on the GraphRAG
config admin page so operators can edit it without hand-editing JSON.
### **PR Type**
Enhancement, Documentation, Tests


___

### **Description**
- Add auto retriever selection flow
  - Rule + LLM selector fallback
  - Default chat mode becomes `auto`
  - Track selection telemetry metadata

- Add trace logging and trace UI
  - Persist per-message backend traces
  - Expose authenticated trace endpoint
  - Show node timing and token usage

- Improve answer safety and ingestion
  - Short-circuit empty retrieval hallucinations
  - Support Excel and robust CSV decoding
  - Warn about unsupported ingest files

- Update docs, version, and CI
  - Add tuning guideline and changelog
  - Bump release to `1.4.0`
  - Skip builds for doc-only pushes


___

### Diagram Walkthrough


```mermaid
flowchart LR
  UI["Chat UI defaults to Auto"] 
  Router["UI router saves trace logs"] 
  Selector["RetrieverSelector chooses method"] 
  Agent["Agent records steps and token usage"] 
  Response["Response includes retriever metadata"] 
  TracePage["Trace Logs page renders trace details"] 
  Metrics["Prometheus selection counter"] 
  Docs["Docs and CI updates"]

  UI -- "sends auto retriever" --> Selector
  Selector -- "sets chosen method" --> Agent
  Agent -- "embeds metadata and usage" --> Response
  Response -- "saved per message" --> Router
  Router -- "served via trace API" --> TracePage
  Selector -- "increments" --> Metrics
  Response -- "documented in" --> Docs
```



<details> <summary><h3> File Walkthrough</h3></summary>

<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><details><summary>14
files</summary><table>
<tr>
<td><strong>ui.py</strong><dd><code>Save and serve per-message trace
logs</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/37/files#diff-6bd0577645f5c331c0503b21762ac99be7a11b0f1dd72d4435a84a02f0d18f62">+65/-4</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>agent_graph.py</strong><dd><code>Add auto retriever
selection and OOC guard</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/37/files#diff-50b5c7a1c74e7d2cd53aed6f304d70d84960e89a05647db4294ab5b3e9487501">+113/-11</a></td>

</tr>

<tr>
<td><strong>method_selector.py</strong><dd><code>Implement rule-based
and LLM retriever chooser</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/37/files#diff-631299e1a113d2608cb06dbe0cc94cef9585da9bd710801c0b095d24fcc39038">+251/-0</a>&nbsp;
</td>

</tr>

<tr>
<td><strong>agent.py</strong><dd><code>Capture per-node traces and token
totals</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/37/files#diff-21b6ee06c77f665fd7772366a70c1d9861d4c82cfed32bc423ac7e72607f1b19">+117/-5</a>&nbsp;
</td>

</tr>

<tr>
<td><strong>base_llm.py</strong><dd><code>Add context-local LLM usage
collection helpers</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/37/files#diff-9eb1335890737196b08ce1158f1de3ff08db71d02a613fbc9b967c347a0aa36d">+61/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>text_extractors.py</strong><dd><code>Improve CSV and Excel
text extraction</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/37/files#diff-c749a2c8ea1a8bc0a734203aef7fa5aa9300d705006afbb4cac26985c2ac257d">+42/-3</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>prometheus_metrics.py</strong><dd><code>Add retriever method
selection metric</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/37/files#diff-005fd0165e2dee1d462f4c1a55d4d339af8ed93225bf012bfca3705f47402cfc">+5/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>TraceLogs.tsx</strong><dd><code>Add full trace logs
inspection page</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/37/files#diff-2a9285146cff9a154ea772e645cd33d63dd0c045ddaeecfe0168698d95f6c0f7">+947/-0</a>&nbsp;
</td>

</tr>

<tr>
<td><strong>CustomChatMessage.tsx</strong><dd><code>Show retriever badge
and open traces</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/37/files#diff-cfff26097e20241baca29ca937bc99de30994552ea521f60b571632c99d837f1">+52/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>ActionProvider.tsx</strong><dd><code>Preserve last user
query for traces</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/37/files#diff-16b0b36230dcfb45e19728a1b279229508bff3de49bbaf794e3c88d3cffe6f51">+7/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>Interact.tsx</strong><dd><code>Add role-gated View Trace
action</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/37/files#diff-756611d7cf8b46de8c46d6abfae34d156ebb8acd8a2e1efbc8ebe289dbe246b8">+23/-8</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>Bot.tsx</strong><dd><code>Default chat retrieval mode to
Auto</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/37/files#diff-240a9434a7410733cf592017b89dd0fe904ccc99e0d71b2b819dfacdae66feae">+5/-4</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>IngestGraph.tsx</strong><dd><code>Warn about skipped and
spreadsheet uploads</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/37/files#diff-7c6239f8c037f4932a1560909f98d7be9e8b61b55885826868ccc6396e56fe4d">+26/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>main.tsx</strong><dd><code>Register authenticated trace page
route</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/37/files#diff-e82a3eb03a96f5d8bc1e29c14b6080b9eb7d437436c438b0664c6cf50e4e8a64">+6/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

</table></details></td></tr><tr><td><strong>Tests</strong></td><td><details><summary>1
files</summary><table>
<tr>
<td><strong>test_method_selector.py</strong><dd><code>Cover selector
rules, LLM path, fallback</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/37/files#diff-23db06d286f3b7d3be02fc84613ab60c5d3f32266533979837850448c38249d6">+292/-0</a>&nbsp;
</td>

</tr>

</table></details></td></tr><tr><td><strong>Documentation</strong></td><td><details><summary>2
files</summary><table>
<tr>
<td><strong>README.md</strong><dd><code>Add tuning guideline and release
updates</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/37/files#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5">+117/-2</a>&nbsp;
</td>

</tr>

<tr>
<td><strong>CHANGELOG.md</strong><dd><code>Document `1.4.0` retrieval
improvements</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/37/files#diff-06572a96a58dc510037d5efa622f9bec8519bc1beab13c9f251e97e657a9d4ed">+10/-0</a>&nbsp;
&nbsp; </td>

</tr>

</table></details></td></tr><tr><td><strong>Dependencies</strong></td><td><details><summary>2
files</summary><table>
<tr>
<td><strong>package.json</strong><dd><code>Add UI packages for trace
page support</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/37/files#diff-c37db0061858d678c19abeadf948abe2659141efd45e288d50145960b1711f5d">+3/-3</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>requirements.txt</strong><dd><code>Add Excel parsing runtime
dependencies</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/37/files#diff-e66887509cf346e41e1a9ccb30ddab589260f362899946f6b26602b5e29c547c">+2/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></details></td></tr><tr><td><strong>Configuration
changes</strong></td><td><details><summary>7 files</summary><table>
<tr>
<td><strong>nginx.conf</strong><dd><code>Proxy trace UI routes through
nginx</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/37/files#diff-f03c325fe986004de6d5dc60fa018b94878b383e21cee2b2b7173a6638a0a964">+8/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>docker-compose.yml</strong><dd><code>Mount persistent trace
logs volume</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/37/files#diff-e45e45baeda1c1e73482975a664062aa56f20c03dd9d64a827aba57775bed0d3">+1/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>cloud-build-nightly.yaml</strong><dd><code>Skip nightly
cloud builds on docs changes</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/37/files#diff-de6b9c67da89f0a01ab72c532ac89caa7aba5666f77ee4a01cbc0438cb6e7213">+9/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>cloud-build-deploy-ci.yaml</strong><dd><code>Skip cloud CI
builds on docs changes</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/37/files#diff-2990880954093756dc99ce17c27de7535c5a3afaca9e816cb534f90c56414940">+9/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>onprem-build-nightly.yaml</strong><dd><code>Skip nightly
on-prem builds on docs changes</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/37/files#diff-f1bc3327e074995d0257ba0cffde0b4568b2a4b96cbbe94a9210371099e58775">+9/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>onprem-build.yaml</strong><dd><code>Skip on-prem builds on
docs changes</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/37/files#diff-509b455bda1cb15bf50d5b895faed9a83d54451cc5a13c883587026239a70bda">+9/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
<td><strong>VERSION</strong><dd><code>Bump project version to
`1.4.0`</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/37/files#diff-7b60b8e351cbb80c47459ffe2c79f1a26404871f49294780fe47ad0e58c09350">+1/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></details></td></tr></tr></tbody></table>

</details>

___
…ML-2004-Integrate-Schema

# Conflicts:
#	CHANGELOG.md
#	README.md
- apply_proposal validates graph and job identifiers, cleans up the
  schema-change job on every failure path, and returns a uniform
  result shape on the error branch.
- Permissive GSQL parser early-rejects edge pairs whose endpoints
  are structural or reserved.
- reload_llm_config and reload_db_config reset the embedding store so
  callers don't keep stale credentials or model bindings after a
  config reload.
- ECC worker resolves endpoint-pair lookups via the canonical-resolved
  edge name.
- convert_sample_files rejects duplicate-basename uploads;
  extract_schema_from_jsonl fails fast when any requested file's JSONL
  is missing.
- E2E schema-aware test sources the TG host from TG_HOST or
  SERVER_CONFIG.db_config.hostname; no baked-in default.
- Similarity retrievers' Python param order matches their GSQL
  signatures.
### **PR Type**
Enhancement, Tests, Bug fix


___

### **Description**
- Add schema-aware domain schema utilities
  - Parse permissive GSQL into proposals
  - Emit additive schema-change jobs
  - Upsert type metadata and retrievers

- Make extraction prompts schema-aware
  - Inject type definitions and endpoints
  - Support strict schema extraction mode

- Improve config and startup behavior
  - Propagate top-level `prompt_path`
  - Async-init embedding store safely
  - Expose embedding service/store getters

- Add broad unit and E2E coverage


___

### Diagram Walkthrough


```mermaid
flowchart LR
  gsql["Pasted or discovered GSQL"] --> parser["`parse_gsql_schema` builds proposal"]
  parser --> diff["Emit additive schema statements"]
  diff --> apply["Atomic `SCHEMA_CHANGE JOB` apply"]
  apply --> meta["Upsert `EntityType` / `RelationshipType` metadata"]
  apply --> retr["Re-render and install retrievers"]
  meta --> extract["Schema-aware extraction prompts"]
  cfg["LLM config"] --> prompt["Propagate top-level `prompt_path`"]
  cfg --> store["Async embedding-store initialization"]
```



<details> <summary><h3> File Walkthrough</h3></summary>

<table><thead><tr><th></th><th align="left">Relevant
files</th></tr></thead><tbody><tr><td><strong>Enhancement</strong></td><td><details><summary>10
files</summary><table>
<tr>
<td><strong>schema_utils.py</strong><dd><code>Add schema proposal
parsing and apply pipeline</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-f20d65e46d5b3bb8288551ded8bdd271d288df7326c3a334935a57fe53873a2b">+1402/-0</a></td>

</tr>

<tr>
<td><strong>config.py</strong><dd><code>Propagate prompt path and async
embed store</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-1bacff878451e5aa9c6d164150c7b2daad028d5e7acba90bb720cb73ffdd827b">+105/-18</a></td>

</tr>

<tr>
<td><strong>LLMEntityRelationshipExtractor.py</strong><dd><code>Inject
schema definitions into extraction prompts</code>&nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-05ab3c45a1534c14f53f2682e3712c2fb1f12e00c55dd9573ab26582facc19e9">+103/-0</a>&nbsp;
</td>

</tr>

<tr>
<td><strong>retriever_render.py</strong><dd><code>Render retrievers from
live domain schema</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-84b533e85612ab5cb0462dff45d30ed279ffc0a0285f235a675cd97ffd44f47c">+204/-0</a>&nbsp;
</td>

</tr>

<tr>
<td><strong>schema_extraction.py</strong><dd><code>Add schema extraction
support from samples</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-22030439b880114c90cafd47a109357d6149e422dfe0a5a56a1a37863b7bb313">+115/-0</a>&nbsp;
</td>

</tr>

<tr>

<td><strong>graphrag_stream_entity_community_pairs.gsql</strong><dd><code>Stream
entity-community pairs for domain mirroring</code>&nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-7d8099030781e3b46e089a169cf952e4e4d0ae9444e944ae4d8ad01c85e42caf">+21/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>graphrag_delete_all_communities.gsql</strong><dd><code>Add
community reset query for re-detection</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-d1230d55cdd05fbf0e6355d86bbd605ce06a0b6750559ecb4e4d3229658e2b3f">+21/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>graphrag_stream_all_ids.gsql</strong><dd><code>Stream graph
ids for schema-related workflows</code>&nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-ddce404e9c8040059469767cf21d0df36ff1cd1c1388129743507c34d884eccd">+17/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>base_llm.py</strong><dd><code>Centralize prompt defaults and
loading behavior</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-9eb1335890737196b08ce1158f1de3ff08db71d02a613fbc9b967c347a0aa36d">+337/-105</a></td>

</tr>

<tr>
<td><strong>ui.py</strong><dd><code>Expose prompt and schema-related UI
endpoints</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-6bd0577645f5c331c0503b21762ac99be7a11b0f1dd72d4435a84a02f0d18f62">+417/-85</a></td>

</tr>

</table></details></td></tr><tr><td><strong>Tests</strong></td><td><details><summary>6
files</summary><table>
<tr>
<td><strong>test_schema_utils.py</strong><dd><code>Cover schema parsing,
emit, apply behavior</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-63260ff00a08bb2154c87abbd6c0740ae43fa7b0222376d1c05f2a767b6efae1">+1325/-0</a></td>

</tr>

<tr>
<td><strong>test_e2e_schema_aware_ingest.py</strong><dd><code>Add
end-to-end schema-aware ingest coverage</code>&nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-76d1146b96fbaa236c3fcb5a7e74e8b15034b10e3f484a3a471fac4f95e49c32">+692/-0</a>&nbsp;
</td>

</tr>

<tr>
<td><strong>test_e2e_prompt_customization.py</strong><dd><code>Add
prompt customization round-trip coverage</code>&nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-69d98ac55f24514ddf0aed09ce2b679e40386edc83580f25fc25a1d4a0fb8d55">+300/-0</a>&nbsp;
</td>

</tr>

<tr>
<td><strong>test_schema_extraction.py</strong><dd><code>Add schema
extraction behavior tests</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-091f5c246510bfcfad3730f8dfded58d4c8a2f0ad04f1bc1c5b32fd89fbc3cc5">+200/-0</a>&nbsp;
</td>

</tr>

<tr>
<td><strong>test_prompt_validation.py</strong><dd><code>Validate prompt
escaping and safety rules</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-6d581b00993006046cd2a11bb23ce3ac160add97a2df2c9578441eea242400a7">+184/-0</a>&nbsp;
</td>

</tr>

<tr>

<td><strong>test_llm_entity_relationship_extractor.py</strong><dd><code>Test
schema-guided extraction prompt assembly</code>&nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
</dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-60eeca8ba0699823d00d662b32c79cd4ac75c89bc1306437974d264e2c70848b">+143/-0</a>&nbsp;
</td>

</tr>
</table></details></td></tr><tr><td><strong>Bug
fix</strong></td><td><details><summary>2 files</summary><table>
<tr>
<td><strong>main.py</strong><dd><code>Use dynamic embedding getter and
version checks</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; </dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-870d07e9c93da59bd2a82227a8dc69ee6276f08f25402fd85c3202f6fb8cb5c3">+12/-5</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
<td><strong>safeJson.ts</strong><dd><code>Add safer frontend JSON
parsing utility</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-5065b47db831cc2d4efab81bb9a122979dfac23f7151923df25de9d0dd5b94b1">+18/-0</a>&nbsp;
&nbsp; </td>

</tr>
</table></details></td></tr><tr><td><strong>Configuration
changes</strong></td><td><details><summary>1 files</summary><table>
<tr>
<td><strong>.npmrc</strong><dd><code>Restrict built dependencies for
frontend installs</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-1306a206423c220480cc95bf53161ee5e347a903e12c57b27706ddf6b7403302">+2/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>
</table></details></td></tr><tr><td><strong>Error
handling</strong></td><td><details><summary>1 files</summary><table>
<tr>
<td><strong>prompt_validation.py</strong><dd><code>Add server-side
prompt validation helpers</code>&nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;
&nbsp; </dd></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-aacbd6cc1fa35bda8cafb21bc2a764b3a9f42ce587a4dd1749207082a31e1a42">+135/-0</a>&nbsp;
</td>

</tr>
</table></details></td></tr><tr><td><strong>Additional
files</strong></td><td><details><summary>82 files</summary><table>
<tr>
  <td><strong>CHANGELOG.md</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-06572a96a58dc510037d5efa622f9bec8519bc1beab13c9f251e97e657a9d4ed">+38/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>README.md</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-b335630551682c19a781afebcf4d07bf978fb1f8ac04c6bf87428ed5106870f5">+1/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>tigergraph_embedding_store.py</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-d5a9f07269bd0fae45334ccacd2143a50c62ca89960e27a751b4bd10c78a0952">+48/-5</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>graphrag_louvain_communities.gsql</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-bf197fe183e644957cb51240676496e6e530248fd5a5ffa1112d4e659fbb3c2b">+2/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>graphrag_louvain_init.gsql</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-32a4cba14d7eda5795b302e2812487deb49527ff1c7c193f4f01eb7a687609bd">+2/-7</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>modularity.gsql</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-ed42f02a70fb074f952baee07e3754421708cf266a940e9b9f7890dab39a9379">+2/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>stream_community.gsql</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-c3591e62444614b51643a63d4bdc93ae90ddf1fd271455a1cb787dc2f0b19c0e">+2/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>SupportAI_Schema.gsql</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-cd43a2393c5b263e1bff773778e2e9e7cfa944ce3dce70ac80d717b76928bd15">+2/-3</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>create_entity_type_relationships.gsql</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-fe3a3159e32515262d6313689dc9c4cf73ec8e1d6715c0968dd19902501ba874">+0/-20</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>Content_Similarity_Search.gsql</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-6553efd08a1ebdda1d28b7c48809cff2c43f660b73280f866c98411649440c5a">+3/-3</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>Content_Similarity_Vector_Search.gsql</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-242bc65511cb0e8801ac19f9da304908a64e8dc0ca1bee98e006f32046bcac9a">+8/-8</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>GraphRAG_Hybrid_Search.gsql</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-8bac37f8728dbce26242117be4c6ef1ad3db4006ac76340e40e6ecb61770a71e">+9/-3</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>GraphRAG_Hybrid_Search_Display.gsql</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-099419619a6053771541c934d132f49a58e91ccac7f4a86e181d70e5ab00242c">+5/-3</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>GraphRAG_Hybrid_Vector_Search.gsql</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-542c584a4bbd9c50692e15bf51fae96e8d7679afe36c005744e83650d12e7a54">+5/-3</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>aws_bedrock_service.py</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-280ea890e1d8201b5289243bcc79a9aae7838af208e2f397e0d2d76524775f7d">+79/-1</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>chatbot_response.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-6d46363b15988ecba07de0c99911041ec01c0018bd1a86d876ac0916acdd4d17">+0/-17</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>community_summarization.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-53833bf48ab85e4e40fa95f9fbc3b1a74bbe68524b5e12b4fb86dab372ef1685">+0/-11</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>entity_relationship_extraction.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-5203bce1ffe79ead72cc5991ee37a2b1062b5287c9fe4dbfa380508c0ce32bc7">+0/-24</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>generate_cypher.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-2bd75c6bfb7ebcbf7696fe9cbfc0ea269f923c822c68a74ae8999cb9c41896e4">+0/-85</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>generate_function.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-2d8cd2c2831fbe9bf617715e1f3283566c7e35b6cb8c76337fbe1fca93d234dc">+0/-27</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>graphrag_scoring.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-fd71b316fc0635133d015c7e1b7c4a658263701e5659605debb5908538f344ea">+0/-7</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>map_question_to_schema.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-d4789c85b3f4674a379221f7b7d55ee1fc506a90053389411b609f82a42e31a5">+0/-14</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>generate_function.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-7a05cd838d0fbc74cd095d6300d38aa945902e8571917f14545fa433b1ba2f6f">+0/-14</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>map_question_to_schema.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-bcc2a3870688c4def6d39da3a5ca718ca47d511710bec8057c6e078d87151f30">+0/-19</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>entity_relationship_extraction.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-7e6cb775c97d781df6db1df3887616a3f56cec75bab68517c325e023839c6036">+0/-24</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>generate_function.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-ebb5cd586870142fc16974ce4dec23ec858ec49cec6a599a301df699d4a91cf5">+0/-29</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>map_question_to_schema.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-9a8bbf84141249b3f23f516ae47c1e8a045eccb5e3022f101b4a9c5ccba7445d">+0/-17</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>chatbot_response.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-0ebdb08b93f126d4b65ab6be980c9d04dea2e3ae49c347023a84a40865edca17">+0/-29</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>community_summarization.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-8cd711e857e436db39e75eaa04ab3c726bafde0c1a2673c8217e566cfda7dbb1">+0/-11</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>entity_relationship_extraction.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-845a93792c8e69faa7de27e3d94d70c525387fe290a042ec42c296ffaa425bb8">+0/-24</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>generate_cypher.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-e5be7011e9d9cdf65026313e3c7a773146866ec280de2b21cf6023b8a1fbdfa3">+0/-85</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>generate_function.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-c2b1f009ab574e291d9fb2f989cc75b7eb0ea287ce87ca72f36ee863d36e3786">+0/-27</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>graphrag_scoring.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-72616dc680c8786e5c4a7f1ecf9ed8f10fd18a3982b61a13ec23e1d9d1c2aa27">+0/-7</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>map_question_to_schema.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-f0e23e10c9b409cd0d651e20cd9f4a9fce2e3896a69e1d70dca7fda9bc74a239">+0/-14</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>community_summarization.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-613eb6dcb521365ef109dfdc5194b2ac8c4d44320deb1b86711bc52a2d8f30e6">+0/-11</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>entity_relationship_extraction.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-1b1b8f6aef5f96052f83a5c09978c109b1ed1baf8bbda994bb8669937ac53f08">+0/-24</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>generate_function.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-85d6281f16d53975597ec7e01ddfc9895652f050e631c62392b70d4f8defd794">+0/-33</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>map_question_to_schema.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-1a7c732bb95d1ad1b531243cf9e24226d9fb67ecb57ba4c7cbad88a7e7940a78">+0/-14</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>chatbot_response.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-42d3a598e348eca10fe8d38d96ae78f911ac9e2ec3512d8121848da526b8cb48">+0/-17</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>community_summarization.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-210f52b3d8035997a4c91287cc2fb566b75fec16c3c393fb2ed78ee11f154c0e">+0/-11</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>entity_relationship_extraction.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-104e980e67fd0f45611cdc4b9c98cf827b46513f106fd0f717d5f9e7e8d02c4f">+0/-24</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>generate_cypher.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-3b6ebf68e804188e779b33b61a4d9a0aa6c65c0982b30e17536f0d600e5d512d">+0/-84</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>generate_function.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-cdc5a67e8b6a4d3e4810329f036c2f08b062094f26d73c0133f6cfc504a45efb">+0/-24</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>graphrag_scoring.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-b4061166513ebb10c4521015d7eacae49fb9ff028140cdd880efecfe670479e6">+0/-7</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>map_question_to_schema.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-2bbd86e7db26405ed1aa0f9791e7831ea76dd5228f2d81b518d38e8183064a47">+0/-15</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>question_expansion.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-365334e8fe13fad8c4cc627217b182e92fe4e7caeedd7001e65b5ecac099265d">+0/-6</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>generate_function.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-ed98f91d4d2bb1d67ac44004e04e536d3e38b5c0c3c844887d95824c8aa13c0b">+0/-24</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>map_question_to_schema.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-40a639a159210850bc00a8861462454afaee7935b2b958ea0136456d643e63fb">+0/-15</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>chatbot_response.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-21f1aa0c6922bc07ce7afeddc5f6443258188cdf569ba16e3ab13340519e46a3">+0/-17</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>community_summarization.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-6f555d1a39a1bdc30123f90c415c072f7f3ef65c1e200cc5dfedb3aac9bd8e04">+0/-11</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>entity_relationship_extraction.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-b82782cf1fe6380df65a9d02ed7cba71d3c2ae51457c9bc31301d615cdde5b74">+0/-24</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>generate_cypher.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-6331b50f12beca6f2165960ebc6d21b349d54d03920b331f4f3d3f5efc9b1861">+0/-85</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>generate_function.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-6bc117f2b29afcf62aa14d094d48537e9ffeacd6ab2b4a8b1cd9251be736f7f1">+0/-27</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>graphrag_scoring.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-514a05e5bd58340c729dba5a29c0f37fef8ec4a40368960d2eac911849a2f025">+0/-7</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>map_question_to_schema.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-c417863ccac41f5228bcc41e4668e481dd17fb9acf371eeeb88f4be63cf6e96f">+0/-15</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>question_expansion.txt</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-fa8a5d3da2208b107766841be22024db76c1caa5454bd168b1773dc67fad94d0">+0/-6</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>image_data_extractor.py</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-a2ac78f7d21a5b6168314b1b17b8d44843350a7ddcbd9ef919cbae3e9e26b27a">+3/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>text_extractors.py</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-c749a2c8ea1a8bc0a734203aef7fa5aa9300d705006afbb4cac26985c2ac257d">+112/-43</a></td>

</tr>

<tr>
  <td><strong>ecc_util.py</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-890bb6f3c6fbe84bfda83faf66d59a1f8058f9760e9e2ee4cac1c388a90f276f">+2/-2</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>eventual_consistency_checker.py</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-dcf13e5656e90e9c903961d7d30aed679293b3e44c4f8f473ca69bead6340fb4">+4/-18</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>community_summarizer.py</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-270a6c623b596eaa5517e1fc7852ae7fc99564cf1891df7e6816f04567e09de8">+1/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>graph_rag.py</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-55a1e5b20c75c4a71f03a1541658d1a4de6567501d51550a1464f49901cb626a">+42/-10</a>&nbsp;
</td>

</tr>

<tr>
  <td><strong>util.py</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-6236f9146192c6334b6e11faf3bc998057eb7011469bb23c7f30de117bf8da87">+198/-13</a></td>

</tr>

<tr>
  <td><strong>workers.py</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-cbee2f3b2dbbc0676fa995614cd945484790f3b540b6186b8ad3ee1dd04a1165">+316/-49</a></td>

</tr>

<tr>
  <td><strong>supportai_init.py</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-0fe1ace2e4a49cc1437c1d5fb903aab7e88ef25572f3eea7737e9b6e2ea1cb26">+2/-2</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>util.py</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-42fd74ef229decb5ca5dbb3cbb461d73cf983a54e9600ce85a0d829ad505c066">+2/-2</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>workers.py</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-51486f8d7c7f1cd5e5e7271d970347522b7af672e7e324acd9a230ff917ceb38">+4/-28</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>package.json</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-c37db0061858d678c19abeadf948abe2659141efd45e288d50145960b1711f5d">+7/-0</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>SideMenu.tsx</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-529b68fc7c175654bcfa30490b22ad07bfd6b8fe5f5b693e106d3aa1c5cf02a2">+4/-3</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>Setup.tsx</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-0685e6c042b591333cecf1c93f7097f15a0028e68f5b9159028662f57957f70a">+6/-5</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>GraphRAGConfig.tsx</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-b1fb191ce371e2ece92c0d79ebc192098e126c3134a1822907321b8f0ad8b27d">+58/-0</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>KGAdmin.tsx</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-c890ce7851058e4166e4f2e8c6aa0fd6c2614618943979d6634aebcbee828041">+1068/-17</a></td>

</tr>

<tr>
  <td><strong>agent.py</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-21b6ee06c77f665fd7772366a70c1d9861d4c82cfed32bc423ac7e72607f1b19">+3/-3</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>inquiryai.py</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-daacaa5ee8ce389e0d01baa69ccfec876f2a8f94ce275f159247ff0e5aa61a44">+28/-25</a>&nbsp;
</td>

</tr>

<tr>
  <td><strong>supportai.py</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-707dd3116aa2563de518e84410cc9b3967f2e0e88eb6437ef22dba8edf786d3f">+21/-16</a>&nbsp;
</td>

</tr>

<tr>
  <td><strong>CommunityRetriever.py</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-311dd78e364927ee0ebb5e19aca562b16d6746e94ed2cf9ada02f914a695e934">+1/-1</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>SimilarityRetriever.py</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-dac21a9f8260b2fcf0ee32d10f4ebb8d9af48b1ad9aee9753fbc199cc03bd0d1">+2/-2</a>&nbsp;
&nbsp; &nbsp; </td>

</tr>

<tr>
  <td><strong>supportai_ingest.py</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-b4a80de039d3bcbf47c3bb7705354de123426efc4abd3d1f0e93570721c0f820">+11/-52</a>&nbsp;
</td>

</tr>

<tr>
  <td><strong>generate_cypher.py</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-773ac3dfe9ff4084f62ba40773d3d7ef6c1d83b1e6d83e31a951cacf763dc81d">+17/-5</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>generate_gsql.py</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-37860a9371cad295d66e69589861346e62ef79bbc2d711583003ab5474598464">+17/-5</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>conftest.py</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-b8832f424ee719b4a81f945435cfa9f84cd642472900c6669fded455044ccc82">+8/-16</a>&nbsp;
&nbsp; </td>

</tr>

<tr>
  <td><strong>test_retriever_render.py</strong></td>
<td><a
href="https://github.com/tigergraph/graphrag/pull/38/files#diff-74d715d8e46e8c7e8a7df5328275524bcc77fe9a6f8d0c609284729e91d3aac9">+177/-0</a>&nbsp;
</td>

</tr>
</table></details></td></tr></tr></tbody></table>

</details>

___
- Backfill the 1.4.0 CHANGELOG with Trace Logs, Excel / CSV ingestion,
  the default chat method flip (hybridsearch -> auto), and a
  Configuration section listing enable_router_fallback and the pnpm
  pin.
- Cache one embedding store per graphname so concurrent chat across
  different graphs doesn't race over a shared TG connection.
  reload_llm_config and reload_db_config reset the cache.
- BaseRetriever resolves the per-graph store via get_embedding_store
  instead of mutating a shared singleton.
- Pin graphrag-ui to pnpm 9 via packageManager and an .npmrc
  allow-list so image builds don't trip pnpm 10's strict approval
  policy.
- Drop the trace_logs host volume from docker-compose; traces live
  for the container's lifetime.
- Drop attribute names that collide with GSQL reserved words at parse
  time so LLM-extracted schemas no longer crash schema-change with
  "Encountered ',' ..." on names like ``count`` / ``min`` / ``max``.
- Run apply_proposal as two phases (ADD VERTEX/EDGE, then ALTER EDGE
  ADD PAIR) so TG's upfront job validator never sees an ALTER that
  references a vertex type created in the same job. Result payload
  exposes both phase names via a new ``job_names`` list; ``job_name``
  remains the first phase that ran.
- Distribute the budget across uploaded files via equal-share with
  rollover so every file contributes head sample, instead of greedy
  first-fit dropping later files when the first is large.
- Drive the budget from llm_config.token_limit when configured, and
  otherwise from a curated per-model context-window table (Claude
  family 200K / Opus 4.7 1M, GPT-4o 128K, Gemini 1.5 1M, etc.).
  Unknown models fall back to a similar family default with a warning;
  no-family-match emits a louder warning at 128K.
- Expose the budget as ``max_tokens`` on ``extract_schema_gsql`` and
  ``concatenate_samples``; characters-per-token conversion is local
  to the truncation step.
- Convert /initialize_graph to submit-then-poll so long inits no
  longer race the browser's idle-response cutoff.
- Refresh the UI's available-graphs list from the live backend so
  a graph created mid-session isn't lost when the client drops the
  success signal.
- Pause the UI idle timer during long backend calls.
- Fix two retriever queries that referenced stale vertex types,
  and stop flagging successful query installs as errors.
- Add suggested vertex and edge type chip inputs to the Initialize
  Graph dialog, with optional edge endpoint pinning. Hints guide
  the schema extractor and persist as the per-graph prompt after a
  successful initialization.
- Reject suggested type names that collide with reserved or
  structural names inline, with a clear reason.
- Expose the schema-extraction prompt on the Customize Prompts page.
- Add per-card collapse to the draft-schema review form.
- Distinguish image-description calls in the log.
- Recover when ingest is run without a cached job by seeding the
  configuration first.
- Add Query Guidance — a free-form, optional partial that the user
  edits on Customize Prompts and that injects into the four
  query-related prompts. Customize Prompts is also reordered by
  graph lifecycle.
- Stamp each image with the repo-root VERSION and a build date;
  expose them via /ui/version and a small footer on the Setup page.
- Stop aborting graph rebuilds on TigerGraph's normal success line.
- Center the Knowledge Graph Setup cards in the row.
- Make the prompt-customization E2E test revert on failure.
- Stream rebuild progress per stage with heartbeats so chunking,
  entity extraction, community detection, and mirror each surface
  in the refresh dialog.
- Demote log lines that exposed user content (entity names, chunk
  IDs, edge payloads) from INFO to DEBUG.
- Share the schema renderer across the four query tools and feed
  the same per-type descriptions to all of them.
- Keep the graph picker in sync across chat, refresh, ingest, and
  customize-prompts.
- Fix the chat WebSocket handshake when the embedding store is
  unavailable and recover stream_chunks empty-response races.
- Stop rendering raw image markdown in chat by sanitizing alt text
  on insert, and ask the image-description prompt to focus on
  content (text, charts, tables) over layout.
- Support parallel edges on the same (src,dst) via discriminator attributes
- Strengthen extraction prompt to suppress facts and values not in the source text
- Coerce LLM-emitted attributes to declared types and drop sentinel placeholders
- Raise per-type attribute caps and remove the hard upper bound on edge type count
- Add eligibility precheck and per-type description capture to the init dialog
- Expose new schema-aware knobs (strict mode, retrieval scope, sample limits)
- Replace pause/resume guard with periodic ping while upload, file
  conversion, or ingest is in flight, so the idle timer can't expire
  mid-operation when the page is a nested modal
- Include useAlert hook and AlertDialog component referenced by KGAdmin and CustomChatMessage; their absence broke fresh-checkout builds
- Drop the cache that copied a chat message into sessionStorage so the new trace tab could skip a fetch; large traces overflowed the 5MB quota and silently aborted the popup
- Show trace log in an inline dialog sized to its content instead of a new tab
- Always fetch trace data on open so messages from history render fully
- Disable Setup, side menu, and chat input while an answer is streaming
- Warn before logout while an answer streams; fix the misleading history claim
- Rename Cancel to Close on the graph initialize dialog footer
- Remove the Final Response section from the trace dialog so heavy markdown with many image references no longer blocks the dialog render
- Add accessible title and description to the trace dialog to satisfy screen-reader requirements
@tg-pr-agent
Copy link
Copy Markdown

tg-pr-agent Bot commented May 15, 2026

PR Reviewer Guide 🔍

Here are some key observations to aid the review process:

⏱️ Estimated effort to review: 5 🔵🔵🔵🔵🔵
🧪 PR contains tests
🔒 No security concerns identified
⚡ Recommended focus areas for review

Cache Race

Per-graph embedding stores are built outside the cache lock, so concurrent first-time requests for the same graph can create multiple stores and duplicate expensive initialization or installation work before one instance is discarded.

if graphname:
    with _embedding_stores_lock:
        cached = _embedding_stores.get(graphname)
        if cached is not None:
            return cached
    # Build outside the lock so first-time setup for one graph
    # doesn't serialize first-time setup for another.
    store = _build_embedding_store(graphname)
    with _embedding_stores_lock:
        existing = _embedding_stores.get(graphname)
        if existing is not None:
            return existing  # racing thread won
        _embedding_stores[graphname] = store
        return store
Atomicity Gap

The schema apply flow now runs ADD and ALTER statements in separate schema-change jobs. If the first phase succeeds and the second fails, the graph is left partially updated even though the API describes the operation as atomic.

# Split into two phases so TG's job-validator never sees an ALTER
# referencing a vertex/edge type created elsewhere in the same
# job. The ADD phase runs first; the ALTER phase (e.g. ADD PAIR
# on existing edges) runs only after the ADD phase commits.
add_stmts = [s for s in statements if s.lstrip().upper().startswith("ADD ")]
alter_stmts = [s for s in statements if s.lstrip().upper().startswith("ALTER ")]

def _run_phase(phase_stmts: List[str], phase_job: Optional[str]) -> Tuple[str, str]:
    block, name = build_schema_change_job(graphname, phase_stmts, phase_job)
    try:
        out = conn.gsql(block)
    except Exception:
        try:
            conn.gsql(f"USE GRAPH {graphname}\nDROP JOB {name}")
        except Exception:
            pass
        raise
    return out, name

# The two-phase split (ADD then ALTER) is internal mechanics; the
# user just sees a single "Applying domain schema" message that
# spans both phases plus the brief metadata upsert. The wording
# matches both schema-source paths (sample extraction and pasted
# GSQL) — "extracted" would be misleading for the paste mode.
_report("Applying domain schema")

phase_outputs: List[str] = []
phase_jobs: List[str] = []
first_job_name: Optional[str] = None
for phase_stmts in (add_stmts, alter_stmts):
    if not phase_stmts:
        continue
    # Only honor the caller-supplied job_name on the first phase that
    # actually runs; subsequent phases get auto-generated names so
    # they don't collide.
    phase_job = job_name if first_job_name is None else None
    output, ran_name = _run_phase(phase_stmts, phase_job)
    phase_outputs.append(output)
    phase_jobs.append(ran_name)
    if first_job_name is None:
        first_job_name = ran_name
    err = gsql_output_error(output)
    if err:
        try:
            conn.gsql(f"USE GRAPH {graphname}\nDROP JOB {ran_name}")
        except Exception:
            pass
        return {
            "status": "error",
            "statements": statements,
            "job_name": first_job_name,
            "job_names": phase_jobs,
            "gsql_output": "\n".join(phase_outputs),
            "error": err,
            "summary": summary,
            "metadata": {"entity_types": [], "relationship_types": []},
            "retrievers": {"status": "skipped", "reason": "schema apply failed"},
        }
Node Typing

Relationship endpoints are constructed with node type equal to the endpoint id rather than the extracted entity type, which can break downstream logic that expects relationship endpoint nodes to preserve semantic types.

relationships.append(Relationship(
    source=Node(id=rel["source"], type=rel["source"],
                properties=src_props),
    target=Node(id=rel["target"], type=rel["target"],
                properties=tgt_props),
    type=rel["type"],
    properties=edge_props,

@chengbiao-jin chengbiao-jin changed the title Release 1.4.0 GML-2022 Release 1.4.0 for schema-aware knowledge graph ingestion and query May 15, 2026
Comment thread common/db/schema_utils.py
Comment thread common/db/schema_utils.py Outdated
Comment thread graphrag/app/routers/ui.py Outdated
Comment thread graphrag/app/routers/ui.py Outdated
Comment thread graphrag/app/routers/ui.py Outdated
Comment thread common/extractors/LLMEntityRelationshipExtractor.py
Comment thread common/extractors/LLMEntityRelationshipExtractor.py
- Atomically reserve graph init state under one lock so concurrent initialize_graph requests can't enqueue duplicate background jobs
- Isolate each sample-doc upload into its own subdirectory so a new schema-extraction request can't re-process stale files from prior sessions
- Carry source / target node types through relationship extraction so endpoint-pair validation accepts valid domain edges
- Validate remote /version payloads before forwarding them so a malformed response can't change the /ui/version response shape
- Remove a stale unreachable block left behind below the build_allowed_schema alias
- Set the v1.4.0 release date on the Releases list
- Replace the obsolete "schema-aware init is on the roadmap" line with a pointer to the shipped Initialize Knowledge Graph flow
@chengbiao-jin chengbiao-jin merged commit 05765a2 into main May 16, 2026
1 check failed
@chengbiao-jin chengbiao-jin deleted the release_1.4.0 branch May 16, 2026 16:02
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.

2 participants