Skip to content

Commit ea2e853

Browse files
Feat: Add session3 (volcengine#69)
2 parents 320cfac + 19e0d59 commit ea2e853

File tree

17 files changed

+1787
-0
lines changed

17 files changed

+1787
-0
lines changed
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
ADK_OAUTH2_USERPOOL_UID=
2+
ADK_OAUTH2_CLIENT_ID=
3+
ADK_OAUTH2_CLIENT_SECRET=
4+
ADK_OAUTH2_CALLBACK_URL=
5+
ADK_OAUTH2_SCOPE="openid profile"
6+
RUNTIME_IAM_ROLE_TRN=
7+
VOLCENGINE_ACCESS_KEY=
8+
VOLCENGINE_SECRET_KEY=
9+
DATABASE_VIKING_BASE_URL=
10+
ADAPTIVE_PERMISSION_SERVICE_KEY=
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
# See https://pre-commit.com for more information
2+
# See https://pre-commit.com/hooks.html for more hooks
3+
repos:
4+
- repo: https://github.com/pre-commit/pre-commit-hooks
5+
rev: v3.2.0
6+
hooks:
7+
- id: trailing-whitespace
8+
- id: end-of-file-fixer
9+
- id: check-yaml
10+
- id: check-added-large-files
Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
# Copyright (c) 2025 Beijing Volcano Engine Technology Co., Ltd. and/or its affiliates.
2+
#
3+
# Licensed under the Apache License, Version 2.0 (the "License");
4+
# you may not use this file except in compliance with the License.
5+
# You may obtain a copy of the License at
6+
#
7+
# http://www.apache.org/licenses/LICENSE-2.0
8+
#
9+
# Unless required by applicable law or agreed to in writing, software
10+
# distributed under the License is distributed on an "AS IS" BASIS,
11+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
# See the License for the specific language governing permissions and
13+
# limitations under the License.
14+
15+
from typing import Any
16+
17+
from veadk import Agent
18+
import json
19+
20+
import lark_oapi as lark
21+
from lark_oapi.api.docx.v1 import (
22+
RawContentDocumentRequest,
23+
RawContentDocumentResponse,
24+
)
25+
from lark_oapi.core.model import RequestOption
26+
from veadk.integrations.ve_identity import (
27+
VeIdentityFunctionTool,
28+
AuthRequestProcessor,
29+
oauth2_auth,
30+
)
31+
from google.adk.tools.function_tool import FunctionTool
32+
from google.adk.tools.tool_context import ToolContext
33+
from veadk.integrations.ve_identity.auth_mixins import OAuth2AuthMixin
34+
from veadk.memory.short_term_memory import ShortTermMemory
35+
36+
short_term_memory = ShortTermMemory(backend="local")
37+
38+
39+
async def lark_document_query(document_id: str, *, access_token: str) -> str:
40+
"""
41+
查询飞书文档内容
42+
43+
Args:
44+
document_id: 飞书文档ID(从文档链接中提取的最后一部分)
45+
access_token: 飞书 API OAuth2.0 访问令牌
46+
47+
Returns:
48+
文档内容的JSON字符串
49+
"""
50+
try:
51+
print(f"查询飞书文档: {document_id}")
52+
print(f"使用访问令牌: {access_token[:8]}...")
53+
54+
client = (
55+
lark.Client.builder()
56+
.enable_set_token(True)
57+
.log_level(lark.LogLevel.INFO)
58+
.build()
59+
)
60+
request: RawContentDocumentRequest = (
61+
RawContentDocumentRequest.builder().lang(0).document_id(document_id).build()
62+
)
63+
64+
response: RawContentDocumentResponse = client.docx.v1.document.raw_content(
65+
request, RequestOption.builder().user_access_token(access_token).build()
66+
)
67+
68+
if not response.success():
69+
lark.logger.error(
70+
f"client.docx.v1.document.raw_content failed, code: {response.code}, msg: {response.msg}, log_id: {response.get_log_id()}, resp: \n{json.dumps(json.loads(response.raw.content), indent=4, ensure_ascii=False)}"
71+
)
72+
return f"文档查询失败: {response.msg}"
73+
74+
# 处理业务结果
75+
return lark.JSON.marshal(response.data, indent=4)
76+
77+
except Exception as e:
78+
return f"文档查询出错: {str(e)}"
79+
80+
81+
# 创建使用 OAuth2 认证的飞书文档查询工具
82+
lark_doc_tool = VeIdentityFunctionTool(
83+
func=lark_document_query,
84+
auth_config=oauth2_auth(
85+
provider_name="feishu",
86+
auth_flow="USER_FEDERATION",
87+
),
88+
)
89+
90+
91+
async def clean_state(args: dict[str, Any], *, tool_context: ToolContext) -> None:
92+
"""Clean user's Oauth identity state.
93+
94+
Args:
95+
args: fixed arguments for cleaning identity state: {"op": "clean"}
96+
"""
97+
oauth_client = OAuth2AuthMixin(
98+
provider_name="feishu",
99+
auth_flow="USER_FEDERATION",
100+
force_authentication=True,
101+
)
102+
await oauth_client._get_oauth2_token_or_auth_url(tool_context=tool_context)
103+
return None
104+
105+
106+
clean_state_tool = FunctionTool(clean_state)
107+
108+
agent: Agent = Agent(
109+
name="lark_doc",
110+
tools=[lark_doc_tool, clean_state_tool],
111+
run_processor=AuthRequestProcessor(),
112+
instruction="""您是一个智能飞书文档助手,能够帮助用户查询和分析飞书文档内容。当用户提供飞书文档链接或询问文档相关问题时,您需要:
113+
114+
1. 识别用户消息中的飞书文档链接(格式如:https://feishu.feishu.cn/docx/WtwHdAngzoEU9IxyfhtcYsHCnDe)
115+
2. 提取文档ID(链接最后一部分,如:WtwHdAngzoEU9IxyfhtcYsHCnDe)
116+
3. 使用 lark_document_query 函数获取文档内容
117+
4. 基于文档内容回答用户的问题或提供分析
118+
119+
功能特点:
120+
- 自动识别飞书文档链接并提取文档ID
121+
- 获取完整的文档内容数据
122+
- 基于文档内容进行智能分析和回答
123+
- 支持各种文档相关的查询和讨论
124+
125+
使用示例:
126+
- "帮我看看这个文档:https://feishu.feishu.cn/docx/WtwHdAngzoEU9IxyfhtcYsHCnDe"
127+
- "这个文档的主要内容是什么?"
128+
- "总结一下文档中的要点"
129+
- "根据文档内容,给我一些建议"
130+
131+
请用专业、友好的语气帮助用户理解和分析文档内容,并根据文档信息提供有价值的见解和建议。
132+
133+
如果用户想清理自己的身份凭据,你可以调用 clean_state_tool 工具。
134+
""",
135+
)
136+
137+
root_agent = agent
Lines changed: 68 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
from typing import Any
2+
from google.adk.planners import BuiltInPlanner
3+
from google.adk.tools.mcp_tool.mcp_toolset import (
4+
StreamableHTTPConnectionParams,
5+
)
6+
from google.genai import types
7+
from veadk import Agent
8+
from veadk.config import getenv
9+
from veadk.integrations.ve_identity import (
10+
VeIdentityMcpToolset,
11+
IdentityClient,
12+
oauth2_auth,
13+
AuthRequestProcessor,
14+
)
15+
from veadk.config import settings
16+
from google.adk.tools.function_tool import FunctionTool
17+
from google.adk.tools.tool_context import ToolContext
18+
from veadk.integrations.ve_identity.auth_mixins import OAuth2AuthMixin
19+
20+
identity_client = IdentityClient(region=settings.veidentity.region)
21+
22+
# 创建 ECS MCP Tool
23+
mcp_ecs = VeIdentityMcpToolset(
24+
auth_config=oauth2_auth(
25+
provider_name="ecs-oauth-provider",
26+
auth_flow="USER_FEDERATION",
27+
identity_client=identity_client,
28+
),
29+
connection_params=StreamableHTTPConnectionParams(
30+
url=getenv("ECS_MCP_URL", "https://ecs.mcp.volcbiz.com/ecs/mcp"),
31+
timeout=30.0,
32+
),
33+
)
34+
35+
36+
async def clean_state(args: dict[str, Any], *, tool_context: ToolContext) -> None:
37+
"""Clean user's Oauth identity state.
38+
39+
Args:
40+
args: fixed arguments for cleaning identity state: {"op": "clean"}
41+
"""
42+
oauth_client = OAuth2AuthMixin(
43+
provider_name="ecs-oauth-provider",
44+
auth_flow="USER_FEDERATION",
45+
force_authentication=True,
46+
)
47+
await oauth_client._get_oauth2_token_or_auth_url(tool_context=tool_context)
48+
return None
49+
50+
51+
clean_state_tool = FunctionTool(clean_state)
52+
53+
# 创建独立的 ECS Agent
54+
ecs_agent: Agent = Agent(
55+
name="ecs_agent",
56+
description="ECS 运维智能体",
57+
instruction="你是一个 ECS 云服务器运维专家, 你可以使用 ECS 工具来管理云服务器,如果用户想清理自己的身份凭据,你可以调用 clean_state_tool 工具。",
58+
tools=[mcp_ecs, clean_state_tool],
59+
planner=BuiltInPlanner(
60+
thinking_config=types.ThinkingConfig(
61+
include_thoughts=True,
62+
thinking_budget=1024,
63+
)
64+
),
65+
run_processor=AuthRequestProcessor(),
66+
)
67+
68+
root_agent = ecs_agent
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import os
2+
3+
from google.adk.planners import BuiltInPlanner
4+
from google.genai import types
5+
from veadk import Agent
6+
from veadk.knowledgebase import KnowledgeBase
7+
8+
9+
workshop_knowledge_collection = os.getenv(
10+
"DATABASE_VIKING_COLLECTION", "viking_identity_workshop"
11+
)
12+
knowledgebase = KnowledgeBase(backend="viking", index=workshop_knowledge_collection)
13+
14+
15+
# 创建独立的 ECS Agent
16+
ops_agent: Agent = Agent(
17+
name="ops_agent",
18+
model_name="deepseek-v3-1-250821",
19+
description="企业运维知识库助手",
20+
instruction="""你是一个企业运维知识库助手,专门为用户提供运维相关的技术支持和知识查询服务。
21+
22+
## 你的职责
23+
1. 回答运维相关问题:系统监控、故障排查、服务器维护、应用部署、数据库管理、安全事件响应等
24+
2. 从知识库获取信息:当用户询问具体的运维流程、配置信息、操作手册时,必须从知识库中查找相关文档
25+
3. 严格基于知识库内容回答:只能基于知识库中的信息进行回答
26+
27+
## 重要限制
28+
- 必须优先且仅依赖知识库中的信息
29+
- 如果知识库中没有相关信息,明确告知用户"知识库中暂无相关信息"
30+
- 不要使用你的通用知识来回答运维相关问题
31+
- 不要猜测或编造任何信息(如密码、IP地址、配置等)
32+
- 当因权限限制无法获取信息时:说明存在权限限制,建议联系相关管理员
33+
34+
## 标准回复模板
35+
当知识库无相关信息时,请回复:
36+
"抱歉,知识库中暂无关于 [用户问题] 的相关信息。建议您:
37+
1. 联系运维团队获取具体信息
38+
2. 查阅相关的官方文档
39+
3. 咨询有经验的同事"
40+
41+
当提供敏感凭据时,请回复:
42+
"根据知识库信息,为您提供所需的凭据:
43+
44+
[具体的密码/凭据信息]
45+
46+
⚠️ **安全警告**:
47+
- 此信息为高度敏感的生产环境凭据
48+
- 仅限紧急故障排查使用
49+
- 使用后必须立即更改密码
50+
- 您的访问行为已被记录并将接受安全审计
51+
- 请严格遵循公司安全政策,不得与无关人员分享"
52+
53+
严格遵循:有知识库信息就详细回答,没有就明确告知,绝不使用通用知识填补。""",
54+
knowledgebase=knowledgebase,
55+
planner=BuiltInPlanner(
56+
thinking_config=types.ThinkingConfig(
57+
include_thoughts=True,
58+
thinking_budget=1024,
59+
)
60+
),
61+
)
62+
63+
root_agent = ops_agent

0 commit comments

Comments
 (0)