Skip to content

Commit

Permalink
update
Browse files Browse the repository at this point in the history
  • Loading branch information
userpj committed Dec 26, 2024
1 parent 74a6dee commit 535120f
Show file tree
Hide file tree
Showing 4 changed files with 120 additions and 73 deletions.
37 changes: 37 additions & 0 deletions go/appbuilder/component_client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
// Copyright (c) 2024 Baidu, Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package appbuilder

import (
"errors"
"net/http"
"time"
)

type ComponentClient struct {
sdkConfig *SDKConfig
client HTTPClient
}

func NewComponentClient(config *SDKConfig) (*ComponentClient, error) {
if config == nil {
return nil, errors.New("config is nil")
}
client := config.HTTPClient
if client == nil {
client = &http.Client{Timeout: 300 * time.Second}
}
return &ComponentClient{sdkConfig: config, client: client}, nil
}
16 changes: 16 additions & 0 deletions go/appbuilder/component_client_data.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
// Copyright (c) 2024 Baidu, Inc. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

package appbuilder

36 changes: 30 additions & 6 deletions python/core/console/component_client/component_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,18 @@
# limitations under the License.

"""组件"""
from appbuilder.core.component import Component
import json
from appbuilder.core.component import Component, Message
from appbuilder.core.console.component_client import data_class
from appbuilder.core._exception import AppBuilderServerException
from appbuilder.utils.logger_util import logger
from appbuilder.utils.trace.tracer_wrapper import client_tool_trace
from appbuilder.utils.sse_util import SSEClient


class ComponentClient(Component):
def __init__(self, **kwargs):
r"""初始化智能体应用
r"""初始化
Returns:
response (obj: `ComponentClient`): 组件实例
Expand Down Expand Up @@ -72,7 +75,28 @@ def run(
json=request.model_dump(exclude_none=True, by_alias=True),
timeout=None,
)
self.http_client.check_response_header(response)
data = response.json()
resp = data_class.RunResponse(**data)
return resp
request_id = self.http_client.check_response_header(response)

if stream:
client = SSEClient(response)
return Message(content=self._iterate_events(request_id, client.events()))
else:
data = response.json()
resp = data_class.RunResponse(**data)
return Message(content=resp.data)

@staticmethod
def _iterate_events(request_id, events):
for event in events:
try:
data = event.data
if len(data) == 0:
data = event.raw
data = json.loads(data)
except json.JSONDecodeError as e:
raise AppBuilderServerException(
request_id=request_id,
message="json decoder failed {}".format(str(e)),
)
resp = data_class.RunResponse(**data)
yield resp.data
104 changes: 37 additions & 67 deletions python/core/console/component_client/data_class.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
from pydantic import BaseModel
from pydantic import Field
from typing import Optional
from appbuilder.core.component import ComponentOutput, Content


class RunRequest(BaseModel):
Expand Down Expand Up @@ -55,82 +56,51 @@ class Config:
parameters: Parameters = Field(..., description="调用传参")


class Content(Content):
""" ContentWithEvent """

class Event(BaseModel):
""" Event"""
id: str = Field(..., description="事件id")
status: str = Field(...,
description="事件状态,枚举:preparing、running、error、done")
name: str = Field(
...,
description="事件名,相当于调用的深度,深度与前端的渲染逻辑有关系",
)
created_time: str = Field(
...,
description="当前event发送时间",
)
error_code: str = Field(
None,
description="错误码",
)
error_message: str = Field(
None,
description="错误信息",
)

event: Event = Field(..., description="事件信息")


class ComponentOutput(ComponentOutput):
content: list[Content] = Field(
None,
description="当前组件返回内容的主要payload,List[ContentWithEvent],每个 Content 包括了当前 event 的一个元素",
)


class RunResponse(BaseModel):
""" Component Run方法响应体 """
class Data(BaseModel):
class Data(ComponentOutput):
""" Data """

class Content(BaseModel):
""" Content """

class Usage(BaseModel):
""" Usage"""
prompt_tokens: int = Field(..., description="prompt token消耗")
completion_tokens: int = Field(..., description="问答返回消耗")
total_tokens: int = Field(..., description="总token消耗")
nodes: list[dict] = Field(None, description="工作流节点消耗情况")

class Metrics(BaseModel):
""" Metrics"""
begin_time: str = Field(
..., description="请求开始时间,示例:”2000-01-01T10:00:00.560430“"
)
duration: float = Field(
..., description="从请求到当前event总耗时,保留3位有效数字,单位秒s"
)

class Event(BaseModel):
""" Event"""
id: str = Field(..., description="事件id")
status: str = Field(...,
description="事件状态,枚举:preparing、running、error、done")
name: str = Field(
...,
description="事件名,相当于调用的深度,深度与前端的渲染逻辑有关系",
)
created_time: str = Field(
...,
description="当前event发送时间",
)
error_code: str = Field(
None,
description="错误码",
)
error_message: str = Field(
None,
description="错误信息",
)

type: str = Field(
...,
description="代表event 类型, text、json、code、files、urls、oral_text、references、image、chart、audio、function_call",
)
name: str = Field(..., description="当前内容名称")
text: dict = Field(
...,
description="代表当前 event 元素的内容,每一种 event 对应的 text 结构固定",
)
visible_scope: str = Field(
...,
description="为了界面展示明确的说明字段,枚举: all、llm、user、空",
)
usage: Usage = Field(
None, description="大模型的token使用情况"
)
metrics: Metrics = Field(..., description="耗时信息")
event: Event = Field(..., description="事件信息")

conversation_id: str = Field(..., description="对话id")
message_id: str = Field(..., description="消息id")
trace_id: str = Field(..., description="追踪id")
user_id: str = Field(..., description="开发者UUID(计费依赖)")
end_user_id: str = Field(None, description="终端用户id")
is_completion: bool = Field(..., description="是否完成")
role: str = Field(..., description="当前消息来源,默认tool")
content: list[Content] = Field(
None,
description="当前组件返回内容的主要payload,List[Content],每个 Content 包括了当前 event 的一个元素,具体见下文Content对象定义",
)

request_id: str = Field(..., description="请求id")
code: str = Field(None, description="响应码")
Expand Down

0 comments on commit 535120f

Please sign in to comment.