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+ from lark_oapi .core .model import RequestOption
23+ from veadk .integrations .ve_identity import (
24+ VeIdentityFunctionTool ,
25+ AuthRequestProcessor ,
26+ oauth2_auth ,
27+ )
28+ from google .adk .tools .function_tool import FunctionTool
29+ from google .adk .tools .tool_context import ToolContext
30+ from veadk .integrations .ve_identity .auth_mixins import OAuth2AuthMixin
31+ from veadk .memory .short_term_memory import ShortTermMemory
32+
33+ short_term_memory = ShortTermMemory (backend = "local" )
34+
35+ async def lark_document_query (document_id : str , * , access_token : str ) -> str :
36+ """
37+ 查询飞书文档内容
38+
39+ Args:
40+ document_id: 飞书文档ID(从文档链接中提取的最后一部分)
41+ access_token: 飞书 API OAuth2.0 访问令牌
42+
43+ Returns:
44+ 文档内容的JSON字符串
45+ """
46+ try :
47+ print (f"查询飞书文档: { document_id } " )
48+ print (f"使用访问令牌: { access_token [:8 ]} ..." )
49+
50+ client = (
51+ lark .Client .builder ()
52+ .enable_set_token (True )
53+ .log_level (lark .LogLevel .INFO )
54+ .build ()
55+ )
56+ request : RawContentDocumentRequest = (
57+ RawContentDocumentRequest .builder ().lang (0 ).document_id (document_id ).build ()
58+ )
59+
60+ response : RawContentDocumentResponse = client .docx .v1 .document .raw_content (
61+ request , RequestOption .builder ().user_access_token (access_token ).build ()
62+ )
63+
64+ if not response .success ():
65+ lark .logger .error (
66+ 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 )} "
67+ )
68+ return f"文档查询失败: { response .msg } "
69+
70+ # 处理业务结果
71+ return lark .JSON .marshal (response .data , indent = 4 )
72+
73+ except Exception as e :
74+ return f"文档查询出错: { str (e )} "
75+
76+
77+ # 创建使用 OAuth2 认证的飞书文档查询工具
78+ lark_doc_tool = VeIdentityFunctionTool (
79+ func = lark_document_query ,
80+ auth_config = oauth2_auth (
81+ provider_name = "feishu" ,
82+ auth_flow = "USER_FEDERATION" ,
83+ ),
84+ )
85+
86+ async def clean_state (args : dict [str , Any ], * , tool_context : ToolContext ) -> None :
87+ """Clean user's Oauth identity state.
88+
89+ Args:
90+ args: fixed arguments for cleaning identity state: {"op": "clean"}
91+ """
92+ oauth_client = OAuth2AuthMixin (
93+ provider_name = "feishu" ,
94+ auth_flow = "USER_FEDERATION" ,
95+ force_authentication = True ,
96+ )
97+ await oauth_client ._get_oauth2_token_or_auth_url (tool_context = tool_context )
98+ return None
99+
100+
101+ clean_state_tool = FunctionTool (clean_state )
102+
103+ agent : Agent = Agent (
104+ name = "lark_doc" ,
105+ tools = [lark_doc_tool , clean_state_tool ],
106+ run_processor = AuthRequestProcessor (),
107+ instruction = """您是一个智能飞书文档助手,能够帮助用户查询和分析飞书文档内容。当用户提供飞书文档链接或询问文档相关问题时,您需要:
108+
109+ 1. 识别用户消息中的飞书文档链接(格式如:https://feishu.feishu.cn/docx/WtwHdAngzoEU9IxyfhtcYsHCnDe)
110+ 2. 提取文档ID(链接最后一部分,如:WtwHdAngzoEU9IxyfhtcYsHCnDe)
111+ 3. 使用 lark_document_query 函数获取文档内容
112+ 4. 基于文档内容回答用户的问题或提供分析
113+
114+ 功能特点:
115+ - 自动识别飞书文档链接并提取文档ID
116+ - 获取完整的文档内容数据
117+ - 基于文档内容进行智能分析和回答
118+ - 支持各种文档相关的查询和讨论
119+
120+ 使用示例:
121+ - "帮我看看这个文档:https://feishu.feishu.cn/docx/WtwHdAngzoEU9IxyfhtcYsHCnDe"
122+ - "这个文档的主要内容是什么?"
123+ - "总结一下文档中的要点"
124+ - "根据文档内容,给我一些建议"
125+
126+ 请用专业、友好的语气帮助用户理解和分析文档内容,并根据文档信息提供有价值的见解和建议。
127+
128+ 如果用户想清理自己的身份凭据,你可以调用 clean_state_tool 工具。
129+ """ ,
130+ )
131+
132+ root_agent = agent
0 commit comments