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


##########
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:
   Kept this as an explicit FIXME/follow-up instead of adding a global lock in 
this PR. A lock would cover long-running RAG/Text2Gremlin work and serialize 
concurrent requests; the real fix should pass graph config through 
request-scoped flow/operator context and construct per-request HugeGraph 
clients.



##########
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())

Review Comment:
   Resolved by keeping the no-lock scope and making the follow-up direction 
explicit. The lock suggestion is intentionally not applied here because it 
would serialize long RAG/Text2Gremlin requests; request-scoped config and 
per-request clients should be handled in a dedicated refactor.



-- 
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