Copilot commented on code in PR #358:
URL: https://github.com/apache/hugegraph-ai/pull/358#discussion_r3346050761


##########
.workflow/code-scan/reports/final-code-scan-report.md:
##########
@@ -0,0 +1,94 @@
+# Final Code Scan Report
+
+Date: 2026-05-31
+Scope: `hugegraph-llm`, `hugegraph-python-client`
+
+## Summary
+
+The scan completed all planned lanes. The highest-risk result is one P0 
security issue in the `hugegraph-llm` admin log API. The broader pattern is 
that core boundary failures are often hidden: client transport errors are 
retyped, provider failures are returned as normal text, graph/vector dependency 
failures can be converted to empty results, and several integration tests use 
local stand-ins rather than production flows.
+
+During the scan phase, no behavior-changing source fixes were made. Only scan 
documents and `FIXME:` comments were added. Follow-up fixes are listed later in 
this report.

Review Comment:
   The summary claims no behavior-changing source fixes were made during the 
scan, but this report also includes a “Fix Progress After Scan” section and the 
PR itself contains multiple behavior-changing fixes (e.g., `/logs` path 
validation, response parsing, redaction). Please reword this line so the report 
is internally consistent for readers.



##########
hugegraph-llm/src/hugegraph_llm/api/rag_api.py:
##########
@@ -45,103 +66,110 @@ def rag_http_api(
     apply_reranker_conf,
     gremlin_generate_selective_func,
 ):
-    @router.post("/rag", status_code=status.HTTP_200_OK)
-    def rag_answer_api(req: RAGRequest):
-        set_graph_config(req)
-
-        # Basic parameter validation: empty query => 400
-        if not req.query or not str(req.query).strip():
-            raise HTTPException(
-                status_code=status.HTTP_400_BAD_REQUEST,
-                detail="Query must not be empty.",
-            )
-
-        result = rag_answer_func(
-            text=req.query,
-            raw_answer=req.raw_answer,
-            vector_only_answer=req.vector_only,
-            graph_only_answer=req.graph_only,
-            graph_vector_answer=req.graph_vector_answer,
-            graph_ratio=req.graph_ratio,
-            rerank_method=req.rerank_method,
-            near_neighbor_first=req.near_neighbor_first,
-            gremlin_tmpl_num=req.gremlin_tmpl_num,
-            max_graph_items=req.max_graph_items,
-            topk_return_results=req.topk_return_results,
-            vector_dis_threshold=req.vector_dis_threshold,
-            topk_per_keyword=req.topk_per_keyword,
-            # Keep prompt params in the end
-            custom_related_information=req.custom_priority_info,
-            answer_prompt=req.answer_prompt or prompt.answer_prompt,
-            keywords_extract_prompt=req.keywords_extract_prompt or 
prompt.keywords_extract_prompt,
-            gremlin_prompt=req.gremlin_prompt or 
prompt.gremlin_generate_prompt,
-        )
-        # TODO: we need more info in the response for users to understand the 
query logic
-        return {
-            "query": req.query,
-            **{
-                key: value
-                for key, value in zip(
-                    ["raw_answer", "vector_only", "graph_only", 
"graph_vector_answer"],
-                    result,
-                )
-                if getattr(req, key)
-            },
-        }
-
-    def set_graph_config(req):
-        if req.client_config:
-            huge_settings.graph_url = req.client_config.url
-            huge_settings.graph_name = req.client_config.graph
-            huge_settings.graph_user = req.client_config.user
-            huge_settings.graph_pwd = req.client_config.pwd
-            huge_settings.graph_space = req.client_config.gs
-
-    @router.post("/rag/graph", status_code=status.HTTP_200_OK)
-    def graph_rag_recall_api(req: GraphRAGRequest):
+    @contextmanager
+    def request_graph_config(req):
+        # TODO: pass graph config through request-scoped flow/operator context
+        # instead of temporarily mutating process-global huge_settings.
+        original_values = _snapshot_settings(huge_settings, 
_GRAPH_CONFIG_FIELD_MAP.values())
         try:
-            set_graph_config(req)
+            client_config = getattr(req, "client_config", None)
+            if client_config is not None:
+                for request_field, settings_field in 
_GRAPH_CONFIG_FIELD_MAP.items():
+                    if request_field in client_config.model_fields_set:
+                        setattr(huge_settings, settings_field, 
getattr(client_config, request_field))
+            yield

Review Comment:
   `request_graph_config()` still mutates the process-global `huge_settings` 
inside the request handler. That means concurrent requests can observe each 
other’s temporary overrides (URL/user/pwd/graphspace), which can cause 
cross-request data leakage or auth misrouting even though values are restored 
in `finally`.



-- 
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.

To unsubscribe, e-mail: [email protected]

For queries about this service, please contact Infrastructure at:
[email protected]


---------------------------------------------------------------------
To unsubscribe, e-mail: [email protected]
For additional commands, e-mail: [email protected]

Reply via email to