This is an automated email from the ASF dual-hosted git repository.

imbajin pushed a commit to branch goal-test
in repository https://gitbox.apache.org/repos/asf/hugegraph-ai.git


The following commit(s) were added to refs/heads/goal-test by this push:
     new b851072d fix(llm): address updated PR review findings
b851072d is described below

commit b851072df679f47ec3d4a7bd725af8fdd70beb2b
Author: imbajin <[email protected]>
AuthorDate: Mon Jun 1 21:39:58 2026 +0800

    fix(llm): address updated PR review findings
    
    - remove import-time repo-root probing from config paths
    - synchronize /config/llm selectors across chat/extract/text2gql
    - tighten HugeGraph smoke isolation and exact assertions
    - enforce coverage floors while keeping readable action versions
---
 .github/workflows/hugegraph-llm.yml                | 40 +++++++++----------
 .github/workflows/hugegraph-python-client.yml      | 28 +++++++-------
 .workflow/quality-program/quality-state.json       | 45 +++++++++++++++++++++-
 .../reports/final-quality-report.md                | 27 +++++++++++--
 .../reports/production-change-ledger.md            |  6 ++-
 docs/quality/coverage-ratchet.md                   | 11 ++++++
 hugegraph-llm/src/hugegraph_llm/api/rag_api.py     |  2 +
 .../src/hugegraph_llm/config/models/base_config.py | 29 +++++++++++++-
 .../config/models/base_prompt_config.py            | 16 ++++++--
 .../hugegraph_llm/demo/rag_demo/configs_block.py   |  3 +-
 hugegraph-llm/src/tests/api/test_rag_api.py        |  9 ++++-
 hugegraph-llm/src/tests/config/test_config.py      | 15 ++++++++
 hugegraph-llm/src/tests/conftest.py                | 14 +++++++
 .../src/tests/integration/test_core_kg_smoke.py    | 37 +++++++++++++++++-
 .../tests/integration/test_graph_rag_pipeline.py   |  4 ++
 .../src/tests/integration/test_kg_construction.py  |  4 ++
 .../src/tests/integration/test_rag_pipeline.py     |  4 ++
 17 files changed, 243 insertions(+), 51 deletions(-)

diff --git a/.github/workflows/hugegraph-llm.yml 
b/.github/workflows/hugegraph-llm.yml
index b73d48ac..85fe694b 100644
--- a/.github/workflows/hugegraph-llm.yml
+++ b/.github/workflows/hugegraph-llm.yml
@@ -38,22 +38,22 @@ jobs:
         python-version: ["3.10", "3.11"]
 
     steps:
-    - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
+    - uses: actions/checkout@v6
       with:
         persist-credentials: false
 
     - name: Set up Python ${{ matrix.python-version }}
-      uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065
+      uses: actions/setup-python@v6
       with:
         python-version: ${{ matrix.python-version }}
 
     - name: Install uv
-      run: |
-        curl -LsSf https://astral.sh/uv/install.sh | sh
-        echo "$HOME/.cargo/bin" >> $GITHUB_PATH
+      uses: astral-sh/setup-uv@v8
+      with:
+        version: "0.9.22"
 
     - name: Cache dependencies
-      uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830
+      uses: actions/cache@v5
       with:
         path: |
           ~/.cache/uv
@@ -71,10 +71,10 @@ jobs:
       env:
         SKIP_EXTERNAL_SERVICES: true
       run: |
-        uv run pytest hugegraph-llm/src/tests -m "unit or contract" 
--cov=hugegraph_llm --cov-report=term 
--cov-report=xml:.workflow/quality-program/coverage/llm-unit-contract.xml -q
+        uv run pytest hugegraph-llm/src/tests -m "unit or contract" 
--cov=hugegraph_llm --cov-fail-under=34 --cov-report=term 
--cov-report=xml:.workflow/quality-program/coverage/llm-unit-contract.xml -q
 
     - name: Upload coverage artifact
-      uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
+      uses: actions/upload-artifact@v7
       with:
         name: llm-unit-contract-coverage-${{ matrix.python-version }}
         path: .workflow/quality-program/coverage/llm-unit-contract.xml
@@ -97,22 +97,22 @@ jobs:
           - 8080:8080
 
     steps:
-    - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
+    - uses: actions/checkout@v6
       with:
         persist-credentials: false
 
     - name: Set up Python ${{ matrix.python-version }}
-      uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065
+      uses: actions/setup-python@v6
       with:
         python-version: ${{ matrix.python-version }}
 
     - name: Install uv
-      run: |
-        curl -LsSf https://astral.sh/uv/install.sh | sh
-        echo "$HOME/.cargo/bin" >> $GITHUB_PATH
+      uses: astral-sh/setup-uv@v8
+      with:
+        version: "0.9.22"
 
     - name: Cache dependencies
-      uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830
+      uses: actions/cache@v5
       with:
         path: |
           ~/.cache/uv
@@ -154,22 +154,22 @@ jobs:
           - 8080:8080
 
     steps:
-    - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
+    - uses: actions/checkout@v6
       with:
         persist-credentials: false
 
     - name: Set up Python ${{ matrix.python-version }}
-      uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065
+      uses: actions/setup-python@v6
       with:
         python-version: ${{ matrix.python-version }}
 
     - name: Install uv
-      run: |
-        curl -LsSf https://astral.sh/uv/install.sh | sh
-        echo "$HOME/.cargo/bin" >> $GITHUB_PATH
+      uses: astral-sh/setup-uv@v8
+      with:
+        version: "0.9.22"
 
     - name: Cache dependencies
-      uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830
+      uses: actions/cache@v5
       with:
         path: |
           ~/.cache/uv
diff --git a/.github/workflows/hugegraph-python-client.yml 
b/.github/workflows/hugegraph-python-client.yml
index 9017b69e..1a34bdd5 100644
--- a/.github/workflows/hugegraph-python-client.yml
+++ b/.github/workflows/hugegraph-python-client.yml
@@ -19,23 +19,23 @@ jobs:
         python-version: ["3.10", "3.11", "3.12"]
 
     steps:
-      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
+      - uses: actions/checkout@v6
         with:
           persist-credentials: false
 
       - name: Set up Python ${{ matrix.python-version }}
-        uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065
+        uses: actions/setup-python@v6
         with:
           python-version: ${{ matrix.python-version }}
 
       - name: Install uv
-        run: |
-          curl -LsSf https://astral.sh/uv/install.sh | sh
-          echo "$HOME/.cargo/bin" >> $GITHUB_PATH
+        uses: astral-sh/setup-uv@v8
+        with:
+          version: "0.9.22"
 
       - name: Cache dependencies
         id: cache-deps
-        uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830
+        uses: actions/cache@v5
         with:
           path: |
             ~/.cache/uv
@@ -49,10 +49,10 @@ jobs:
 
       - name: Run unit and contract tests
         run: |
-          uv run pytest hugegraph-python-client/src/tests -m "unit or 
contract" --cov=pyhugegraph --cov-report=term 
--cov-report=xml:.workflow/quality-program/coverage/client-unit-contract.xml -q
+          uv run pytest hugegraph-python-client/src/tests -m "unit or 
contract" --cov=pyhugegraph --cov-fail-under=45 --cov-report=term 
--cov-report=xml:.workflow/quality-program/coverage/client-unit-contract.xml -q
 
       - name: Upload coverage artifact
-        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02
+        uses: actions/upload-artifact@v7
         with:
           name: client-unit-contract-coverage-${{ matrix.python-version }}
           path: .workflow/quality-program/coverage/client-unit-contract.xml
@@ -75,23 +75,23 @@ jobs:
           - 8080:8080
 
     steps:
-      - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5
+      - uses: actions/checkout@v6
         with:
           persist-credentials: false
 
       - name: Set up Python ${{ matrix.python-version }}
-        uses: actions/setup-python@a26af69be951a213d495a4c3e4e4022e16d87065
+        uses: actions/setup-python@v6
         with:
           python-version: ${{ matrix.python-version }}
 
       - name: Install uv
-        run: |
-          curl -LsSf https://astral.sh/uv/install.sh | sh
-          echo "$HOME/.cargo/bin" >> $GITHUB_PATH
+        uses: astral-sh/setup-uv@v8
+        with:
+          version: "0.9.22"
 
       - name: Cache dependencies
         id: cache-deps
-        uses: actions/cache@0057852bfaa89a56745cba8c7296529d2fc39830
+        uses: actions/cache@v5
         with:
           path: |
             ~/.cache/uv
diff --git a/.workflow/quality-program/quality-state.json 
b/.workflow/quality-program/quality-state.json
index c3fd5b4b..28de62ba 100644
--- a/.workflow/quality-program/quality-state.json
+++ b/.workflow/quality-program/quality-state.json
@@ -78,6 +78,9 @@
     "hugegraph-llm/src/tests/operators/hugegraph_op/test_fetch_graph_data.py",
     "hugegraph-llm/src/tests/operators/hugegraph_op/test_schema_manager.py",
     "hugegraph-llm/src/hugegraph_llm/api/rag_api.py",
+    "hugegraph-llm/src/hugegraph_llm/config/models/base_config.py",
+    "hugegraph-llm/src/hugegraph_llm/config/models/base_prompt_config.py",
+    "hugegraph-llm/src/hugegraph_llm/demo/rag_demo/configs_block.py",
     "hugegraph-llm/src/tests/fixtures/fake_llm.py",
     "hugegraph-llm/src/tests/models/embeddings/test_ollama_embedding.py",
     "hugegraph-llm/src/tests/data/quality_program/kg_text.txt",
@@ -87,6 +90,9 @@
     "hugegraph-llm/src/tests/integration/test_core_kg_smoke.py",
     "hugegraph-llm/src/tests/integration/test_core_graphrag_smoke.py",
     "hugegraph-llm/src/tests/integration/test_core_text2gremlin_smoke.py",
+    "hugegraph-llm/src/tests/integration/test_graph_rag_pipeline.py",
+    "hugegraph-llm/src/tests/integration/test_kg_construction.py",
+    "hugegraph-llm/src/tests/integration/test_rag_pipeline.py",
     "docs/quality/coverage-ratchet.md",
     ".workflow/quality-program/coverage/combined-baseline.json",
     ".workflow/quality-program/checkpoints/07-coverage-ratchet.md",
@@ -112,6 +118,30 @@
       "file": "hugegraph-llm/src/hugegraph_llm/api/rag_api.py",
       "change": "Map /config/llm to llm_settings.chat_llm_type instead of 
nonexistent llm_settings.llm_type.",
       "test": "uv run pytest hugegraph-llm/src/tests/api -m 'unit or contract' 
-v --tb=short"
+    },
+    {
+      "goal": "PR68 updated review",
+      "file": "hugegraph-llm/src/hugegraph_llm/config/models/base_config.py",
+      "change": "Resolve .env through HUGEGRAPH_LLM_ENV_PATH, source-tree 
module root, then cwd fallback without import-time repository-root probing.",
+      "test": "uv run pytest hugegraph-llm/src/tests/config/test_config.py -q"
+    },
+    {
+      "goal": "PR68 updated review",
+      "file": 
"hugegraph-llm/src/hugegraph_llm/config/models/base_prompt_config.py",
+      "change": "Resolve prompt config YAML through package resources with a 
module-relative fallback.",
+      "test": "uv run pytest hugegraph-llm/src/tests/config/test_config.py -q"
+    },
+    {
+      "goal": "PR68 updated review",
+      "file": "hugegraph-llm/src/hugegraph_llm/api/rag_api.py",
+      "change": "Keep /config/llm as one endpoint and synchronize chat, 
extract, and Text2Gremlin LLM selectors.",
+      "test": "uv run pytest hugegraph-llm/src/tests/api/test_rag_api.py -q"
+    },
+    {
+      "goal": "PR68 updated review",
+      "file": "hugegraph-llm/src/hugegraph_llm/demo/rag_demo/configs_block.py",
+      "change": "Reuse the shared .env path from base_config for Gradio LLM 
config propagation.",
+      "test": "uv run pytest hugegraph-llm/src/tests/config/test_config.py -q"
     }
   ],
   "tests_added_or_changed": [
@@ -125,7 +155,10 @@
     "Added FakeLLM fixture and deterministic parser/operator tests for 
property graph, keyword, and Gremlin generation contracts.",
     "Added API public-surface tests for config field mapping, invalid request 
bodies, and callback exception responses.",
     "Added provider wrapper tests for OpenAI, LiteLLM, and Ollama 
malformed/error surfaces.",
-    "Added deterministic KG, GraphRAG, and Text2Gremlin smoke tests that 
import production code."
+    "Added deterministic KG, GraphRAG, and Text2Gremlin smoke tests that 
import production code.",
+    "Tightened KG smoke assertions to exact vertex and edge contents after 
fixture cleanup.",
+    "Marked legacy mock-only integration suites as external and slow so 
default gates do not silently leave ambiguous integration files outside the 
selected layers.",
+    "Added config/API regression tests for package-relative config resolution, 
shared demo .env path, and /config/llm selector synchronization."
   ],
   "commands_run": [
     "sed -n '1,220p' AGENTS.md",
@@ -212,7 +245,15 @@
     "placeholder scan over .workflow/quality-program docs/quality",
     "git status --short",
     "uv run ruff format --check .",
-    "uv run ruff check ."
+    "uv run ruff check .",
+    "uv run pytest hugegraph-llm/src/tests/config/test_config.py 
hugegraph-llm/src/tests/api/test_rag_api.py -q",
+    "uv run pytest hugegraph-python-client/src/tests -m \"unit or contract\" 
--cov=pyhugegraph --cov-fail-under=45 --cov-report=term 
--cov-report=xml:.workflow/quality-program/coverage/client-unit-contract.xml 
-q",
+    "uv run pytest hugegraph-llm/src/tests -m \"unit or contract\" 
--cov=hugegraph_llm --cov-fail-under=34 --cov-report=term 
--cov-report=xml:.workflow/quality-program/coverage/llm-unit-contract.xml -q",
+    "uv run python -c \"import yaml, pathlib; 
[yaml.safe_load(pathlib.Path(p).read_text()) for p in 
['.github/workflows/hugegraph-llm.yml','.github/workflows/hugegraph-python-client.yml']]\"",
+    "HUGEGRAPH_REQUIRED=true HUGEGRAPH_URL=http://127.0.0.1:18080 
HUGEGRAPH_PASSWORD=admin uv run pytest 
hugegraph-llm/src/tests/integration/test_hugegraph_boundary.py 
hugegraph-llm/src/tests/integration/test_core_kg_smoke.py -v --tb=short",
+    "HUGEGRAPH_REQUIRED=true HUGEGRAPH_URL=http://127.0.0.1:18080 
HUGEGRAPH_PASSWORD=admin uv run pytest hugegraph-llm/src/tests -m \"integration 
and hugegraph\" -v --tb=short",
+    "HUGEGRAPH_REQUIRED=true HUGEGRAPH_URL=http://127.0.0.1:18080 
HUGEGRAPH_PASSWORD=admin uv run pytest hugegraph-llm/src/tests/integration -m 
\"smoke\" -v --tb=short",
+    "uv run pytest hugegraph-llm/src/tests/integration -m 'smoke and not 
hugegraph' -v --tb=short"
   ],
   "known_failures": [],
   "deferred_items": [
diff --git a/.workflow/quality-program/reports/final-quality-report.md 
b/.workflow/quality-program/reports/final-quality-report.md
index 2906638e..a4a0c012 100644
--- a/.workflow/quality-program/reports/final-quality-report.md
+++ b/.workflow/quality-program/reports/final-quality-report.md
@@ -25,6 +25,14 @@ Layer D  external       opt-in only, not default PR gates
 | Formatting | workspace | `uv run ruff format --check .` | 342 files already 
formatted |
 | Lint | workspace | `uv run ruff check .` | all checks passed |
 
+Post-PR68 updated-review verification:
+
+| Layer | Module | Command | Result |
+|---|---|---|---|
+| Layer A | `hugegraph-llm` config/API contracts | `uv run pytest 
hugegraph-llm/src/tests/config/test_config.py 
hugegraph-llm/src/tests/api/test_rag_api.py -q` | 11 passed |
+| Layer B/C | `hugegraph-llm` HugeGraph boundary + KG smoke | 
`HUGEGRAPH_REQUIRED=true HUGEGRAPH_URL=http://127.0.0.1:18080 
HUGEGRAPH_PASSWORD=admin uv run pytest 
hugegraph-llm/src/tests/integration/test_hugegraph_boundary.py 
hugegraph-llm/src/tests/integration/test_core_kg_smoke.py -v --tb=short` | 5 
passed |
+| Layer C | `hugegraph-llm` non-HugeGraph smoke | `uv run pytest 
hugegraph-llm/src/tests/integration -m "smoke and not hugegraph" -v --tb=short` 
| 3 passed, 16 deselected |
+
 ## Coverage Baseline and Ratchets
 
 Baseline artifacts:
@@ -37,6 +45,15 @@ Baseline artifacts:
 
 The combined baseline required `--import-mode=importlib` because both 
workspace packages expose `tests.conftest` during cross-package collection.
 
+CI now enforces the initial module floors in the default unit/contract jobs:
+
+| Workflow | Coverage gate |
+|---|---:|
+| `.github/workflows/hugegraph-python-client.yml` | `--cov-fail-under=45` |
+| `.github/workflows/hugegraph-llm.yml` | `--cov-fail-under=34` |
+
+Final local gate results: `pyhugegraph` reached 45.34%; `hugegraph_llm` 
reached 39.41%.
+
 Initial ratchet areas are documented in `docs/quality/coverage-ratchet.md`:
 
 - `pyhugegraph`
@@ -75,9 +92,11 @@ Final G7 sanity checks:
 | G3 | 
`hugegraph-llm/src/hugegraph_llm/operators/hugegraph_op/commit_to_hugegraph.py` 
| Map primary-key `label:value` edge endpoints to server-created VIDs and raise 
explicit vertex creation errors. | `uv run pytest 
hugegraph-llm/src/tests/operators/hugegraph_op/test_commit_to_hugegraph.py::TestCommit2Graph::test_load_into_graph_raises_explicit_error_when_vertex_creation_fails
 -q`; `HUGEGRAPH_REQUIRED=true uv run pytest 
hugegraph-llm/src/tests/integration/test_hugegraph_boundary.py -v - [...]
 | G4 | `hugegraph-llm/src/hugegraph_llm/api/rag_api.py` | Map `/config/llm` to 
`llm_settings.chat_llm_type`. | `uv run pytest hugegraph-llm/src/tests/api -m 
"unit or contract" -v --tb=short` |
 | PR68 review | 
`hugegraph-llm/src/hugegraph_llm/operators/hugegraph_op/commit_to_hugegraph.py` 
| Extend primary-key endpoint mapping to multi-key vertex labels. | `uv run 
pytest 
hugegraph-llm/src/tests/operators/hugegraph_op/test_commit_to_hugegraph_load_into_graph.py
 -q` |
-| PR68 review | 
`hugegraph-llm/src/hugegraph_llm/config/models/base_prompt_config.py` | Resolve 
prompt config YAML from the package project root instead of process cwd. | `uv 
run pytest hugegraph-llm/src/tests/config/test_config.py -q` |
-| PR68 review | `hugegraph-llm/src/hugegraph_llm/config/models/base_config.py` 
| Resolve `.env` from the package project root instead of process cwd. | `uv 
run pytest hugegraph-llm/src/tests/config/test_config.py -q` |
+| PR68 review | 
`hugegraph-llm/src/hugegraph_llm/config/models/base_prompt_config.py` | Resolve 
prompt config YAML from package resources with module-relative fallback, 
avoiding repository-root probing at import time. | `uv run pytest 
hugegraph-llm/src/tests/config/test_config.py -q` |
+| PR68 review | `hugegraph-llm/src/hugegraph_llm/config/models/base_config.py` 
| Resolve `.env` from explicit override, source-tree module root, then cwd 
fallback, avoiding repository-root probing at import time. | `uv run pytest 
hugegraph-llm/src/tests/config/test_config.py -q` |
 | PR68 second review | `hugegraph-python-client/src/pyhugegraph/utils/util.py` 
| Preserve `NotAuthorizedError` for 401 responses in `ResponseValidation`. | 
`uv run pytest 
hugegraph-python-client/src/tests/api/test_response_validation.py -q` |
+| PR68 updated review | `hugegraph-llm/src/hugegraph_llm/api/rag_api.py` | 
Synchronize `/config/llm` across chat, extraction, and Text2Gremlin selectors. 
| `uv run pytest hugegraph-llm/src/tests/api/test_rag_api.py -q` |
+| PR68 updated review | 
`hugegraph-llm/src/hugegraph_llm/demo/rag_demo/configs_block.py` | Reuse the 
shared `.env` path helper for Gradio config propagation. | `uv run pytest 
hugegraph-llm/src/tests/config/test_config.py -q` |
 
 No production code changed in G5-G7. PR68 review fixes added the 
production-code rows above.
 
@@ -87,7 +106,8 @@ No production code changed in G5-G7. PR68 review fixes added 
the production-code
 - Two LLM model tests remain skipped inside the Layer A selection; they are 
explicit pytest skips, not service-bound silent skips.
 - Layer B commands used local HugeGraph `hugegraph/hugegraph:1.7.0` and 
`HUGEGRAPH_REQUIRED=true`.
 - GraphRAG smoke emits known NLTK BLEU zero-overlap warnings for short 
deterministic strings; assertions do not depend on BLEU score value.
-- Legacy mock-only integration tests remain documented as future cleanup. New 
authoritative smoke tests import production code.
+- Legacy mock-only integration tests are explicitly marked `external` and 
`slow`. New authoritative smoke tests import production code.
+- Local `hugegraph-quality` on port 8080 returned 401 for `admin/admin` 
despite `PASSWORD=admin`; updated-review Layer B/C verification used the 
preserved fresh HugeGraph 1.7.0 container on port 18080 instead.
 
 ## Deferred Refactors
 
@@ -107,6 +127,7 @@ Deferred items are documented in 
`.workflow/quality-program/reports/deferred-ref
 - HugeGraph integration jobs use `hugegraph/hugegraph:1.7.0` and selected 
integration tests fail when the required service is unavailable.
 - Smoke tests are deterministic and exercise production code at KG, GraphRAG, 
and Text2Gremlin boundaries.
 - Coverage ratchets start from local areas instead of imposing a 
full-repository threshold.
+- GitHub Actions are kept on readable official major-version tags 
(`actions/checkout@v6`, `actions/setup-python@v6`, `actions/cache@v5`, 
`actions/upload-artifact@v7`, `astral-sh/setup-uv@v8`) per maintainer 
preference; SHA-pinning review feedback is intentionally not adopted.
 
 ## Recommended Next Actions
 
diff --git a/.workflow/quality-program/reports/production-change-ledger.md 
b/.workflow/quality-program/reports/production-change-ledger.md
index 5684375a..71267361 100644
--- a/.workflow/quality-program/reports/production-change-ledger.md
+++ b/.workflow/quality-program/reports/production-change-ledger.md
@@ -6,6 +6,8 @@
 | G3 | 
`hugegraph-llm/src/hugegraph_llm/operators/hugegraph_op/commit_to_hugegraph.py` 
| Map primary-key `label:value` edge endpoints to server-created VIDs and raise 
explicit vertex creation errors before accessing `.id`. | `uv run pytest 
hugegraph-llm/src/tests/operators/hugegraph_op/test_commit_to_hugegraph.py::TestCommit2Graph::test_load_into_graph_raises_explicit_error_when_vertex_creation_fails
 -q`; `HUGEGRAPH_REQUIRED=true uv run pytest 
hugegraph-llm/src/tests/integration/test_hug [...]
 | G4 | `hugegraph-llm/src/hugegraph_llm/api/rag_api.py` | Map `/config/llm` to 
existing `llm_settings.chat_llm_type` instead of nonexistent 
`llm_settings.llm_type`. | `uv run pytest hugegraph-llm/src/tests/api -m "unit 
or contract" -v --tb=short` | API public-surface field mapping contract gap. | 
Low; aligns route with existing config schema and leaves callback arguments 
unchanged. |
 | PR68 review | 
`hugegraph-llm/src/hugegraph_llm/operators/hugegraph_op/commit_to_hugegraph.py` 
| Extend primary-key endpoint mapping to multi-key vertex labels by joining 
primary key values with `!`. | `uv run pytest 
hugegraph-llm/src/tests/operators/hugegraph_op/test_commit_to_hugegraph_load_into_graph.py
 -q` | Review-identified edge creation gap for multiple primary-key vertex IDs. 
| Low; only broadens fallback mapping for existing primary-key schemas. |
-| PR68 review | 
`hugegraph-llm/src/hugegraph_llm/config/models/base_prompt_config.py` | Resolve 
prompt config YAML from the package project root instead of process cwd. | `uv 
run pytest hugegraph-llm/src/tests/config/test_config.py -q` | Avoid 
import-time cwd mutation in test harness and make config path deterministic. | 
Medium-low; preserves the same file path when run from module root and removes 
cwd guard. |
-| PR68 review | `hugegraph-llm/src/hugegraph_llm/config/models/base_config.py` 
| Resolve `.env` from the package project root instead of process cwd. | `uv 
run pytest hugegraph-llm/src/tests/config/test_config.py -q` | Avoid writing or 
reading a caller cwd `.env` when tests import config from repo root. | 
Medium-low; preserves the same `.env` file when run from module root and 
removes cwd coupling. |
+| PR68 review | 
`hugegraph-llm/src/hugegraph_llm/config/models/base_prompt_config.py` | Resolve 
prompt config YAML through package resources with a module-relative fallback, 
avoiding import-time repository-root probing. | `uv run pytest 
hugegraph-llm/src/tests/config/test_config.py -q` | Review-identified 
packaged/vendored import failure when no parent `pyproject.toml` or `.git` 
exists. | Medium-low; preserves the source-tree path and removes 
`get_project_root()` from import-time prompt  [...]
+| PR68 review | `hugegraph-llm/src/hugegraph_llm/config/models/base_config.py` 
| Resolve `.env` through `HUGEGRAPH_LLM_ENV_PATH`, source-tree module root, 
then process cwd fallback, avoiding import-time repository-root probing. | `uv 
run pytest hugegraph-llm/src/tests/config/test_config.py -q` | 
Review-identified packaged/vendored import failure when no parent 
`pyproject.toml` or `.git` exists. | Medium-low; preserves source-tree `.env` 
behavior while allowing explicit installed-layout o [...]
 | PR68 second review | `hugegraph-python-client/src/pyhugegraph/utils/util.py` 
| Preserve `NotAuthorizedError` for 401 responses in `ResponseValidation` while 
keeping backend error-envelope details for other HTTP errors. | `uv run pytest 
hugegraph-python-client/src/tests/api/test_response_validation.py -q` | 
Second-review finding that the G2 envelope preservation broadened 401 responses 
to generic `Exception`. | Low; restores the existing 401 contract and removes 
dead HTTPError fallback code. |
+| PR68 updated review | `hugegraph-llm/src/hugegraph_llm/api/rag_api.py` | 
Keep `/config/llm` as a single endpoint and synchronize `chat_llm_type`, 
`extract_llm_type`, and `text2gql_llm_type`. | `uv run pytest 
hugegraph-llm/src/tests/api/test_rag_api.py -q` | Review-identified runtime 
regression where extractor and Text2Gremlin LLM selectors kept stale provider 
values. | Medium-low; preserves current single-endpoint API contract and only 
broadens selector synchronization. |
+| PR68 updated review | 
`hugegraph-llm/src/hugegraph_llm/demo/rag_demo/configs_block.py` | Reuse the 
shared `.env` path from `base_config` when deciding whether chat settings 
should propagate to mini-task LLM settings. | `uv run pytest 
hugegraph-llm/src/tests/config/test_config.py -q` | Review-identified 
config-surface mismatch between API/config model and Gradio UI. | Low; removes 
cwd-specific `.env` lookup from the demo config UI. |
diff --git a/docs/quality/coverage-ratchet.md b/docs/quality/coverage-ratchet.md
index 17c83d0f..8251cb13 100644
--- a/docs/quality/coverage-ratchet.md
+++ b/docs/quality/coverage-ratchet.md
@@ -33,6 +33,17 @@ Current combined baseline:
 
 The original combined command hits a pytest import-path collision because both 
workspace packages define a `tests.conftest` module. Use 
`--import-mode=importlib` for combined workspace baselines until the test 
package layout is normalized.
 
+## CI Gates
+
+The default unit/contract jobs enforce module-level floors from the initial 
baseline artifacts:
+
+| Workflow | Scope | Gate |
+|---|---|---:|
+| `.github/workflows/hugegraph-python-client.yml` | `pyhugegraph` 
unit/contract | `--cov-fail-under=45` |
+| `.github/workflows/hugegraph-llm.yml` | `hugegraph_llm` unit/contract | 
`--cov-fail-under=34` |
+
+These gates are intentionally baseline-level floors. Raise them only after the 
corresponding local ratchet areas gain meaningful tests.
+
 ## Local Commands
 
 ```bash
diff --git a/hugegraph-llm/src/hugegraph_llm/api/rag_api.py 
b/hugegraph-llm/src/hugegraph_llm/api/rag_api.py
index bce7de0d..4f5a80c3 100644
--- a/hugegraph-llm/src/hugegraph_llm/api/rag_api.py
+++ b/hugegraph-llm/src/hugegraph_llm/api/rag_api.py
@@ -162,6 +162,8 @@ def rag_http_api(
     @router.post("/config/llm", status_code=status.HTTP_201_CREATED)
     def llm_config_api(req: LLMConfigRequest):
         llm_settings.chat_llm_type = req.llm_type
+        llm_settings.extract_llm_type = req.llm_type
+        llm_settings.text2gql_llm_type = req.llm_type
 
         if req.llm_type == "openai":
             res = apply_llm_conf(
diff --git a/hugegraph-llm/src/hugegraph_llm/config/models/base_config.py 
b/hugegraph-llm/src/hugegraph_llm/config/models/base_config.py
index 6953166b..0e5ca609 100644
--- a/hugegraph-llm/src/hugegraph_llm/config/models/base_config.py
+++ b/hugegraph-llm/src/hugegraph_llm/config/models/base_config.py
@@ -17,15 +17,40 @@
 
 
 import os
+from pathlib import Path
 
 from dotenv import dotenv_values, set_key
 from pydantic_settings import BaseSettings
 
-from hugegraph_llm.utils.anchor import get_project_root
 from hugegraph_llm.utils.log import log
 
 dir_name = os.path.dirname
-env_path = os.path.join(get_project_root(), ".env")
+ENV_PATH_ENV_VAR = "HUGEGRAPH_LLM_ENV_PATH"
+
+
+def _source_project_root() -> Path | None:
+    package_root = Path(__file__).resolve().parents[2]
+    if package_root.parent.name != "src":
+        return None
+    project_root = package_root.parent.parent
+    if (project_root / "pyproject.toml").exists():
+        return project_root
+    return None
+
+
+def resolve_env_path() -> str:
+    explicit_env_path = os.getenv(ENV_PATH_ENV_VAR)
+    if explicit_env_path:
+        return str(Path(explicit_env_path).expanduser())
+
+    project_root = _source_project_root()
+    if project_root is not None:
+        return str(project_root / ".env")
+
+    return str(Path.cwd() / ".env")
+
+
+env_path = resolve_env_path()
 
 
 class BaseConfig(BaseSettings):
diff --git 
a/hugegraph-llm/src/hugegraph_llm/config/models/base_prompt_config.py 
b/hugegraph-llm/src/hugegraph_llm/config/models/base_prompt_config.py
index b7cd2f91..feab61b3 100644
--- a/hugegraph-llm/src/hugegraph_llm/config/models/base_prompt_config.py
+++ b/hugegraph-llm/src/hugegraph_llm/config/models/base_prompt_config.py
@@ -16,16 +16,26 @@
 # under the License.
 
 import os
+from importlib import resources
+from pathlib import Path
 
 import yaml
 
-from hugegraph_llm.utils.anchor import get_project_root
 from hugegraph_llm.utils.log import log
 
 dir_name = os.path.dirname
 F_NAME = "config_prompt.yaml"
-PROJECT_ROOT = get_project_root()
-yaml_file_path = os.path.join(PROJECT_ROOT, 
"src/hugegraph_llm/resources/demo", F_NAME)
+
+
+def resolve_prompt_yaml_path() -> str:
+    try:
+        return 
str(resources.files("hugegraph_llm.resources.demo").joinpath(F_NAME))
+    except (ModuleNotFoundError, TypeError):
+        package_root = Path(__file__).resolve().parents[2]
+        return str(package_root / "resources" / "demo" / F_NAME)
+
+
+yaml_file_path = resolve_prompt_yaml_path()
 
 
 class LiteralStr(str):
diff --git a/hugegraph-llm/src/hugegraph_llm/demo/rag_demo/configs_block.py 
b/hugegraph-llm/src/hugegraph_llm/demo/rag_demo/configs_block.py
index 72c1eec0..0b51aa6c 100644
--- a/hugegraph-llm/src/hugegraph_llm/demo/rag_demo/configs_block.py
+++ b/hugegraph-llm/src/hugegraph_llm/demo/rag_demo/configs_block.py
@@ -16,7 +16,6 @@
 # under the License.
 
 import json
-import os
 from functools import partial
 from typing import Optional
 
@@ -26,6 +25,7 @@ from dotenv import dotenv_values
 from requests.auth import HTTPBasicAuth
 
 from hugegraph_llm.config import huge_settings, index_settings, llm_settings
+from hugegraph_llm.config.models.base_config import env_path
 from hugegraph_llm.models.embeddings.litellm import LiteLLMEmbedding
 from hugegraph_llm.models.llms.litellm import LiteLLMClient
 from hugegraph_llm.utils.log import log
@@ -429,7 +429,6 @@ def create_configs_block() -> list:
                 llm_config_button = gr.Button("Apply configuration")
                 llm_config_button.click(apply_llm_config_with_chat_op, 
inputs=llm_config_input)
                 # Determine whether there are Settings in the.env file
-                env_path = os.path.join(os.getcwd(), ".env")  # Load .env from 
the current working directory
                 env_vars = dotenv_values(env_path)
                 api_extract_key = env_vars.get("OPENAI_EXTRACT_API_KEY")
                 api_text2sql_key = env_vars.get("OPENAI_TEXT2GQL_API_KEY")
diff --git a/hugegraph-llm/src/tests/api/test_rag_api.py 
b/hugegraph-llm/src/tests/api/test_rag_api.py
index 336216fb..0bed3174 100644
--- a/hugegraph-llm/src/tests/api/test_rag_api.py
+++ b/hugegraph-llm/src/tests/api/test_rag_api.py
@@ -22,6 +22,7 @@ from fastapi import APIRouter, FastAPI, status
 from fastapi.testclient import TestClient
 
 from hugegraph_llm.api.rag_api import rag_http_api
+from hugegraph_llm.config import llm_settings
 
 pytestmark = pytest.mark.contract
 
@@ -83,7 +84,10 @@ def 
test_graph_config_api_passes_graph_field_to_apply_graph_conf():
     )
 
 
-def test_llm_config_api_passes_openai_fields_to_apply_llm_conf():
+def test_llm_config_api_passes_openai_fields_to_apply_llm_conf(monkeypatch):
+    monkeypatch.setattr(llm_settings, "chat_llm_type", "ollama/local")
+    monkeypatch.setattr(llm_settings, "extract_llm_type", "ollama/local")
+    monkeypatch.setattr(llm_settings, "text2gql_llm_type", "ollama/local")
     client, callbacks = _make_test_client()
 
     response = client.post(
@@ -97,6 +101,9 @@ def 
test_llm_config_api_passes_openai_fields_to_apply_llm_conf():
         },
     )
 
+    assert llm_settings.chat_llm_type == "openai"
+    assert llm_settings.extract_llm_type == "openai"
+    assert llm_settings.text2gql_llm_type == "openai"
     assert response.status_code == status.HTTP_201_CREATED
     assert response.json() == {"message": "Connection successful. Configured 
finished."}
     callbacks["apply_llm_conf"].assert_called_once_with(
diff --git a/hugegraph-llm/src/tests/config/test_config.py 
b/hugegraph-llm/src/tests/config/test_config.py
index b5569a8f..e407194e 100644
--- a/hugegraph-llm/src/tests/config/test_config.py
+++ b/hugegraph-llm/src/tests/config/test_config.py
@@ -17,7 +17,9 @@
 
 
 import unittest
+from os import environ
 from pathlib import Path
+from unittest.mock import patch
 
 import pytest
 
@@ -44,3 +46,16 @@ class TestConfig(unittest.TestCase):
 
         expected = Path(__file__).resolve().parents[3] / ".env"
         self.assertEqual(Path(base_config.env_path), expected)
+
+    def test_env_path_prefers_explicit_override(self):
+        from hugegraph_llm.config.models import base_config
+
+        custom_env = Path("/tmp/hugegraph-llm-test.env")
+        with patch.dict(environ, {base_config.ENV_PATH_ENV_VAR: 
str(custom_env)}):
+            self.assertEqual(Path(base_config.resolve_env_path()), custom_env)
+
+    def test_demo_config_block_uses_shared_env_path(self):
+        from hugegraph_llm.config.models import base_config
+        from hugegraph_llm.demo.rag_demo import configs_block
+
+        self.assertEqual(configs_block.env_path, base_config.env_path)
diff --git a/hugegraph-llm/src/tests/conftest.py 
b/hugegraph-llm/src/tests/conftest.py
index a8764547..a330280f 100644
--- a/hugegraph-llm/src/tests/conftest.py
+++ b/hugegraph-llm/src/tests/conftest.py
@@ -18,6 +18,7 @@
 import logging
 import os
 import sys
+from contextlib import suppress
 
 import nltk
 import pytest
@@ -36,6 +37,17 @@ from fixtures.hugegraph_service import hugegraph_service  # 
noqa: E402
 __all__ = ["hugegraph_client", "hugegraph_service"]
 
 
+def _clear_quality_schema(client):
+    schema = client.schema()
+    for remove in (
+        lambda: schema.edgeLabel("quality_created").remove(),
+        lambda: schema.vertexLabel("quality_software").remove(),
+        lambda: schema.vertexLabel("quality_person").remove(),
+    ):
+        with suppress(Exception):
+            remove()
+
+
 @pytest.fixture()
 def hugegraph_client(hugegraph_service):
     from pyhugegraph.client import PyHugeClient
@@ -63,11 +75,13 @@ def hugegraph_client(hugegraph_service):
         graphspace=hugegraph_service.graphspace,
     )
     client.graphs().clear_graph_all_data()
+    _clear_quality_schema(client)
     try:
         yield client
     finally:
         try:
             client.graphs().clear_graph_all_data()
+            _clear_quality_schema(client)
         finally:
             for key, value in original.items():
                 setattr(huge_settings, key, value)
diff --git a/hugegraph-llm/src/tests/integration/test_core_kg_smoke.py 
b/hugegraph-llm/src/tests/integration/test_core_kg_smoke.py
index ed505921..2824a9f5 100644
--- a/hugegraph-llm/src/tests/integration/test_core_kg_smoke.py
+++ b/hugegraph-llm/src/tests/integration/test_core_kg_smoke.py
@@ -71,5 +71,38 @@ def 
test_kg_construction_smoke_uses_production_code(hugegraph_client):
     Commit2Graph().run(data)
 
     summary = FetchGraphData(hugegraph_client).run({})
-    assert summary["vertex_num"] >= len(fixture["vertices"])
-    assert summary["edge_num"] >= len(fixture["edges"])
+    vertices = hugegraph_client.gremlin().exec(
+        """
+        g.V().hasLabel('quality_person', 'quality_software').
+          project('label', 'name', 'age', 'lang').
+          by(label()).
+          by(values('name')).
+          by(coalesce(values('age'), constant(null))).
+          by(coalesce(values('lang'), constant(null)))
+        """
+    )["data"]
+    edges = hugegraph_client.gremlin().exec(
+        """
+        g.E().hasLabel('quality_created').
+          project('label', 'out', 'in', 'date').
+          by(label()).
+          by(outV().values('name')).
+          by(inV().values('name')).
+          by(values('date'))
+        """
+    )["data"]
+
+    assert summary["vertex_num"] == len(fixture["vertices"])
+    assert summary["edge_num"] == len(fixture["edges"])
+    assert sorted(vertices, key=lambda item: item["label"]) == [
+        {"label": "quality_person", "name": "marko", "age": 29, "lang": None},
+        {"label": "quality_software", "name": "lop", "age": None, "lang": 
"java"},
+    ]
+    assert edges == [
+        {
+            "label": "quality_created",
+            "out": "marko",
+            "in": "lop",
+            "date": "2026-05-31",
+        }
+    ]
diff --git a/hugegraph-llm/src/tests/integration/test_graph_rag_pipeline.py 
b/hugegraph-llm/src/tests/integration/test_graph_rag_pipeline.py
index 243963c3..8a352e29 100644
--- a/hugegraph-llm/src/tests/integration/test_graph_rag_pipeline.py
+++ b/hugegraph-llm/src/tests/integration/test_graph_rag_pipeline.py
@@ -21,8 +21,12 @@ import tempfile
 import unittest
 from unittest.mock import MagicMock
 
+import pytest
+
 from tests.utils.mock import MockEmbedding
 
+pytestmark = [pytest.mark.external, pytest.mark.slow]
+
 
 class BaseLLM:
     def generate(self, prompt, **kwargs):
diff --git a/hugegraph-llm/src/tests/integration/test_kg_construction.py 
b/hugegraph-llm/src/tests/integration/test_kg_construction.py
index daa7b191..379cb350 100644
--- a/hugegraph-llm/src/tests/integration/test_kg_construction.py
+++ b/hugegraph-llm/src/tests/integration/test_kg_construction.py
@@ -22,6 +22,8 @@ import os
 import unittest
 from unittest.mock import patch
 
+import pytest
+
 # 导入测试工具
 from src.tests.test_utils import (
     create_test_document,
@@ -29,6 +31,8 @@ from src.tests.test_utils import (
     with_mock_openai_client,
 )
 
+pytestmark = [pytest.mark.external, pytest.mark.slow]
+
 
 # Create mock classes to replace missing modules
 class OpenAILLM:
diff --git a/hugegraph-llm/src/tests/integration/test_rag_pipeline.py 
b/hugegraph-llm/src/tests/integration/test_rag_pipeline.py
index bb5e4364..3abf253f 100644
--- a/hugegraph-llm/src/tests/integration/test_rag_pipeline.py
+++ b/hugegraph-llm/src/tests/integration/test_rag_pipeline.py
@@ -19,6 +19,8 @@ import os
 import tempfile
 import unittest
 
+import pytest
+
 # 导入测试工具
 from src.tests.test_utils import (
     create_test_document,
@@ -28,6 +30,8 @@ from src.tests.test_utils import (
 )
 from tests.utils.mock import VectorIndex
 
+pytestmark = [pytest.mark.external, pytest.mark.slow]
+
 
 # 创建模拟类,替代缺失的模块
 class Document:


Reply via email to