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

feat: add ops trace #5483

Merged
merged 69 commits into from
Jun 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
69 commits
Select commit Hold shift + click to select a range
cd7c586
feat: add llm ops tracing
ZhouhaoJiang Jun 16, 2024
a40433c
feat: add remove tracing app
ZhouhaoJiang Jun 17, 2024
4eb0c4d
feat: update trace table
ZhouhaoJiang Jun 17, 2024
000e855
feat: change table struct
ZhouhaoJiang Jun 18, 2024
e6def58
feat: change TraceAppConfigApi request type patch
ZhouhaoJiang Jun 18, 2024
6cfeb1a
feat: update default reply when config is none
ZhouhaoJiang Jun 18, 2024
98e1c30
fix: advanced chat trace error
ZhouhaoJiang Jun 19, 2024
1fc0225
feat: add trace ops api check
ZhouhaoJiang Jun 19, 2024
a454813
fix: uuid error
ZhouhaoJiang Jun 19, 2024
07531ab
feat: update workflow trace conversation_id
ZhouhaoJiang Jun 19, 2024
ebea85d
feat: format input and out
ZhouhaoJiang Jun 20, 2024
5eb901a
feat: generate tracing_instance in app_generator
ZhouhaoJiang Jun 21, 2024
5ae066a
feat: update down_revision
ZhouhaoJiang Jun 21, 2024
04af80c
feat: add trace_config_check_error
ZhouhaoJiang Jun 21, 2024
f604b7c
feat: update poetry.lock
ZhouhaoJiang Jun 21, 2024
a0a7c75
feat: format llm workflow trace
ZhouhaoJiang Jun 21, 2024
660d4e5
feat: add ops trace encrypt config decrypt_config obfuscate_config
ZhouhaoJiang Jun 20, 2024
9470169
feat: update the file structure
ZhouhaoJiang Jun 23, 2024
d1c8d69
fix: moderation trace message_id error
ZhouhaoJiang Jun 23, 2024
8d2f08d
feat: adding comments for BaseTraceInstance
ZhouhaoJiang Jun 23, 2024
0d798ac
fix: tracing_provider null error
ZhouhaoJiang Jun 24, 2024
41e2347
fix: completion-messages trace instance error
ZhouhaoJiang Jun 24, 2024
8cb809c
fix: add trace entity
ZhouhaoJiang Jun 24, 2024
41e936d
feat: add langfuse and langsmith trace class
ZhouhaoJiang Jun 24, 2024
c1bc774
fix: message trace start time error
ZhouhaoJiang Jun 24, 2024
7ee9616
feat: update base_trace_instance.py
ZhouhaoJiang Jun 24, 2024
54fc284
fix: workflow_trace llm error
ZhouhaoJiang Jun 24, 2024
0c10f77
fix: api_check_trace error
ZhouhaoJiang Jun 24, 2024
4293361
fix: type definition error
ZhouhaoJiang Jun 24, 2024
c77a738
fix: remove chinese
ZhouhaoJiang Jun 24, 2024
1d652e6
feat: remove trace folder
ZhouhaoJiang Jun 24, 2024
ad7fbc7
fix: the field is indeed wrong
ZhouhaoJiang Jun 24, 2024
d2ffc48
feat: trace manager generated in app generator
ZhouhaoJiang Jun 24, 2024
f815e7e
feat: add workflow_node_executions created time precision
ZhouhaoJiang Jun 24, 2024
ad45808
fix: update trace config error
ZhouhaoJiang Jun 24, 2024
c787fac
fix: remove superfluous tracing instance
ZhouhaoJiang Jun 24, 2024
53c033e
feat: through trace queue manager generate trace_instance
ZhouhaoJiang Jun 24, 2024
afbd778
chore: get rid of useless stuff
ZhouhaoJiang Jun 24, 2024
e6294b1
chore: change ops_trace_service location
ZhouhaoJiang Jun 24, 2024
c885fe0
Merge branch 'refs/heads/main' into feat/cleaning_ops_trace
ZhouhaoJiang Jun 24, 2024
7701aaf
update WorkflowNodeExecution init created_at
takatost Jun 24, 2024
16511dc
Merge remote-tracking branch 'origin/feat/cleaning_ops_trace' into fe…
ZhouhaoJiang Jun 24, 2024
bb2ad52
feat: update poetry.lock
ZhouhaoJiang Jun 24, 2024
3d1b27a
feat: add provider_config_map
ZhouhaoJiang Jun 24, 2024
7bf8faa
fix: trace queue manager error
ZhouhaoJiang Jun 25, 2024
084112e
fix: workflow on_tool_end trace_manager error
ZhouhaoJiang Jun 25, 2024
202872e
chore: change the trace structure
ZhouhaoJiang Jun 25, 2024
27c2446
fix: pydantic model_ warning
ZhouhaoJiang Jun 25, 2024
0971768
fix: conversation none error
ZhouhaoJiang Jun 25, 2024
13a0104
fix: from_account_id type error
ZhouhaoJiang Jun 25, 2024
b5df587
chore: update pydantic warning and tracing_provider_map
ZhouhaoJiang Jun 25, 2024
a760d0d
fix: tracing_provider error
ZhouhaoJiang Jun 25, 2024
0117310
fix: invalid tracing provider None
ZhouhaoJiang Jun 25, 2024
d5b9fbd
fix: trace_manager none error
ZhouhaoJiang Jun 25, 2024
fca9121
fix: conversation generate error
ZhouhaoJiang Jun 25, 2024
9590da7
fix generate conversation name
takatost Jun 25, 2024
f88d915
feat: add BaseTraceInfo field validator
ZhouhaoJiang Jun 25, 2024
1e6cc9d
feat: update MessageTraceInfo
ZhouhaoJiang Jun 25, 2024
a21da4c
feat: update suggested question trace manager
ZhouhaoJiang Jun 25, 2024
3f9de5c
optimize error msg
takatost Jun 25, 2024
81a6f80
fix _invoke_error_mapping of tongyi tts
takatost Jun 25, 2024
568b4d4
fix
takatost Jun 25, 2024
a071529
feat: optimize file_list
ZhouhaoJiang Jun 25, 2024
f426e55
Merge remote-tracking branch 'origin/feat/cleaning_ops_trace' into fe…
ZhouhaoJiang Jun 25, 2024
10cd08e
optimize
takatost Jun 25, 2024
8bf2c38
feat: update workflow trace
ZhouhaoJiang Jun 25, 2024
da93485
feat: update langfuse trace structure
ZhouhaoJiang Jun 26, 2024
91c177b
Resolve merge conflicts
ZhouhaoJiang Jun 26, 2024
6a9d4f7
remove requirements.txt
takatost Jun 26, 2024
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/controllers/console/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
generator,
message,
model_config,
ops_trace,
site,
statistic,
workflow,
Expand Down
40 changes: 35 additions & 5 deletions api/controllers/console/app/app.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
import json
import uuid

from flask_login import current_user
Expand All @@ -9,17 +8,14 @@
from controllers.console.app.wraps import get_app_model
from controllers.console.setup import setup_required
from controllers.console.wraps import account_initialization_required, cloud_edition_billing_resource_check
from core.tools.tool_manager import ToolManager
from core.tools.utils.configuration import ToolParameterConfigurationManager
from core.ops.ops_trace_manager import OpsTraceManager
from fields.app_fields import (
app_detail_fields,
app_detail_fields_with_site,
app_pagination_fields,
)
from libs.login import login_required
from models.model import App, AppMode, AppModelConfig
from services.app_service import AppService
from services.tag_service import TagService

ALLOW_CREATE_APP_MODES = ['chat', 'agent-chat', 'advanced-chat', 'workflow', 'completion']

Expand Down Expand Up @@ -286,6 +282,39 @@ def post(self, app_model):
return app_model


class AppTraceApi(Resource):
@setup_required
@login_required
@account_initialization_required
def get(self, app_id):
"""Get app trace"""
app_trace_config = OpsTraceManager.get_app_tracing_config(
app_id=app_id
)

return app_trace_config

@setup_required
@login_required
@account_initialization_required
def post(self, app_id):
# add app trace
if not current_user.is_admin_or_owner:
raise Forbidden()
parser = reqparse.RequestParser()
parser.add_argument('enabled', type=bool, required=True, location='json')
parser.add_argument('tracing_provider', type=str, required=True, location='json')
args = parser.parse_args()

OpsTraceManager.update_app_tracing_config(
app_id=app_id,
enabled=args['enabled'],
tracing_provider=args['tracing_provider'],
)

return {"result": "success"}


api.add_resource(AppListApi, '/apps')
api.add_resource(AppImportApi, '/apps/import')
api.add_resource(AppApi, '/apps/<uuid:app_id>')
Expand All @@ -295,3 +324,4 @@ def post(self, app_model):
api.add_resource(AppIconApi, '/apps/<uuid:app_id>/icon')
api.add_resource(AppSiteStatus, '/apps/<uuid:app_id>/site-enable')
api.add_resource(AppApiStatus, '/apps/<uuid:app_id>/api-enable')
api.add_resource(AppTraceApi, '/apps/<uuid:app_id>/trace')
18 changes: 18 additions & 0 deletions api/controllers/console/app/error.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,3 +97,21 @@ class DraftWorkflowNotSync(BaseHTTPException):
error_code = 'draft_workflow_not_sync'
description = "Workflow graph might have been modified, please refresh and resubmit."
code = 400


class TracingConfigNotExist(BaseHTTPException):
error_code = 'trace_config_not_exist'
description = "Trace config not exist."
code = 400


class TracingConfigIsExist(BaseHTTPException):
error_code = 'trace_config_is_exist'
description = "Trace config is exist."
code = 400


class TracingConfigCheckError(BaseHTTPException):
error_code = 'trace_config_check_error'
description = "Invalid Credentials."
code = 400
101 changes: 101 additions & 0 deletions api/controllers/console/app/ops_trace.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
from flask_restful import Resource, reqparse

from controllers.console import api
from controllers.console.app.error import TracingConfigCheckError, TracingConfigIsExist, TracingConfigNotExist
from controllers.console.setup import setup_required
from controllers.console.wraps import account_initialization_required
from libs.login import login_required
from services.ops_service import OpsService


class TraceAppConfigApi(Resource):
"""
Manage trace app configurations
"""

@setup_required
@login_required
@account_initialization_required
def get(self, app_id):
parser = reqparse.RequestParser()
parser.add_argument('tracing_provider', type=str, required=True, location='args')
args = parser.parse_args()

try:
trace_config = OpsService.get_tracing_app_config(
app_id=app_id, tracing_provider=args['tracing_provider']
)
if not trace_config:
return {"has_not_configured": True}
return trace_config
except Exception as e:
raise e

@setup_required
@login_required
@account_initialization_required
def post(self, app_id):
"""Create a new trace app configuration"""
parser = reqparse.RequestParser()
parser.add_argument('tracing_provider', type=str, required=True, location='json')
parser.add_argument('tracing_config', type=dict, required=True, location='json')
args = parser.parse_args()

try:
result = OpsService.create_tracing_app_config(
app_id=app_id,
tracing_provider=args['tracing_provider'],
tracing_config=args['tracing_config']
)
if not result:
raise TracingConfigIsExist()
if result.get('error'):
raise TracingConfigCheckError()
return result
except Exception as e:
raise e

@setup_required
@login_required
@account_initialization_required
def patch(self, app_id):
"""Update an existing trace app configuration"""
parser = reqparse.RequestParser()
parser.add_argument('tracing_provider', type=str, required=True, location='json')
parser.add_argument('tracing_config', type=dict, required=True, location='json')
args = parser.parse_args()

try:
result = OpsService.update_tracing_app_config(
app_id=app_id,
tracing_provider=args['tracing_provider'],
tracing_config=args['tracing_config']
)
if not result:
raise TracingConfigNotExist()
return {"result": "success"}
except Exception as e:
raise e

@setup_required
@login_required
@account_initialization_required
def delete(self, app_id):
"""Delete an existing trace app configuration"""
parser = reqparse.RequestParser()
parser.add_argument('tracing_provider', type=str, required=True, location='args')
args = parser.parse_args()

try:
result = OpsService.delete_tracing_app_config(
app_id=app_id,
tracing_provider=args['tracing_provider']
)
if not result:
raise TracingConfigNotExist()
return {"result": "success"}
except Exception as e:
raise e


api.add_resource(TraceAppConfigApi, '/apps/<uuid:app_id>/trace-config')
21 changes: 13 additions & 8 deletions api/core/agent/cot_agent_runner.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import json
from abc import ABC, abstractmethod
from collections.abc import Generator
from typing import Union
from typing import Optional, Union

from core.agent.base_agent_runner import BaseAgentRunner
from core.agent.entities import AgentScratchpadUnit
Expand All @@ -15,6 +15,7 @@
ToolPromptMessage,
UserPromptMessage,
)
from core.ops.ops_trace_manager import TraceQueueManager
from core.prompt.agent_history_prompt_transform import AgentHistoryPromptTransform
from core.tools.entities.tool_entities import ToolInvokeMeta
from core.tools.tool.tool import Tool
Expand Down Expand Up @@ -42,6 +43,8 @@ def run(self, message: Message,
self._repack_app_generate_entity(app_generate_entity)
self._init_react_state(query)

trace_manager = app_generate_entity.trace_manager

# check model mode
if 'Observation' not in app_generate_entity.model_conf.stop:
if app_generate_entity.model_conf.provider not in self._ignore_observation_providers:
Expand Down Expand Up @@ -211,7 +214,8 @@ def increase_usage(final_llm_usage_dict: dict[str, LLMUsage], usage: LLMUsage):
tool_invoke_response, tool_invoke_meta = self._handle_invoke_action(
action=scratchpad.action,
tool_instances=tool_instances,
message_file_ids=message_file_ids
message_file_ids=message_file_ids,
trace_manager=trace_manager,
)
scratchpad.observation = tool_invoke_response
scratchpad.agent_response = tool_invoke_response
Expand All @@ -237,8 +241,7 @@ def increase_usage(final_llm_usage_dict: dict[str, LLMUsage], usage: LLMUsage):

# update prompt tool message
for prompt_tool in self._prompt_messages_tools:
self.update_prompt_message_tool(
tool_instances[prompt_tool.name], prompt_tool)
self.update_prompt_message_tool(tool_instances[prompt_tool.name], prompt_tool)

iteration_step += 1

Expand Down Expand Up @@ -275,14 +278,15 @@ def increase_usage(final_llm_usage_dict: dict[str, LLMUsage], usage: LLMUsage):
message=AssistantPromptMessage(
content=final_answer
),
usage=llm_usage['usage'] if llm_usage['usage'] else LLMUsage.empty_usage(
),
usage=llm_usage['usage'] if llm_usage['usage'] else LLMUsage.empty_usage(),
system_fingerprint=''
)), PublishFrom.APPLICATION_MANAGER)

def _handle_invoke_action(self, action: AgentScratchpadUnit.Action,
tool_instances: dict[str, Tool],
message_file_ids: list[str]) -> tuple[str, ToolInvokeMeta]:
message_file_ids: list[str],
trace_manager: Optional[TraceQueueManager] = None
) -> tuple[str, ToolInvokeMeta]:
"""
handle invoke action
:param action: action
Expand Down Expand Up @@ -312,7 +316,8 @@ def _handle_invoke_action(self, action: AgentScratchpadUnit.Action,
tenant_id=self.tenant_id,
message=self.message,
invoke_from=self.application_generate_entity.invoke_from,
agent_tool_callback=self.agent_callback
agent_tool_callback=self.agent_callback,
trace_manager=trace_manager,
)

# publish files
Expand Down
4 changes: 4 additions & 0 deletions api/core/agent/fc_agent_runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,9 @@ def run(self,
}
final_answer = ''

# get tracing instance
trace_manager = app_generate_entity.trace_manager

def increase_usage(final_llm_usage_dict: dict[str, LLMUsage], usage: LLMUsage):
if not final_llm_usage_dict['usage']:
final_llm_usage_dict['usage'] = usage
Expand Down Expand Up @@ -243,6 +246,7 @@ def increase_usage(final_llm_usage_dict: dict[str, LLMUsage], usage: LLMUsage):
message=self.message,
invoke_from=self.application_generate_entity.invoke_from,
agent_tool_callback=self.agent_callback,
trace_manager=trace_manager,
)
# publish files
for message_file_id, save_as in message_files:
Expand Down
10 changes: 9 additions & 1 deletion api/core/app/app_config/entities.py
Original file line number Diff line number Diff line change
Expand Up @@ -183,6 +183,14 @@ class TextToSpeechEntity(BaseModel):
language: Optional[str] = None


class TracingConfigEntity(BaseModel):
"""
Tracing Config Entity.
"""
enabled: bool
tracing_provider: str


class FileExtraConfig(BaseModel):
"""
File Upload Entity.
Expand All @@ -199,7 +207,7 @@ class AppAdditionalFeatures(BaseModel):
more_like_this: bool = False
speech_to_text: bool = False
text_to_speech: Optional[TextToSpeechEntity] = None

trace_config: Optional[TracingConfigEntity] = None

class AppConfig(BaseModel):
"""
Expand Down
22 changes: 14 additions & 8 deletions api/core/app/apps/advanced_chat/app_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
from core.app.entities.task_entities import ChatbotAppBlockingResponse, ChatbotAppStreamResponse
from core.file.message_file_parser import MessageFileParser
from core.model_runtime.errors.invoke import InvokeAuthorizationError, InvokeError
from core.ops.ops_trace_manager import TraceQueueManager
from extensions.ext_database import db
from models.account import Account
from models.model import App, Conversation, EndUser, Message
Expand All @@ -29,13 +30,14 @@


class AdvancedChatAppGenerator(MessageBasedAppGenerator):
def generate(self, app_model: App,
workflow: Workflow,
user: Union[Account, EndUser],
args: dict,
invoke_from: InvokeFrom,
stream: bool = True) \
-> Union[dict, Generator[dict, None, None]]:
def generate(
self, app_model: App,
workflow: Workflow,
user: Union[Account, EndUser],
args: dict,
invoke_from: InvokeFrom,
stream: bool = True,
) -> Union[dict, Generator[dict, None, None]]:
"""
Generate App response.

Expand Down Expand Up @@ -84,6 +86,9 @@ def generate(self, app_model: App,
workflow=workflow
)

# get tracing instance
trace_manager = TraceQueueManager(app_id=app_model.id)

if invoke_from == InvokeFrom.DEBUGGER:
# always enable retriever resource in debugger mode
app_config.additional_features.show_retrieve_source = True
Expand All @@ -99,7 +104,8 @@ def generate(self, app_model: App,
user_id=user.id,
stream=stream,
invoke_from=invoke_from,
extras=extras
extras=extras,
trace_manager=trace_manager
)

return self._generate(
Expand Down
Loading
Loading