add tool
parent
c0358d8d0c
commit
8c269e061f
@ -0,0 +1,66 @@
|
||||
name: Build Docker Image
|
||||
|
||||
on:
|
||||
push:
|
||||
tags:
|
||||
- v*
|
||||
workflow_dispatch:
|
||||
|
||||
env:
|
||||
DOCKERHUB_REPO: registry.cn-hangzhou.aliyuncs.com/kindlingx/dify-api
|
||||
|
||||
jobs:
|
||||
build-image:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest]
|
||||
runs-on: ${{ matrix.os }}
|
||||
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v2
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
|
||||
- name: Set up Docker Buildx
|
||||
uses: docker/setup-buildx-action@v3
|
||||
|
||||
- name: Login to DockerHub
|
||||
uses: docker/login-action@v3
|
||||
with:
|
||||
registry: registry.cn-hangzhou.aliyuncs.com
|
||||
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||
|
||||
- name: Generate App Version (AMD64)
|
||||
if: ${{ matrix.os == 'ubuntu-latest' }}
|
||||
run: |
|
||||
TAG=$(git describe --tags --exact-match 2>/dev/null || echo "")
|
||||
if [ -n "$TAG" ]; then
|
||||
echo "APP_VERSION=$TAG" >> $GITHUB_ENV
|
||||
else
|
||||
BRANCH=$(git rev-parse --abbrev-ref HEAD | sed 's#[^a-zA-Z0-9._-]#-#g')
|
||||
COMMIT=$(git rev-parse --short HEAD)
|
||||
echo "APP_VERSION=${BRANCH}-${COMMIT}" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Generate App Version (ARM64)
|
||||
if: ${{ matrix.os == 'ubuntu-24.04-arm' }}
|
||||
run: |
|
||||
TAG=$(git describe --tags --exact-match 2>/dev/null || echo "")
|
||||
if [ -n "$TAG" ]; then
|
||||
echo "APP_VERSION=$TAG-arm64" >> $GITHUB_ENV
|
||||
else
|
||||
BRANCH=$(git rev-parse --abbrev-ref HEAD | sed 's#[^a-zA-Z0-9._-]#-#g')
|
||||
COMMIT=$(git rev-parse --short HEAD)
|
||||
echo "APP_VERSION=${BRANCH}-${COMMIT}-arm64" >> $GITHUB_ENV
|
||||
fi
|
||||
|
||||
- name: Build and push
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
context: ./api
|
||||
push: true
|
||||
tags: |
|
||||
${{ env.DOCKERHUB_REPO }}:${{ env.APP_VERSION }}
|
||||
@ -0,0 +1,17 @@
|
||||
from pydantic import Field
|
||||
from pydantic_settings import BaseSettings
|
||||
|
||||
|
||||
class APOConfig(BaseSettings):
|
||||
"""
|
||||
Configuration settings for apo
|
||||
"""
|
||||
|
||||
APO_BACKEND_URL: str = Field(
|
||||
description="apo backend url",
|
||||
default="http://localhost:8080",
|
||||
)
|
||||
APO_VM_URL: str = Field(
|
||||
description="apo vm url",
|
||||
default="http://localhost:8080",
|
||||
)
|
||||
@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.666992 8.00008C0.666992 3.94999 3.95024 0.666748 8.00033 0.666748C12.0504 0.666748 15.3337 3.94999 15.3337 8.00008C15.3337 12.0502 12.0504 15.3334 8.00033 15.3334C3.95024 15.3334 0.666992 12.0502 0.666992 8.00008ZM8.66699 4.00008C8.66699 3.63189 8.36852 3.33341 8.00033 3.33341C7.63213 3.33341 7.33366 3.63189 7.33366 4.00008V8.00008C7.33366 8.2526 7.47633 8.48344 7.70218 8.59637L10.3688 9.9297C10.6982 10.0944 11.0986 9.96088 11.2633 9.63156C11.4279 9.30224 11.2945 8.90179 10.9651 8.73713L8.66699 7.58806V4.00008Z" fill="#EC4A0A"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 691 B |
@ -0,0 +1,8 @@
|
||||
from typing import Any
|
||||
|
||||
from core.tools.builtin_tool.provider import BuiltinToolProviderController
|
||||
|
||||
|
||||
class APOAnalysisProvider(BuiltinToolProviderController):
|
||||
def _validate_credentials(self, user_id: str, credentials: dict[str, Any]) -> None:
|
||||
pass
|
||||
@ -0,0 +1,14 @@
|
||||
identity:
|
||||
author: APO
|
||||
name: apo_analysis
|
||||
label:
|
||||
en_US: APOAnalysis
|
||||
zh_Hans: APO异常检测
|
||||
pt_BR: APOSelect
|
||||
description:
|
||||
en_US: A tool for getting the current time.
|
||||
zh_Hans: APO异常检测分析。
|
||||
pt_BR: A tool for getting the current time.
|
||||
icon: icon.svg
|
||||
tags:
|
||||
- utilities
|
||||
@ -0,0 +1,121 @@
|
||||
import json
|
||||
from collections.abc import Generator
|
||||
from typing import Any, Optional
|
||||
|
||||
from core.tools.builtin_tool.tool import BuiltinTool
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
|
||||
|
||||
class AlertAssociateTool(BuiltinTool):
|
||||
def _invoke(
|
||||
self,
|
||||
user_id: str,
|
||||
tool_parameters: dict[str, Any],
|
||||
conversation_id: Optional[str] = None,
|
||||
app_id: Optional[str] = None,
|
||||
message_id: Optional[str] = None,
|
||||
) -> Generator[ToolInvokeMessage, None, None]:
|
||||
metric = tool_parameters.get('topology_data')
|
||||
topology_data = json.loads(metric)['data']
|
||||
alert_data = json.loads(tool_parameters.get('alert_data'))['data']
|
||||
alert = self.process_alert(alert_data)
|
||||
topology = self.process_topology(topology_data, alert)
|
||||
|
||||
# res = json.dumps({
|
||||
# "type": 'llm',
|
||||
# "display": False,
|
||||
# "data": topology
|
||||
# }, ensure_ascii=False)
|
||||
yield self.create_text_message(topology)
|
||||
|
||||
def _summary_delta_event(self, delta_data: list, stats: dict):
|
||||
for event in delta_data:
|
||||
service = event['serviceName']
|
||||
endpoint = event['endpoint']
|
||||
anormal_status = event['anormalStatus']
|
||||
anormal_type = event['anormalType']
|
||||
time = event['timestamp']
|
||||
p = f'{service}_#"{endpoint}"'
|
||||
|
||||
if p not in stats:
|
||||
stats[p] = {}
|
||||
|
||||
if anormal_type not in stats[p]:
|
||||
stats[p][anormal_type] = {
|
||||
"add": 0,
|
||||
"duplicate": 0,
|
||||
"resolve": 0,
|
||||
"keep": 0,
|
||||
"lastTime": time,
|
||||
"firstTime": time
|
||||
}
|
||||
|
||||
if time < stats[p][anormal_type]["firstTime"]:
|
||||
stats[p][anormal_type]["firstTime"] = time
|
||||
|
||||
if time > stats[p][anormal_type]["lastTime"]:
|
||||
stats[p][anormal_type]["lastTime"] = time
|
||||
|
||||
match anormal_status:
|
||||
case "startFiring":
|
||||
stats[p][anormal_type]["add"] += 1
|
||||
case "resolved":
|
||||
stats[p][anormal_type]["resolve"] += 1
|
||||
if "resolveTime" not in stats[p][anormal_type]:
|
||||
stats[p][anormal_type]["resolveTime"] = time
|
||||
case "updatedFiring":
|
||||
stats[p][anormal_type]["duplicate"] += 1
|
||||
|
||||
def _summary_keep_event(self, json_data: list, stats: dict):
|
||||
for event in json_data:
|
||||
service_name = event["serviceName"]
|
||||
anormal_type = event["anormalType"]
|
||||
endpoint = event["endpoint"]
|
||||
p = service_name + '_#"' + endpoint + '"'
|
||||
stats[p][anormal_type]["keep"] += 1
|
||||
|
||||
def process_alert(self, alert_data: dict) -> dict:
|
||||
stats = {}
|
||||
json_data = alert_data["deltaAnormalEvents"]
|
||||
self._summary_delta_event(json_data, stats)
|
||||
json_data = alert_data["finalAnormalEvents"]
|
||||
self._summary_keep_event(json_data, stats)
|
||||
return stats
|
||||
|
||||
def _build_tree(self, node: str, depth=0, relation_dict={}, list=[], alert_data={}):
|
||||
indent = " " * depth
|
||||
text = ""
|
||||
text += f'{indent}{depth}──'
|
||||
|
||||
if node in alert_data:
|
||||
alert_text = json.dumps(alert_data[node])
|
||||
text += f"{node} {alert_text}\n"
|
||||
else:
|
||||
text += f"{node}\n"
|
||||
|
||||
list.append(text)
|
||||
|
||||
if node in relation_dict:
|
||||
for child in relation_dict[node]:
|
||||
self._build_tree(child, depth + 1, relation_dict, list, alert_data)
|
||||
|
||||
def process_topology(self, topology_data: dict, alert_data: dict) -> str:
|
||||
relation_dict = {}
|
||||
for relation in topology_data["childRelations"]:
|
||||
|
||||
p = relation['parentService']
|
||||
c = relation['service']
|
||||
parent_node = f'{p}_#"{relation['parentEndpoint']}"'
|
||||
child_node = f'{c}_#"{relation['endpoint']}"'
|
||||
|
||||
if parent_node not in relation_dict:
|
||||
relation_dict[parent_node] = []
|
||||
|
||||
relation_dict[parent_node].append(child_node)
|
||||
|
||||
text = []
|
||||
root_nodes = set(relation_dict.keys()) - {child for children in relation_dict.values() for child in children}
|
||||
for root in root_nodes:
|
||||
self._build_tree(root, 0, relation_dict, text, alert_data)
|
||||
res = "".join(text)
|
||||
return res
|
||||
@ -0,0 +1,40 @@
|
||||
identity:
|
||||
name: alert_associate
|
||||
author: APO
|
||||
label:
|
||||
en_US: alert_associate
|
||||
zh_Hans: 关联拓扑和告警数据
|
||||
pt_BR: alert_associate
|
||||
description:
|
||||
human:
|
||||
en_US: A tool for alert_associate
|
||||
zh_Hans: 关联拓扑和告警数据
|
||||
pt_BR: A tool for alert_associate
|
||||
llm: A tool for alert_associate
|
||||
parameters:
|
||||
- name: topology_data
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: topology_data
|
||||
zh_Hans: 拓扑数据
|
||||
pt_BR: topology_data
|
||||
human_description:
|
||||
en_US: topology_data
|
||||
zh_Hans: 拓扑数据
|
||||
pt_BR: topology_data
|
||||
llm_description: topology data
|
||||
form: llm
|
||||
- name: alert_data
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: alert_data
|
||||
zh_Hans: 告警事件数据
|
||||
pt_BR: alert_data
|
||||
human_description:
|
||||
en_US: alert_data
|
||||
zh_Hans: 告警事件数据
|
||||
pt_BR: alert_data
|
||||
llm_description: alert event data
|
||||
form: llm
|
||||
@ -0,0 +1,31 @@
|
||||
import json
|
||||
from collections.abc import Generator
|
||||
from typing import Any, Optional
|
||||
|
||||
from core.tools.builtin_tool.tool import BuiltinTool
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
|
||||
|
||||
class ThresholdTool(BuiltinTool):
|
||||
def _invoke(
|
||||
self,
|
||||
user_id: str,
|
||||
tool_parameters: dict[str, Any],
|
||||
conversation_id: Optional[str] = None,
|
||||
app_id: Optional[str] = None,
|
||||
message_id: Optional[str] = None,
|
||||
) -> Generator[ToolInvokeMessage, None, None]:
|
||||
metric = tool_parameters.get('metric_data')
|
||||
metric_data = json.loads(metric)
|
||||
threshold = float(tool_parameters.get('threshold'))
|
||||
res = {}
|
||||
for k, v in metric_data['data'].items():
|
||||
if v > threshold:
|
||||
res[str(k)] = v
|
||||
res = json.dumps({
|
||||
"type": 'llm',
|
||||
"display": False,
|
||||
"data": res
|
||||
})
|
||||
|
||||
yield self.create_text_message(res)
|
||||
@ -0,0 +1,40 @@
|
||||
identity:
|
||||
name: threshold
|
||||
author: APO
|
||||
label:
|
||||
en_US: threshold
|
||||
zh_Hans: 阈值判定
|
||||
pt_BR: threshold
|
||||
description:
|
||||
human:
|
||||
en_US: A tool for getting the current time
|
||||
zh_Hans: 阈值判定
|
||||
pt_BR: A tool for getting the current time
|
||||
llm: A tool for getting the current time
|
||||
parameters:
|
||||
- name: metric_data
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: metric_data
|
||||
zh_Hans: 指标数据
|
||||
pt_BR: metric_data
|
||||
human_description:
|
||||
en_US: Time format in strftime standard
|
||||
zh_Hans: 时序指标数据
|
||||
pt_BR: Time format in strftime standard
|
||||
llm_description: metric type data
|
||||
form: llm
|
||||
- name: threshold
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: threshold
|
||||
zh_Hans: 阈值
|
||||
pt_BR: threshold
|
||||
human_description:
|
||||
en_US: Time format in strftime standard
|
||||
zh_Hans: 阈值判定
|
||||
pt_BR: Time format in strftime standard
|
||||
llm_description: data threshold judgement
|
||||
form: llm
|
||||
@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.666992 8.00008C0.666992 3.94999 3.95024 0.666748 8.00033 0.666748C12.0504 0.666748 15.3337 3.94999 15.3337 8.00008C15.3337 12.0502 12.0504 15.3334 8.00033 15.3334C3.95024 15.3334 0.666992 12.0502 0.666992 8.00008ZM8.66699 4.00008C8.66699 3.63189 8.36852 3.33341 8.00033 3.33341C7.63213 3.33341 7.33366 3.63189 7.33366 4.00008V8.00008C7.33366 8.2526 7.47633 8.48344 7.70218 8.59637L10.3688 9.9297C10.6982 10.0944 11.0986 9.96088 11.2633 9.63156C11.4279 9.30224 11.2945 8.90179 10.9651 8.73713L8.66699 7.58806V4.00008Z" fill="#EC4A0A"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 691 B |
@ -0,0 +1,8 @@
|
||||
from typing import Any
|
||||
|
||||
from core.tools.builtin_tool.provider import BuiltinToolProviderController
|
||||
|
||||
|
||||
class APORuleProvider(BuiltinToolProviderController):
|
||||
def _validate_credentials(self, user_id: str, credentials: dict[str, Any]) -> None:
|
||||
pass
|
||||
@ -0,0 +1,14 @@
|
||||
identity:
|
||||
author: APO
|
||||
name: apo_rule
|
||||
label:
|
||||
en_US: APORule
|
||||
zh_Hans: APO规则执行
|
||||
pt_BR: APOSelect
|
||||
description:
|
||||
en_US: APO execute rule.
|
||||
zh_Hans: APO规则执行
|
||||
pt_BR: APO execute rule.
|
||||
icon: icon.svg
|
||||
tags:
|
||||
- utilities
|
||||
@ -0,0 +1,29 @@
|
||||
|
||||
from collections.abc import Generator
|
||||
from typing import Any, Optional
|
||||
|
||||
from core.tools.builtin_tool.tool import BuiltinTool
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
|
||||
|
||||
class AlertRuleTool(BuiltinTool):
|
||||
def _invoke(
|
||||
self,
|
||||
user_id: str,
|
||||
tool_parameters: dict[str, Any],
|
||||
conversation_id: Optional[str] = None,
|
||||
app_id: Optional[str] = None,
|
||||
message_id: Optional[str] = None,
|
||||
) -> Generator[ToolInvokeMessage, None, None]:
|
||||
"""
|
||||
invoke tools
|
||||
"""
|
||||
# data = tool_parameters.get("data")
|
||||
rule = tool_parameters.get("rule")
|
||||
# res = f'{rule}\n{data}'
|
||||
# list = json.dumps({
|
||||
# 'type': 'alert',
|
||||
# 'display': False,
|
||||
# 'data': res,
|
||||
# })
|
||||
yield self.create_text_message(rule)
|
||||
@ -0,0 +1,40 @@
|
||||
identity:
|
||||
name: alert_rule
|
||||
author: APO
|
||||
label:
|
||||
en_US: alert_rule
|
||||
zh_Hans: 告警规则执行
|
||||
pt_BR: alert_rule
|
||||
description:
|
||||
human:
|
||||
en_US: alert rule execute
|
||||
zh_Hans: 告警规则执行
|
||||
pt_BR: alert rule execute
|
||||
llm: alert rule execute
|
||||
parameters:
|
||||
# - name: data
|
||||
# type: string
|
||||
# required: false
|
||||
# label:
|
||||
# en_US: data
|
||||
# zh_Hans: 需要大模型分析的数据
|
||||
# pt_BR: data
|
||||
# human_description:
|
||||
# en_US: llm analysis data
|
||||
# zh_Hans: 大模型分析数据
|
||||
# pt_BR: llm analysis data
|
||||
# llm_description: llm analysis data
|
||||
# form: llm
|
||||
- name: rule
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: rule
|
||||
zh_Hans: 自然语言描述的规则
|
||||
pt_BR: rule
|
||||
human_description:
|
||||
en_US: rule
|
||||
zh_Hans: 自然语言描述的规则
|
||||
pt_BR: rule
|
||||
llm_description: rule
|
||||
form: llm
|
||||
@ -0,0 +1,53 @@
|
||||
import json
|
||||
from collections.abc import Generator
|
||||
from typing import Any, Optional
|
||||
|
||||
from core.tools.builtin_tool.tool import BuiltinTool
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
|
||||
|
||||
class RootCauseTool(BuiltinTool):
|
||||
def _invoke(
|
||||
self,
|
||||
user_id: str,
|
||||
tool_parameters: dict[str, Any],
|
||||
conversation_id: Optional[str] = None,
|
||||
app_id: Optional[str] = None,
|
||||
message_id: Optional[str] = None,
|
||||
) -> Generator[ToolInvokeMessage, None, None]:
|
||||
"""
|
||||
invoke tools
|
||||
"""
|
||||
llm_text = tool_parameters.get("llm_text")
|
||||
node_lists, text = self._get_node_list(llm_text)
|
||||
|
||||
yield self.create_text_message(text)
|
||||
yield self.create_json_message({'nodelists': node_lists})
|
||||
|
||||
def _get_node_list(self, data: str) -> tuple[list, str]:
|
||||
data = data.strip('```')
|
||||
data = data.strip('json')
|
||||
text = ""
|
||||
try:
|
||||
nodeinfo = json.loads(data)
|
||||
nodeList = []
|
||||
if "nodeName" in nodeinfo:
|
||||
service = nodeinfo["nodeName"].split('_#')[0]
|
||||
ep = nodeinfo["nodeName"].split('_#')[1]
|
||||
endpoint = ep.strip('"')
|
||||
endpoint = endpoint.strip("'")
|
||||
nodeList.append({'service': service, 'endpoint': endpoint, "isRoot": True})
|
||||
text = text + f'造成根因的节点是{nodeinfo['nodeName']}\n'
|
||||
|
||||
if "otherNodeName" in data:
|
||||
for node in nodeinfo["otherNodeName"]:
|
||||
tmpservice = node.split('_#')[0]
|
||||
ep = node.split('_#')[1]
|
||||
tmpendpoint = ep.strip('"')
|
||||
tmpendpoint = tmpendpoint.strip("'")
|
||||
nodeList.append({'service': tmpservice, 'endpoint': tmpendpoint, "isRoot": False})
|
||||
otherstr = ",".join(nodeinfo["otherNodeName"])
|
||||
text = text + f'疑似根因节点有{otherstr}\n'
|
||||
return nodeList, text
|
||||
except Exception as e:
|
||||
return [], ""
|
||||
@ -0,0 +1,27 @@
|
||||
identity:
|
||||
name: root_cause
|
||||
author: APO
|
||||
label:
|
||||
en_US: root_cause
|
||||
zh_Hans: 提取根因节点
|
||||
pt_BR: root_cause
|
||||
description:
|
||||
human:
|
||||
en_US: get root cause
|
||||
zh_Hans: 获取根因节点
|
||||
pt_BR: get root cause
|
||||
llm: get root cause node
|
||||
parameters:
|
||||
- name: llm_text
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: llm_text
|
||||
zh_Hans: 大模型返回结果
|
||||
pt_BR: llm_text
|
||||
human_description:
|
||||
en_US: llm_text
|
||||
zh_Hans: 大模型返回结果
|
||||
pt_BR: llm_text
|
||||
llm_description: rule
|
||||
form: llm
|
||||
@ -0,0 +1,3 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="0 0 16 16" fill="none">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M0.666992 8.00008C0.666992 3.94999 3.95024 0.666748 8.00033 0.666748C12.0504 0.666748 15.3337 3.94999 15.3337 8.00008C15.3337 12.0502 12.0504 15.3334 8.00033 15.3334C3.95024 15.3334 0.666992 12.0502 0.666992 8.00008ZM8.66699 4.00008C8.66699 3.63189 8.36852 3.33341 8.00033 3.33341C7.63213 3.33341 7.33366 3.63189 7.33366 4.00008V8.00008C7.33366 8.2526 7.47633 8.48344 7.70218 8.59637L10.3688 9.9297C10.6982 10.0944 11.0986 9.96088 11.2633 9.63156C11.4279 9.30224 11.2945 8.90179 10.9651 8.73713L8.66699 7.58806V4.00008Z" fill="#EC4A0A"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 691 B |
@ -0,0 +1,8 @@
|
||||
from typing import Any
|
||||
|
||||
from core.tools.builtin_tool.provider import BuiltinToolProviderController
|
||||
|
||||
|
||||
class APOSelectProvider(BuiltinToolProviderController):
|
||||
def _validate_credentials(self, user_id: str, credentials: dict[str, Any]) -> None:
|
||||
pass
|
||||
@ -0,0 +1,14 @@
|
||||
identity:
|
||||
author: APO
|
||||
name: apo_select
|
||||
label:
|
||||
en_US: APOSelect
|
||||
zh_Hans: APO查询数据
|
||||
pt_BR: APOSelect
|
||||
description:
|
||||
en_US: APO query data.
|
||||
zh_Hans: APO查询数据的工具。
|
||||
pt_BR: APO query data.
|
||||
icon: icon.svg
|
||||
tags:
|
||||
- utilities
|
||||
@ -0,0 +1,74 @@
|
||||
import json
|
||||
from collections.abc import Generator
|
||||
from typing import Any, Optional
|
||||
|
||||
import requests
|
||||
|
||||
from configs import dify_config
|
||||
from core.tools.builtin_tool.tool import BuiltinTool
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
|
||||
|
||||
class AlertTool(BuiltinTool):
|
||||
def _invoke(
|
||||
self,
|
||||
user_id: str,
|
||||
tool_parameters: dict[str, Any],
|
||||
conversation_id: Optional[str] = None,
|
||||
app_id: Optional[str] = None,
|
||||
message_id: Optional[str] = None,
|
||||
) -> Generator[ToolInvokeMessage, None, None]:
|
||||
service = tool_parameters.get("service")
|
||||
endpoint = tool_parameters.get("endpoint")
|
||||
start_time = tool_parameters.get("start_time")
|
||||
end_time = tool_parameters.get("end_time")
|
||||
params = {
|
||||
'service': service,
|
||||
'endpoint': endpoint,
|
||||
'startTime': start_time,
|
||||
'endTime': end_time,
|
||||
'anormalTypes': "app,container,infra,network,error,appInstance",
|
||||
'deltaStartTime': start_time,
|
||||
'deltaEndTime': end_time,
|
||||
'step': self.get_step(start_time, end_time),
|
||||
}
|
||||
resp = requests.post(dify_config.APO_BACKEND_URL + '/api/alerts/descendant/anormal/delta', json=params)
|
||||
list = resp.json()
|
||||
list = json.dumps({
|
||||
'type': 'alert',
|
||||
'display': True,
|
||||
'data': list,
|
||||
})
|
||||
yield self.create_text_message(list)
|
||||
|
||||
def get_step(self, start_time, end_time):
|
||||
time_diff = end_time - start_time
|
||||
|
||||
SECOND = 1000000 # microseconds
|
||||
MINUTE = 60 * SECOND
|
||||
HOUR = 60 * MINUTE
|
||||
|
||||
step = SECOND # default step is 1 second
|
||||
|
||||
if time_diff <= 15 * MINUTE:
|
||||
step = 30 * SECOND
|
||||
elif time_diff <= 30 * MINUTE:
|
||||
step = 1 * MINUTE
|
||||
elif time_diff <= 1 * HOUR:
|
||||
step = 2 * MINUTE
|
||||
elif time_diff <= 1.5 * HOUR:
|
||||
step = 3 * MINUTE
|
||||
elif time_diff <= 3 * HOUR:
|
||||
step = 6 * MINUTE
|
||||
elif time_diff <= 6 * HOUR:
|
||||
step = 12 * MINUTE
|
||||
elif time_diff <= 12 * HOUR:
|
||||
step = 24 * MINUTE
|
||||
elif time_diff <= 15 * HOUR:
|
||||
step = 30 * MINUTE
|
||||
elif time_diff <= 30 * HOUR:
|
||||
step = 1 * HOUR
|
||||
else:
|
||||
step = ((time_diff + 30 * SECOND - 1) // (30 * SECOND)) * SECOND
|
||||
|
||||
return step
|
||||
@ -0,0 +1,66 @@
|
||||
identity:
|
||||
name: alert
|
||||
author: APO
|
||||
label:
|
||||
en_US: toplogy
|
||||
zh_Hans: 获取当前入口拓扑的告警事件
|
||||
pt_BR: toplogy
|
||||
description:
|
||||
human:
|
||||
en_US: A tool for getting the current time.
|
||||
zh_Hans: 获取当前入口拓扑的告警事件
|
||||
pt_BR: A tool for getting the current time.
|
||||
llm: A tool for getting the current time.
|
||||
parameters:
|
||||
- name: service
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: service
|
||||
zh_Hans: 服务名
|
||||
pt_BR: service
|
||||
human_description:
|
||||
en_US: Time format in strftime standard.
|
||||
zh_Hans: 拓扑入口服务名
|
||||
pt_BR: Time format in strftime standard.
|
||||
llm_description: toplogy service name
|
||||
form: llm
|
||||
- name: endpoint
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: endpoint
|
||||
zh_Hans: 服务端点
|
||||
pt_BR: endpoint
|
||||
human_description:
|
||||
en_US: Time format in strftime standard.
|
||||
zh_Hans: 拓扑入口服务端点
|
||||
pt_BR: Time format in strftime standard.
|
||||
llm_description: toplogy endpoint
|
||||
form: llm
|
||||
- name: start_time
|
||||
type: number
|
||||
required: false
|
||||
label:
|
||||
en_US: start_time
|
||||
zh_Hans: 开始时间
|
||||
pt_BR: start_time
|
||||
human_description:
|
||||
en_US: Time format in strftime standard.
|
||||
zh_Hans: 查询开始时间。
|
||||
pt_BR: Time format in strftime standard.
|
||||
llm_description: Time format in strftime standard.
|
||||
form: llm
|
||||
- name: end_time
|
||||
type: number
|
||||
required: false
|
||||
label:
|
||||
en_US: end_time
|
||||
zh_Hans: 结束时间
|
||||
pt_BR: end_time
|
||||
human_description:
|
||||
en_US: Time format in strftime standard.
|
||||
zh_Hans: 指定查询的结束时间
|
||||
pt_BR: Time format in strftime standard.
|
||||
llm_description: Time format in strftime standard.
|
||||
form: llm
|
||||
@ -0,0 +1,42 @@
|
||||
import json
|
||||
from collections.abc import Generator
|
||||
from typing import Any, Optional
|
||||
|
||||
import requests
|
||||
|
||||
from configs import dify_config
|
||||
from core.tools.builtin_tool.tool import BuiltinTool
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
|
||||
|
||||
class SelectContainerCPUTool(BuiltinTool):
|
||||
def _invoke(
|
||||
self,
|
||||
user_id: str,
|
||||
tool_parameters: dict[str, Any],
|
||||
conversation_id: Optional[str] = None,
|
||||
app_id: Optional[str] = None,
|
||||
message_id: Optional[str] = None,
|
||||
) -> Generator[ToolInvokeMessage, None, None]:
|
||||
container_name = tool_parameters.get("container_name")
|
||||
start_time = tool_parameters.get("start_time")
|
||||
end_time = tool_parameters.get("end_time")
|
||||
pmql = 'rate(container_cpu_usage_seconds_total{container="' + container_name + '"}[1m])'
|
||||
params = {
|
||||
'query': pmql,
|
||||
'start': start_time,
|
||||
'end': end_time,
|
||||
'step': '1m'
|
||||
}
|
||||
url = dify_config.APO_VM_URL + "/api/v1/query_range"
|
||||
resp = requests.get(url, params=params)
|
||||
list = resp.json()['data']['result'][0]
|
||||
res = {}
|
||||
for item in list['values']:
|
||||
res[str(item[0] * 1000)] = float(item[1])
|
||||
list = json.dumps({
|
||||
'type': 'cpu',
|
||||
'display': True,
|
||||
'data': res,
|
||||
})
|
||||
yield self.create_text_message(list)
|
||||
@ -0,0 +1,53 @@
|
||||
identity:
|
||||
name: select_container_cpu
|
||||
author: APO
|
||||
label:
|
||||
en_US: select_container_cpu
|
||||
zh_Hans: 查询容器CPU占用
|
||||
pt_BR: select_container_cpu
|
||||
description:
|
||||
human:
|
||||
en_US: A tool for getting container cpu.
|
||||
zh_Hans: 查询容器CPU占用
|
||||
pt_BR: A tool for getting container cpu.
|
||||
llm: A tool for getting container cpu.
|
||||
parameters:
|
||||
- name: container_name
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: container_name
|
||||
zh_Hans: 容器名
|
||||
pt_BR: container_name
|
||||
human_description:
|
||||
en_US: Time format in strftime standard.
|
||||
zh_Hans: 查询指定Pod的CPU占用。
|
||||
pt_BR: Time format in strftime standard.
|
||||
llm_description: Time format in strftime standard.
|
||||
form: llm
|
||||
- name: start_time
|
||||
type: number
|
||||
required: false
|
||||
label:
|
||||
en_US: start_time
|
||||
zh_Hans: 开始时间
|
||||
pt_BR: start_time
|
||||
human_description:
|
||||
en_US: Time format in strftime standard.
|
||||
zh_Hans: 指定查询CPU指标的开始时间。
|
||||
pt_BR: Time format in strftime standard.
|
||||
llm_description: Time format in strftime standard.
|
||||
form: llm
|
||||
- name: end_time
|
||||
type: number
|
||||
required: false
|
||||
label:
|
||||
en_US: end_time
|
||||
zh_Hans: 结束时间
|
||||
pt_BR: end_time
|
||||
human_description:
|
||||
en_US: Time format in strftime standard.
|
||||
zh_Hans: 指定查询CPU指标的结束时间。
|
||||
pt_BR: Time format in strftime standard.
|
||||
llm_description: Time format in strftime standard.
|
||||
form: llm
|
||||
@ -0,0 +1,41 @@
|
||||
import json
|
||||
from collections.abc import Generator
|
||||
from typing import Any, Optional
|
||||
|
||||
import requests
|
||||
|
||||
from configs import dify_config
|
||||
from core.tools.builtin_tool.tool import BuiltinTool
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
|
||||
|
||||
class SelectContainerRSSTool(BuiltinTool):
|
||||
def _invoke(
|
||||
self,
|
||||
user_id: str,
|
||||
tool_parameters: dict[str, Any],
|
||||
conversation_id: Optional[str] = None,
|
||||
app_id: Optional[str] = None,
|
||||
message_id: Optional[str] = None,
|
||||
) -> Generator[ToolInvokeMessage, None, None]:
|
||||
container_name = tool_parameters.get("container_name")
|
||||
start_time = tool_parameters.get("start_time")
|
||||
end_time = tool_parameters.get("end_time")
|
||||
pmql = 'container_memory_rss{container="' + container_name + '"}'
|
||||
params = {
|
||||
'query': pmql,
|
||||
'start': start_time,
|
||||
'end': end_time,
|
||||
'step': '1m'
|
||||
}
|
||||
resp = requests.get(dify_config.APO_VM_URL + '/api/v1/query_range', params=params)
|
||||
list = resp.json()['data']['result'][0]
|
||||
res = {}
|
||||
for item in list['values']:
|
||||
res[str(item[0] * 1000)] = float(item[1])
|
||||
list = json.dumps({
|
||||
'type': 'memory',
|
||||
'display': True,
|
||||
'data': res,
|
||||
})
|
||||
yield self.create_text_message(list)
|
||||
@ -0,0 +1,53 @@
|
||||
identity:
|
||||
name: select_container_rss
|
||||
author: APO
|
||||
label:
|
||||
en_US: select_container_rss
|
||||
zh_Hans: 查询容器驻留内存
|
||||
pt_BR: select_container_rss
|
||||
description:
|
||||
human:
|
||||
en_US: A tool for getting container rss.
|
||||
zh_Hans: 查询容器CPU占用
|
||||
pt_BR: A tool for getting container rss.
|
||||
llm: A tool for getting container rss.
|
||||
parameters:
|
||||
- name: container_name
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: container_name
|
||||
zh_Hans: 容器名
|
||||
pt_BR: container_name
|
||||
human_description:
|
||||
en_US: Time format in strftime standard.
|
||||
zh_Hans: 查询指定Pod的CPU占用。
|
||||
pt_BR: Time format in strftime standard.
|
||||
llm_description: Time format in strftime standard.
|
||||
form: llm
|
||||
- name: start_time
|
||||
type: number
|
||||
required: false
|
||||
label:
|
||||
en_US: start_time
|
||||
zh_Hans: 开始时间
|
||||
pt_BR: start_time
|
||||
human_description:
|
||||
en_US: Time format in strftime standard.
|
||||
zh_Hans: 指定查询CPU指标的开始时间。
|
||||
pt_BR: Time format in strftime standard.
|
||||
llm_description: Time format in strftime standard.
|
||||
form: llm
|
||||
- name: end_time
|
||||
type: number
|
||||
required: false
|
||||
label:
|
||||
en_US: end_time
|
||||
zh_Hans: 结束时间
|
||||
pt_BR: end_time
|
||||
human_description:
|
||||
en_US: Time format in strftime standard.
|
||||
zh_Hans: 指定查询CPU指标的结束时间。
|
||||
pt_BR: Time format in strftime standard.
|
||||
llm_description: Time format in strftime standard.
|
||||
form: llm
|
||||
@ -0,0 +1,42 @@
|
||||
import json
|
||||
from collections.abc import Generator
|
||||
from typing import Any, Optional
|
||||
|
||||
import requests
|
||||
|
||||
from configs import dify_config
|
||||
from core.tools.builtin_tool.tool import BuiltinTool
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
|
||||
|
||||
class FaultLogTool(BuiltinTool):
|
||||
def _invoke(
|
||||
self,
|
||||
user_id: str,
|
||||
tool_parameters: dict[str, Any],
|
||||
conversation_id: Optional[str] = None,
|
||||
app_id: Optional[str] = None,
|
||||
message_id: Optional[str] = None,
|
||||
) -> Generator[ToolInvokeMessage, None, None]:
|
||||
service = tool_parameters.get("service")
|
||||
start_time = tool_parameters.get("start_time")
|
||||
end_time = tool_parameters.get("end_time")
|
||||
params = {
|
||||
'service': [service],
|
||||
'startTime': start_time,
|
||||
'endTime': end_time,
|
||||
'pageNum': 1,
|
||||
'pageSize': 10
|
||||
}
|
||||
url = dify_config.APO_BACKEND_URL + "/api/log/fault/pagelist"
|
||||
resp = requests.post(url, json=params)
|
||||
list = resp.json()['list'][0]
|
||||
|
||||
content_url = dify_config.APO_BACKEND_URL + "/api/log/fault/content"
|
||||
content = requests.post(content_url, json=list).json()
|
||||
list = json.dumps({
|
||||
'type': 'log',
|
||||
'display': True,
|
||||
'data': content,
|
||||
})
|
||||
yield self.create_text_message(list)
|
||||
@ -0,0 +1,53 @@
|
||||
identity:
|
||||
name: fault_log
|
||||
author: APO
|
||||
label:
|
||||
en_US: fault_log
|
||||
zh_Hans: 获取故障现场日志
|
||||
pt_BR: fault_log
|
||||
description:
|
||||
human:
|
||||
en_US: A tool for getting fault log.
|
||||
zh_Hans: 查询容器CPU占用
|
||||
pt_BR: A tool for getting fault log.
|
||||
llm: A tool for getting fault log.
|
||||
parameters:
|
||||
- name: service
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: service
|
||||
zh_Hans: 服务名
|
||||
pt_BR: service
|
||||
human_description:
|
||||
en_US: Time format in strftime standard.
|
||||
zh_Hans: 查询指定Pod的CPU占用。
|
||||
pt_BR: Time format in strftime standard.
|
||||
llm_description: Time format in strftime standard.
|
||||
form: llm
|
||||
- name: start_time
|
||||
type: number
|
||||
required: false
|
||||
label:
|
||||
en_US: start_time
|
||||
zh_Hans: 开始时间
|
||||
pt_BR: start_time
|
||||
human_description:
|
||||
en_US: Time format in strftime standard.
|
||||
zh_Hans: 指定查询CPU指标的开始时间。
|
||||
pt_BR: Time format in strftime standard.
|
||||
llm_description: Time format in strftime standard.
|
||||
form: llm
|
||||
- name: end_time
|
||||
type: number
|
||||
required: false
|
||||
label:
|
||||
en_US: end_time
|
||||
zh_Hans: 结束时间
|
||||
pt_BR: end_time
|
||||
human_description:
|
||||
en_US: Time format in strftime standard.
|
||||
zh_Hans: 指定查询CPU指标的结束时间。
|
||||
pt_BR: Time format in strftime standard.
|
||||
llm_description: Time format in strftime standard.
|
||||
form: llm
|
||||
@ -0,0 +1,88 @@
|
||||
import json
|
||||
from collections.abc import Generator
|
||||
from typing import Any, Optional
|
||||
|
||||
import requests
|
||||
|
||||
from configs import dify_config
|
||||
from core.tools.builtin_tool.tool import BuiltinTool
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
|
||||
|
||||
class FaultLogTool(BuiltinTool):
|
||||
def _invoke(
|
||||
self,
|
||||
user_id: str,
|
||||
tool_parameters: dict[str, Any],
|
||||
conversation_id: Optional[str] = None,
|
||||
app_id: Optional[str] = None,
|
||||
message_id: Optional[str] = None,
|
||||
) -> Generator[ToolInvokeMessage, None, None]:
|
||||
service = tool_parameters.get("service")
|
||||
endpoint = tool_parameters.get("endpoint")
|
||||
entryService = tool_parameters.get("entryService")
|
||||
entryEndpoint = tool_parameters.get("entryEndpoint")
|
||||
start_time = tool_parameters.get("start_time")
|
||||
end_time = tool_parameters.get("end_time")
|
||||
type = tool_parameters.get("type")
|
||||
|
||||
params = {
|
||||
"anormalTypes": "app,container,infra,network,error,appInstance",
|
||||
"endTime": end_time,
|
||||
"endpoint": endpoint,
|
||||
"entryEndpoint": entryEndpoint,
|
||||
"entryService": entryService,
|
||||
"service": service,
|
||||
"startTime": start_time,
|
||||
"step": self.get_step(start_time, end_time),
|
||||
"type": [type],
|
||||
"withTopology": True,
|
||||
}
|
||||
|
||||
url = "http://192.168.1.6:13680/api/nodeinfo"
|
||||
res = {}
|
||||
with requests.post(url, json=params, stream=True) as response:
|
||||
# 逐行读取流式响应
|
||||
for line in response.iter_lines():
|
||||
if line: # 过滤空行
|
||||
# 解码字节为字符串
|
||||
decoded_line = line.decode('utf-8')
|
||||
res = json.loads(decoded_line[5:].strip())
|
||||
list = json.dumps({
|
||||
'type': 'nodeinfo',
|
||||
'display': True,
|
||||
'data': res,
|
||||
})
|
||||
yield self.create_text_message(list)
|
||||
|
||||
def get_step(self, start_time, end_time):
|
||||
time_diff = end_time - start_time
|
||||
|
||||
SECOND = 1000000 # microseconds
|
||||
MINUTE = 60 * SECOND
|
||||
HOUR = 60 * MINUTE
|
||||
|
||||
step = SECOND # default step is 1 second
|
||||
|
||||
if time_diff <= 15 * MINUTE:
|
||||
step = 30 * SECOND
|
||||
elif time_diff <= 30 * MINUTE:
|
||||
step = 1 * MINUTE
|
||||
elif time_diff <= 1 * HOUR:
|
||||
step = 2 * MINUTE
|
||||
elif time_diff <= 1.5 * HOUR:
|
||||
step = 3 * MINUTE
|
||||
elif time_diff <= 3 * HOUR:
|
||||
step = 6 * MINUTE
|
||||
elif time_diff <= 6 * HOUR:
|
||||
step = 12 * MINUTE
|
||||
elif time_diff <= 12 * HOUR:
|
||||
step = 24 * MINUTE
|
||||
elif time_diff <= 15 * HOUR:
|
||||
step = 30 * MINUTE
|
||||
elif time_diff <= 30 * HOUR:
|
||||
step = 1 * HOUR
|
||||
else:
|
||||
step = ((time_diff + 30 * SECOND - 1) // (30 * SECOND)) * SECOND
|
||||
|
||||
return step
|
||||
@ -0,0 +1,105 @@
|
||||
identity:
|
||||
name: node_info
|
||||
author: APO
|
||||
label:
|
||||
en_US: node_info
|
||||
zh_Hans: 获取节点信息
|
||||
pt_BR: node_info
|
||||
description:
|
||||
human:
|
||||
en_US: A tool for getting fault log.
|
||||
zh_Hans: 获取节点信息
|
||||
pt_BR: A tool for getting fault log.
|
||||
llm: A tool for getting fault log.
|
||||
parameters:
|
||||
- name: entryService
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: entryService
|
||||
zh_Hans: 入口服务名
|
||||
pt_BR: entryService
|
||||
human_description:
|
||||
en_US: Time format in strftime standard.
|
||||
zh_Hans: 拓扑入口服务名
|
||||
pt_BR: Time format in strftime standard.
|
||||
llm_description: toplogy service name
|
||||
form: llm
|
||||
- name: entryEndpoint
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: entryEndpoint
|
||||
zh_Hans: 入口服务端点
|
||||
pt_BR: entryEndpoint
|
||||
human_description:
|
||||
en_US: Time format in strftime standard.
|
||||
zh_Hans: 拓扑入口服务端点
|
||||
pt_BR: Time format in strftime standard.
|
||||
llm_description: toplogy endpoint
|
||||
form: llm
|
||||
- name: service
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: service
|
||||
zh_Hans: 服务名
|
||||
pt_BR: service
|
||||
human_description:
|
||||
en_US: Time format in strftime standard.
|
||||
zh_Hans: 查询指定服务的名称
|
||||
pt_BR: Time format in strftime standard.
|
||||
llm_description: Time format in strftime standard.
|
||||
form: llm
|
||||
- name: endpoint
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: endpoint
|
||||
zh_Hans: 服务端点
|
||||
pt_BR: endpoint
|
||||
human_description:
|
||||
en_US: Time format in strftime standard.
|
||||
zh_Hans: 指定服务的端点
|
||||
pt_BR: Time format in strftime standard.
|
||||
llm_description: toplogy endpoint
|
||||
form: llm
|
||||
- name: start_time
|
||||
type: number
|
||||
required: false
|
||||
label:
|
||||
en_US: start_time
|
||||
zh_Hans: 开始时间
|
||||
pt_BR: start_time
|
||||
human_description:
|
||||
en_US: Time format in strftime standard.
|
||||
zh_Hans: 指定查询CPU指标的开始时间。
|
||||
pt_BR: Time format in strftime standard.
|
||||
llm_description: Time format in strftime standard.
|
||||
form: llm
|
||||
- name: end_time
|
||||
type: number
|
||||
required: false
|
||||
label:
|
||||
en_US: end_time
|
||||
zh_Hans: 结束时间
|
||||
pt_BR: end_time
|
||||
human_description:
|
||||
en_US: Time format in strftime standard.
|
||||
zh_Hans: 指定查询CPU指标的结束时间。
|
||||
pt_BR: Time format in strftime standard.
|
||||
llm_description: Time format in strftime standard.
|
||||
form: llm
|
||||
- name: type
|
||||
type: string
|
||||
required: false
|
||||
label:
|
||||
en_US: type
|
||||
zh_Hans: 查询数据类型(log, slow, error)
|
||||
pt_BR: type
|
||||
human_description:
|
||||
en_US: Time format in strftime standard.
|
||||
zh_Hans: 指定查询数据类型(log, slow, error)。
|
||||
pt_BR: Time format in strftime standard.
|
||||
llm_description: Time format in strftime standard.
|
||||
form: llm
|
||||
@ -0,0 +1,42 @@
|
||||
import json
|
||||
from collections.abc import Generator
|
||||
from typing import Any, Optional
|
||||
|
||||
import requests
|
||||
|
||||
from configs import dify_config
|
||||
from core.tools.builtin_tool.tool import BuiltinTool
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
|
||||
|
||||
class SelectCPUTool(BuiltinTool):
|
||||
def _invoke(
|
||||
self,
|
||||
user_id: str,
|
||||
tool_parameters: dict[str, Any],
|
||||
conversation_id: Optional[str] = None,
|
||||
app_id: Optional[str] = None,
|
||||
message_id: Optional[str] = None,
|
||||
) -> Generator[ToolInvokeMessage, None, None]:
|
||||
node_name = tool_parameters.get("node_name")
|
||||
start_time = tool_parameters.get("start_time")
|
||||
end_time = tool_parameters.get("end_time")
|
||||
sumql = 'sum by (instance_name) (avg by (mode, instance_name)'
|
||||
pmql = sumql + ' (rate(node_cpu_seconds_total{mode!="idle", instance_name="' + node_name + '"}[1m])))'
|
||||
params = {
|
||||
'query': pmql,
|
||||
'start': start_time,
|
||||
'end': end_time,
|
||||
'step': '1m'
|
||||
}
|
||||
resp = requests.get(dify_config.APO_VM_URL + '/api/v1/query_range', params=params)
|
||||
list = resp.json()['data']['result'][0]
|
||||
res = {}
|
||||
for item in list['values']:
|
||||
res[str(item[0] * 1000)] = float(item[1])
|
||||
list = json.dumps({
|
||||
'type': 'cpu',
|
||||
'display': True,
|
||||
'data': res,
|
||||
})
|
||||
yield self.create_text_message(list)
|
||||
@ -0,0 +1,53 @@
|
||||
identity:
|
||||
name: select_cpu
|
||||
author: APO
|
||||
label:
|
||||
en_US: select_cpu
|
||||
zh_Hans: 查询CPU主机指标
|
||||
pt_BR: select_cpu
|
||||
description:
|
||||
human:
|
||||
en_US: A tool for getting the current time.
|
||||
zh_Hans: 查询CPU主机指标
|
||||
pt_BR: A tool for getting the current time.
|
||||
llm: A tool for getting the current time.
|
||||
parameters:
|
||||
- name: node_name
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: node_name
|
||||
zh_Hans: 主机名
|
||||
pt_BR: node_name
|
||||
human_description:
|
||||
en_US: Time format in strftime standard.
|
||||
zh_Hans: 指定查询CPU所在的主机名。
|
||||
pt_BR: Time format in strftime standard.
|
||||
llm_description: Time format in strftime standard.
|
||||
form: llm
|
||||
- name: start_time
|
||||
type: number
|
||||
required: false
|
||||
label:
|
||||
en_US: start_time
|
||||
zh_Hans: 开始时间
|
||||
pt_BR: start_time
|
||||
human_description:
|
||||
en_US: Time format in strftime standard.
|
||||
zh_Hans: 指定查询CPU指标的开始时间。
|
||||
pt_BR: Time format in strftime standard.
|
||||
llm_description: Time format in strftime standard.
|
||||
form: llm
|
||||
- name: end_time
|
||||
type: number
|
||||
required: false
|
||||
label:
|
||||
en_US: end_time
|
||||
zh_Hans: 结束时间
|
||||
pt_BR: end_time
|
||||
human_description:
|
||||
en_US: Time format in strftime standard.
|
||||
zh_Hans: 指定查询CPU指标的结束时间。
|
||||
pt_BR: Time format in strftime standard.
|
||||
llm_description: Time format in strftime standard.
|
||||
form: llm
|
||||
@ -0,0 +1,42 @@
|
||||
import json
|
||||
from collections.abc import Generator
|
||||
from typing import Any, Optional
|
||||
|
||||
import requests
|
||||
|
||||
from configs import dify_config
|
||||
from core.tools.builtin_tool.tool import BuiltinTool
|
||||
from core.tools.entities.tool_entities import ToolInvokeMessage
|
||||
|
||||
|
||||
class TopologyTool(BuiltinTool):
|
||||
def _invoke(
|
||||
self,
|
||||
user_id: str,
|
||||
tool_parameters: dict[str, Any],
|
||||
conversation_id: Optional[str] = None,
|
||||
app_id: Optional[str] = None,
|
||||
message_id: Optional[str] = None,
|
||||
) -> Generator[ToolInvokeMessage, None, None]:
|
||||
service = tool_parameters.get("service")
|
||||
endpoint = tool_parameters.get("endpoint")
|
||||
start_time = tool_parameters.get("start_time")
|
||||
end_time = tool_parameters.get("end_time")
|
||||
params = {
|
||||
'service': service,
|
||||
'endpoint': endpoint,
|
||||
'startTime': start_time,
|
||||
'endTime': end_time,
|
||||
'entryService': service,
|
||||
'entryEndpoint': endpoint,
|
||||
'withTopology': True,
|
||||
'removeClientCall': True,
|
||||
}
|
||||
resp = requests.get(dify_config.APO_BACKEND_URL + '/api/service/relation', params=params)
|
||||
list = resp.json()
|
||||
list = json.dumps({
|
||||
'type': 'topology',
|
||||
'display': True,
|
||||
'data': list,
|
||||
})
|
||||
yield self.create_text_message(list)
|
||||
@ -0,0 +1,66 @@
|
||||
identity:
|
||||
name: topology
|
||||
author: APO
|
||||
label:
|
||||
en_US: topology
|
||||
zh_Hans: 获取当前入口的拓扑结构
|
||||
pt_BR: topology
|
||||
description:
|
||||
human:
|
||||
en_US: A tool for getting the current time.
|
||||
zh_Hans: 获取当前入口的拓扑结构
|
||||
pt_BR: A tool for getting the current time.
|
||||
llm: A tool for getting the current time.
|
||||
parameters:
|
||||
- name: service
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: service
|
||||
zh_Hans: 服务名
|
||||
pt_BR: service
|
||||
human_description:
|
||||
en_US: Time format in strftime standard.
|
||||
zh_Hans: 拓扑入口服务名
|
||||
pt_BR: Time format in strftime standard.
|
||||
llm_description: toplogy service name
|
||||
form: llm
|
||||
- name: endpoint
|
||||
type: string
|
||||
required: true
|
||||
label:
|
||||
en_US: endpoint
|
||||
zh_Hans: 服务端点
|
||||
pt_BR: endpoint
|
||||
human_description:
|
||||
en_US: Time format in strftime standard.
|
||||
zh_Hans: 拓扑入口服务端点
|
||||
pt_BR: Time format in strftime standard.
|
||||
llm_description: toplogy endpoint
|
||||
form: llm
|
||||
- name: start_time
|
||||
type: number
|
||||
required: false
|
||||
label:
|
||||
en_US: start_time
|
||||
zh_Hans: 开始时间
|
||||
pt_BR: start_time
|
||||
human_description:
|
||||
en_US: Time format in strftime standard.
|
||||
zh_Hans: 查询开始时间。
|
||||
pt_BR: Time format in strftime standard.
|
||||
llm_description: Time format in strftime standard.
|
||||
form: llm
|
||||
- name: end_time
|
||||
type: number
|
||||
required: false
|
||||
label:
|
||||
en_US: end_time
|
||||
zh_Hans: 结束时间
|
||||
pt_BR: end_time
|
||||
human_description:
|
||||
en_US: Time format in strftime standard.
|
||||
zh_Hans: 指定查询的结束时间
|
||||
pt_BR: Time format in strftime standard.
|
||||
llm_description: Time format in strftime standard.
|
||||
form: llm
|
||||
Loading…
Reference in New Issue