浏览代码

fix LangSmith project config error (#7996)

Charlie.Wei 7 月之前
父节点
当前提交
feefeb44d7

+ 23 - 0
api/core/ops/langsmith_trace/langsmith_trace.py

@@ -1,9 +1,11 @@
 import json
 import logging
 import os
+import uuid
 from datetime import datetime, timedelta
 
 from langsmith import Client
+from langsmith.schemas import RunBase
 
 from core.ops.base_trace_instance import BaseTraceInstance
 from core.ops.entities.config_entity import LangSmithConfig
@@ -371,3 +373,24 @@ class LangSmithDataTrace(BaseTraceInstance):
         except Exception as e:
             logger.debug(f"LangSmith API check failed: {str(e)}")
             raise ValueError(f"LangSmith API check failed: {str(e)}")
+
+    def get_project_url(self):
+        try:
+            run_data = RunBase(
+                id=uuid.uuid4(),
+                name="tool",
+                inputs={"input": "test"},
+                outputs={"output": "test"},
+                run_type=LangSmithRunType.tool,
+                start_time=datetime.now(),
+            )
+
+            project_url = self.langsmith_client.get_run_url(run=run_data,
+                                                        project_id=self.project_id,
+                                                        project_name=self.project_name)
+            return project_url.split('/r/')[0]
+        except Exception as e:
+            logger.debug(f"LangSmith get run url failed: {str(e)}")
+            raise ValueError(f"LangSmith get run url failed: {str(e)}")
+
+

+ 13 - 0
api/core/ops/ops_trace_manager.py

@@ -264,6 +264,19 @@ class OpsTraceManager:
         tracing_config = config_type(**tracing_config)
         return trace_instance(tracing_config).get_project_key()
 
+    @staticmethod
+    def get_trace_config_project_url(tracing_config: dict, tracing_provider: str):
+        """
+        get trace config is project key
+        :param tracing_config: tracing config
+        :param tracing_provider: tracing provider
+        :return:
+        """
+        config_type, trace_instance = provider_config_map[tracing_provider]['config_class'], \
+            provider_config_map[tracing_provider]['trace_instance']
+        tracing_config = config_type(**tracing_config)
+        return trace_instance(tracing_config).get_project_url()
+
 
 class TraceTask:
     def __init__(

+ 19 - 5
api/services/ops_service.py

@@ -32,7 +32,15 @@ class OpsService:
             "project_key" not in decrypt_tracing_config or not decrypt_tracing_config.get("project_key")
         ):
             project_key = OpsTraceManager.get_trace_config_project_key(decrypt_tracing_config, tracing_provider)
-            new_decrypt_tracing_config.update({"project_key": project_key})
+            new_decrypt_tracing_config.update(
+                {"project_url": "{host}/project/{key}".format(host=decrypt_tracing_config.get("host"), key=project_key)}
+            )
+
+        if tracing_provider == "langsmith" and (
+            "project_url" not in decrypt_tracing_config or not decrypt_tracing_config.get("project_url")
+        ):
+            project_url = OpsTraceManager.get_trace_config_project_url(decrypt_tracing_config, tracing_provider)
+            new_decrypt_tracing_config.update({"project_url": project_url})
 
         trace_config_data.tracing_config = new_decrypt_tracing_config
         return trace_config_data.to_dict()
@@ -62,8 +70,14 @@ class OpsService:
         if not OpsTraceManager.check_trace_config_is_effective(tracing_config, tracing_provider):
             return {"error": "Invalid Credentials"}
 
-        # get project key
-        project_key = OpsTraceManager.get_trace_config_project_key(tracing_config, tracing_provider)
+        # get project url
+        if tracing_provider == "langfuse":
+            project_key = OpsTraceManager.get_trace_config_project_key(tracing_config, tracing_provider)
+            project_url = "{host}/project/{key}".format(host=tracing_config.get("host"), key=project_key)
+        elif tracing_provider == "langsmith":
+            project_url = OpsTraceManager.get_trace_config_project_url(tracing_config, tracing_provider)
+        else:
+            project_url = None
 
         # check if trace config already exists
         trace_config_data: TraceAppConfig = (
@@ -78,8 +92,8 @@ class OpsService:
         # get tenant id
         tenant_id = db.session.query(App).filter(App.id == app_id).first().tenant_id
         tracing_config = OpsTraceManager.encrypt_tracing_config(tenant_id, tracing_provider, tracing_config)
-        if tracing_provider == "langfuse" and project_key:
-            tracing_config["project_key"] = project_key
+        if project_url:
+            tracing_config["project_url"] = project_url
         trace_config_data = TraceAppConfig(
             app_id=app_id,
             tracing_provider=tracing_provider,

+ 4 - 3
web/app/(commonLayout)/app/(appDetailLayout)/[appId]/overview/tracing/provider-panel.tsx

@@ -48,9 +48,10 @@ const ProviderPanel: FC<Props> = ({
     e.preventDefault()
     e.stopPropagation()
 
-    const url = `${config?.host}/project/${config?.project_key}`
-    window.open(url, '_blank', 'noopener,noreferrer')
-  }, [])
+    const url = config?.project_url
+    if (url)
+      window.open(url, '_blank', 'noopener,noreferrer')
+  }, [config?.project_url])
 
   const handleChosen = useCallback((e: React.MouseEvent) => {
     e.stopPropagation()