Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

langfuser add view button #7571

Merged
merged 3 commits into from
Aug 23, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions api/core/ops/entities/config_entity.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ class LangfuseConfig(BaseTracingConfig):
"""
public_key: str
secret_key: str
project_key: str
host: str = 'https://api.langfuse.com'

@field_validator("host")
Expand Down
8 changes: 8 additions & 0 deletions api/core/ops/langfuse_trace/langfuse_trace.py
Original file line number Diff line number Diff line change
Expand Up @@ -419,3 +419,11 @@ def api_check(self):
except Exception as e:
logger.debug(f"LangFuse API check failed: {str(e)}")
raise ValueError(f"LangFuse API check failed: {str(e)}")

def get_project_key(self):
try:
projects = self.langfuse_client.client.projects.get()
return projects.data[0].id
except Exception as e:
logger.debug(f"LangFuse get project key failed: {str(e)}")
raise ValueError(f"LangFuse get project key failed: {str(e)}")
16 changes: 14 additions & 2 deletions api/core/ops/ops_trace_manager.py
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@
TracingProviderEnum.LANGFUSE.value: {
'config_class': LangfuseConfig,
'secret_keys': ['public_key', 'secret_key'],
'other_keys': ['host'],
'other_keys': ['host', 'project_key'],
'trace_instance': LangFuseDataTrace
},
TracingProviderEnum.LANGSMITH.value: {
Expand Down Expand Up @@ -123,7 +123,6 @@ def obfuscated_decrypt_token(cls, tracing_provider: str, decrypt_tracing_config:

for key in other_keys:
new_config[key] = decrypt_tracing_config.get(key, "")

return config_class(**new_config).model_dump()

@classmethod
Expand Down Expand Up @@ -252,6 +251,19 @@ def check_trace_config_is_effective(tracing_config: dict, tracing_provider: str)
tracing_config = config_type(**tracing_config)
return trace_instance(tracing_config).api_check()

@staticmethod
def get_trace_config_project_key(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_key()


class TraceTask:
def __init__(
Expand Down
11 changes: 10 additions & 1 deletion api/services/ops_service.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,10 @@ def get_tracing_app_config(cls, app_id: str, tracing_provider: str):
# decrypt_token and obfuscated_token
tenant_id = db.session.query(App).filter(App.id == app_id).first().tenant_id
decrypt_tracing_config = OpsTraceManager.decrypt_tracing_config(tenant_id, tracing_provider, trace_config_data.tracing_config)
if tracing_provider == 'langfuse' and ('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)
decrypt_tracing_config['project_key'] = project_key

decrypt_tracing_config = OpsTraceManager.obfuscated_decrypt_token(tracing_provider, decrypt_tracing_config)

trace_config_data.tracing_config = decrypt_tracing_config
Expand All @@ -37,7 +41,7 @@ def create_tracing_app_config(cls, app_id: str, tracing_provider: str, tracing_c
:param tracing_config: tracing config
:return:
"""
if tracing_provider not in provider_config_map.keys() and tracing_provider != None:
if tracing_provider not in provider_config_map.keys() and tracing_provider:
return {"error": f"Invalid tracing provider: {tracing_provider}"}

config_class, other_keys = provider_config_map[tracing_provider]['config_class'], \
Expand All @@ -51,6 +55,9 @@ def create_tracing_app_config(cls, app_id: str, tracing_provider: str, tracing_c
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)

# check if trace config already exists
trace_config_data: TraceAppConfig = db.session.query(TraceAppConfig).filter(
TraceAppConfig.app_id == app_id, TraceAppConfig.tracing_provider == tracing_provider
Expand All @@ -62,6 +69,8 @@ def create_tracing_app_config(cls, app_id: str, tracing_provider: str, tracing_c
# 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':
tracing_config['project_key'] = project_key
trace_config_data = TraceAppConfig(
app_id=app_id,
tracing_provider=tracing_provider,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,13 +6,15 @@ import { TracingProvider } from './type'
import cn from '@/utils/classnames'
import { LangfuseIconBig, LangsmithIconBig } from '@/app/components/base/icons/src/public/tracing'
import { Settings04 } from '@/app/components/base/icons/src/vender/line/general'
import { Eye as View } from '@/app/components/base/icons/src/vender/solid/general'

const I18N_PREFIX = 'app.tracing'

type Props = {
type: TracingProvider
readOnly: boolean
isChosen: boolean
Config: any
onChoose: () => void
hasConfigured: boolean
onConfig: () => void
Expand All @@ -29,6 +31,7 @@ const ProviderPanel: FC<Props> = ({
type,
readOnly,
isChosen,
Config,
onChoose,
hasConfigured,
onConfig,
Expand All @@ -41,6 +44,14 @@ const ProviderPanel: FC<Props> = ({
onConfig()
}, [onConfig])

const viewBtnClick = useCallback((e: React.MouseEvent) => {
e.preventDefault()
e.stopPropagation()

const url = `${Config?.host}/project/${Config?.project_key}`
window.open(url, '_blank', 'noopener,noreferrer')
}, [Config?.host, Config?.project_key])

const handleChosen = useCallback((e: React.MouseEvent) => {
e.stopPropagation()
if (isChosen || !hasConfigured || readOnly)
Expand All @@ -58,12 +69,20 @@ const ProviderPanel: FC<Props> = ({
{isChosen && <div className='ml-1 flex items-center h-4 px-1 rounded-[4px] border border-primary-500 leading-4 text-xs font-medium text-primary-500 uppercase '>{t(`${I18N_PREFIX}.inUse`)}</div>}
</div>
{!readOnly && (
<div
className='flex px-2 items-center h-6 bg-white rounded-md border-[0.5px] border-gray-200 shadow-xs cursor-pointer text-gray-700 space-x-1'
onClick={handleConfigBtnClick}
>
<Settings04 className='w-3 h-3' />
<div className='text-xs font-medium'>{t(`${I18N_PREFIX}.config`)}</div>
<div className={'flex justify-between items-center space-x-1'}>
{hasConfigured && (
<div className='flex px-2 items-center h-6 bg-white rounded-md border-[0.5px] border-gray-200 shadow-xs cursor-pointer text-gray-700 space-x-1' onClick={viewBtnClick} >
<View className='w-3 h-3'/>
<div className='text-xs font-medium'>{t(`${I18N_PREFIX}.view`)}</div>
</div>
)}
<div
className='flex px-2 items-center h-6 bg-white rounded-md border-[0.5px] border-gray-200 shadow-xs cursor-pointer text-gray-700 space-x-1'
onClick={handleConfigBtnClick}
>
<Settings04 className='w-3 h-3' />
<div className='text-xs font-medium'>{t(`${I18N_PREFIX}.config`)}</div>
</div>
</div>
)}

Expand Down
1 change: 1 addition & 0 deletions web/i18n/en-US/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -95,6 +95,7 @@ const translation = {
title: 'Tracing app performance',
description: 'Configuring a Third-Party LLMOps provider and tracing app performance.',
config: 'Config',
view: 'View',
collapse: 'Collapse',
expand: 'Expand',
tracing: 'Tracing',
Expand Down
1 change: 1 addition & 0 deletions web/i18n/zh-Hans/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -94,6 +94,7 @@ const translation = {
title: '追踪应用性能',
description: '配置第三方 LLMOps 提供商并跟踪应用程序性能。',
config: '配置',
view: '查看',
collapse: '折叠',
expand: '展开',
tracing: '追踪',
Expand Down
1 change: 1 addition & 0 deletions web/i18n/zh-Hant/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,7 @@ const translation = {
title: '追蹤應用程式效能',
description: '配置第三方LLMOps提供商並追蹤應用程式效能。',
config: '配置',
view: '查看',
collapse: '收起',
expand: '展開',
tracing: '追蹤',
Expand Down