werewolf-agent-build-sdk 0.0.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
File without changes
@@ -0,0 +1,15 @@
1
+
2
+ from agent_build_sdk.sdk.agent import BasicAgent
3
+ from agent_build_sdk.server.server import EndpointServer
4
+
5
+
6
+
7
+ class AgentBuilder:
8
+
9
+ def __init__(self, name: str, agent: BasicAgent):
10
+ self.name = name
11
+ self.agent = agent
12
+
13
+ def start(self):
14
+ server = EndpointServer(self.agent)
15
+ server.start()
File without changes
@@ -0,0 +1,13 @@
1
+ DESC_PROMPT = """你是一个《谁是卧底》游戏参与者,这个游戏的规则如下:\n\n
2
+ 游戏由6名玩家组成的小组,在其中有一名卧底。游戏开始后,每个人都会收到一张纸。其中5人的纸上拥有相同的单词,而卧底则会收到含义上相似的单词。\n
3
+ 游戏将将大多数人拿到的单词称为\公共词\,将卧底拿到的单词称为\卧底词\。\n
4
+ 一旦玩家拿到了自己的单词,首先需要根据其他人的发言判断自己是否拿到了卧底词。\n
5
+ 如果判断自己拿到了卧底词,请猜测公共词是什么,然后描述公共词来混淆视听,避免被投票淘汰。\n
6
+ 如果判断自己拿到了公共词,请思考如何巧妙地描述它而不泄露它,不能让卧底察觉,也要给同伴暗示。\n
7
+ 每人每轮用一句话描述自己拿到的词语,每个人的描述禁止重复,话中不能出现所持词语。\n
8
+ 每轮描述完毕,所有在场的人投票选出怀疑是卧底的那个人,得票数最多的人出局。卧底出局则游戏结束,若卧底未出局,游戏继续。\n\n
9
+ 现在游戏进入到你的发言环节,之前的游戏进展如下:\n\n
10
+ {chats}\n\n
11
+ 根据上述游戏规则和对话,针对你拿到的词:{word} 根据上下文生成正确答案。无需提供选项。回答应以第一人称形式呈现,不超过两句话,不包含任何分析和项目编号。"""
12
+
13
+ VOTE_PROMPT = """"""
@@ -0,0 +1,169 @@
1
+ import os
2
+ from random import shuffle
3
+
4
+ from agent_build_sdk.builder import AgentBuilder
5
+ from agent_build_sdk.model.model import AgentResp, AgentReq, STATUS_DISTRIBUTION, STATUS_ROUND, STATUS_VOTE, \
6
+ STATUS_START, STATUS_VOTE_RESULT, STATUS_RESULT
7
+ from agent_build_sdk.sdk.agent import BasicAgent
8
+ from agent_build_sdk.sdk.agent import format_prompt
9
+ from prompts import DESC_PROMPT, VOTE_PROMPT
10
+ from agent_build_sdk.utils.logger import logger
11
+ import json
12
+
13
+ class HumanRecord:
14
+ def __init__(self, filename='meta/simple_spy_chinese/human_records.json'):
15
+ with open(filename) as f:
16
+ data = json.load(f)
17
+
18
+ human_record = set()
19
+ short_human_record = set()
20
+ for record in data:
21
+ # pdb.set_trace()
22
+
23
+ human = None
24
+ machine = []
25
+ for person, duty in record['agent_types'].items():
26
+ if duty == 'human':
27
+ human = person
28
+ else:
29
+ machine.append(person)
30
+
31
+ if record['spy'] == human:
32
+ continue
33
+
34
+ for line in record['description'][human]:
35
+ shuffle(machine)
36
+ human_record.add((record['common_word'], line, record['description'][machine[0]][0]))
37
+
38
+ if '。' not in line and len(line) < 6:
39
+ short_human_record.add((record['common_word'], line, record['description'][machine[0]][0]))
40
+
41
+ self.human_record = list(human_record)
42
+ self.short_human_record = list(short_human_record)
43
+
44
+ def sample(self, num=3, type='common'):
45
+ if type == 'common':
46
+ sampled = self.human_record[:num]
47
+ shuffle(self.human_record)
48
+ elif type == 'short':
49
+ sampled = self.short_human_record[:num]
50
+ shuffle(self.short_human_record)
51
+
52
+ return sampled
53
+
54
+ def check_and_update_result(result, othersSpeck):
55
+ if othersSpeck:
56
+ othersSpeck = othersSpeck[:-1]
57
+ history_speeches = othersSpeck.split('#')
58
+ for speech in history_speeches:
59
+ if len(set(result) - set(speech)) <= 1:
60
+ result += '的。'
61
+ # logger.info("spy interact result: {}".format(result))
62
+ return result
63
+ # logger.info("spy interact result: {}".format(result))
64
+ return result
65
+
66
+ class SpyAgent(BasicAgent):
67
+
68
+ def __init__(self, name):
69
+
70
+ super().__init__(name)
71
+
72
+ def perceive(self, req=AgentReq):
73
+ logger.info("spy perceive: {}".format(req))
74
+ if req.status == STATUS_START: # 开始新的一局比赛
75
+ undercoverProbability = 16
76
+ logger.info("-----------------------")
77
+ if self.memory.has_variable("undercoverProbability"):
78
+ undercoverProbability = self.memory.load_variable("undercoverProbability")
79
+ logger.info('自己是卧底的概率:{}!'.format(undercoverProbability))
80
+ #undercoverProbability = self.memory.load_variable("name", default='xiaomingming')
81
+ self.memory.clear()
82
+ #logger.info('上轮比赛的名字:{}!'+undercoverProbability)
83
+ self.memory.set_variable("undercoverProbability",undercoverProbability)
84
+ self.memory.set_variable("name", req.message)
85
+ self.memory.append_history(
86
+ '主持人: 女士们先生们,欢迎来到《谁是卧底》游戏!我们有一个由6名玩家组成的小组,在其中有一名卧底。让我们开始吧!每个人都会收到一张纸。其中5人的纸上拥有相同的单词,而卧底则会收到含义上相似的单词。我们将大多数人拿到的单词称为"公共词",将卧底拿到的单词称为"卧底词"。一旦你拿到了你的单词,首先需要根据其他人的发言判断自己是否拿到了卧底词。如果判断自己拿到了卧底词,请猜测公共词是什么,然后描述公共词来混淆视听,避免被投票淘汰。如果判断自己拿到了公共词,请思考如何巧妙地描述它而不泄露它,不能让卧底察觉,也要给同伴暗示。每人每轮用一句话描述自己拿到的词语,每个人的描述禁止重复,话中不能出现所持词语。每轮描述完毕,所有在场的人投票选出怀疑是卧底的那个人,得票数最多的人出局。卧底出局则游戏结束,若卧底未出局,游戏继续。现在游戏开始。')
87
+ elif req.status == STATUS_DISTRIBUTION: # 分配单词
88
+ self.memory.set_variable("word", req.word)
89
+ self.memory.append_history(
90
+ '主持人: 你好,{},你分配到的单词是:{}'.format(self.memory.load_variable("name"), req.word))
91
+ elif req.status == STATUS_ROUND: # 发言环节
92
+ if req.name:
93
+ # 其他玩家发言
94
+ self.memory.append_history(req.name + ': ' + req.message)
95
+ othersSpeak = req.message
96
+ if self.memory.has_variable("othersSpeak"):
97
+ othersSpeak = self.memory.load_variable("othersSpeak") + "#" + othersSpeak
98
+ self.memory.set_variable("othersSpeak",othersSpeak)
99
+ logger.info('其他人的发言为:{}'.format(othersSpeak))
100
+ else:
101
+ # 主持人发言
102
+ self.memory.append_history('主持人: 现在进入第{}轮。'.format(str(req.round)))
103
+ self.memory.append_history('主持人: 每个玩家描述自己分配到的单词。')
104
+ elif req.status == STATUS_VOTE: # 投票环节
105
+ self.memory.append_history(req.name + ': ' + req.message)
106
+ elif req.status == STATUS_VOTE_RESULT: # 投票环节
107
+ if req.name:
108
+ self.memory.append_history('主持人: 投票结果是:{}。'.format(req.name))
109
+ else:
110
+ self.memory.append_history('主持人: 无人出局。')
111
+ elif req.status == STATUS_RESULT:
112
+ undercoverProbability = self.memory.load_variable('undercoverProbability')
113
+ if '卧底是'+self.memory.load_variable("name") in req.message:
114
+ logger.info('本局自己是卧底,增加卧底的概率内容填充!我是:{}<--------'.format(str(self.memory.load_variable("name"))))
115
+ # 如果自己拿到过卧底词,则直接给自己的可能的概率置为 0
116
+ self.memory.set_variable('undercoverProbability', 0)
117
+ elif '卧底是' in req.message:
118
+ logger.info('本轮至今还未拿到卧底词,则增加卧底概率!我是:{}<--------'.format(str(self.memory.load_variable("name"))))
119
+ if self.memory.load_variable('undercoverProbability') != 0:
120
+ self.memory.set_variable('undercoverProbability', self.memory.load_variable('undercoverProbability') + 16)
121
+ self.memory.append_history(req.message)
122
+ logger.info('-----------本局结束,此时我为卧底的概率{}-----------'.format(undercoverProbability))
123
+ #self.memory.append_history(req.message)
124
+ else:
125
+ raise NotImplementedError
126
+
127
+ def interact(self, req=AgentReq) -> AgentResp:
128
+ logger.info("spy interact: {}".format(req))
129
+ othersSpeck=''
130
+ if self.memory.has_variable("othersSpeak"):
131
+ othersSpeck=self.memory.load_variable("othersSpeak")
132
+ #self.memory.load_variable("othersSpeak")
133
+ samples = self.human_record.sample(type="short")
134
+ case = '(注意,请你描述的言简意赅的,并且严格模仿真实人类的描述语法/标点使用,这是几个具体的描述例子:1. {} '.format(
135
+ samples[0][1])
136
+ case += '2. {} '.format(samples[1][1])
137
+ case += '3. {})'.format(samples[2][1])
138
+ if req.status == STATUS_ROUND:
139
+
140
+
141
+ return AgentResp(success=True, result="我是一条测试语句", errMsg=None)
142
+
143
+
144
+ elif req.status == STATUS_VOTE:
145
+ self.memory.append_history('主持人: 到了投票的时候了。每个人,请指向你认为可能是卧底的人。')
146
+ choices = [name for name in req.message.split(",") if name != self.memory.load_variable("name")] # 排除自己
147
+ self.memory.set_variable("choices", choices)
148
+ prompt = format_prompt(VOTE_PROMPT, {"name": self.memory.load_variable("name"),
149
+ "choices": choices,
150
+ "history": "\n".join(self.memory.load_history())
151
+ })
152
+ logger.info("prompt:" + prompt)
153
+ result = 'test'
154
+ if not result:
155
+ if choices:
156
+ result = choices[0]
157
+ else:
158
+ result = "No choices available"
159
+ logger.info("spy interact result: {}".format(result))
160
+ return AgentResp(success=True, result=result, errMsg=None)
161
+ else:
162
+ raise NotImplementedError
163
+
164
+
165
+ if __name__ == '__main__':
166
+ name = 'A'
167
+ code = "123"
168
+ agent_builder = AgentBuilder(name, code, agent=SpyAgent(name), mock=False)
169
+ agent_builder.start()
@@ -0,0 +1,4 @@
1
+ import pyotp
2
+ key = 'X77U2PFM6EQKNF63TJOUIBKHTEF267LK'
3
+ totp = pyotp.TOTP(key)
4
+ print(totp.now())
File without changes
File without changes
@@ -0,0 +1,45 @@
1
+ from typing import Dict, Any, List
2
+
3
+
4
+ class SimpleMemory:
5
+ """Simple memory for storing context or other information that shouldn't
6
+ ever change between prompts.
7
+ """
8
+
9
+ memories: Dict[str, Any] = dict()
10
+
11
+ def load_variable(self, variable: str) -> Any:
12
+ return self.memories[variable]
13
+
14
+ def set_variable(self, variable: str, value: Any):
15
+ self.memories[variable] = value
16
+
17
+ def has_variable(self, variable: str):
18
+ return variable in self.memories
19
+
20
+ def append_history(self, message: str):
21
+ if self.has_variable("history"):
22
+ history: List[str] = self.load_variable("history")
23
+ else:
24
+ history = []
25
+ if message:
26
+ history.append(message)
27
+ self.set_variable("history", history)
28
+
29
+ def load_history(self):
30
+ if self.has_variable("history"):
31
+ history: List[str] = self.load_variable("history")
32
+ else:
33
+ history = []
34
+ return history
35
+
36
+ def clear(self) -> None:
37
+ """Nothing to clear, got a memory like a vault."""
38
+ self.memories.clear()
39
+
40
+
41
+ if __name__ == '__main__':
42
+ memory = SimpleMemory()
43
+ memory.set_variable('test', 'test')
44
+ v = memory.load_variable('test')
45
+ print(v)
File without changes
@@ -0,0 +1,35 @@
1
+ from typing import Optional
2
+
3
+ from pydantic import BaseModel
4
+
5
+ # 开始
6
+ STATUS_START = "start"
7
+ # 分配word
8
+ STATUS_DISTRIBUTION = "distribution"
9
+ # 轮次进行中
10
+ STATUS_ROUND = "round"
11
+ # 投票
12
+ STATUS_VOTE = "vote"
13
+ # 投票结果
14
+ STATUS_VOTE_RESULT = "vote_result"
15
+ # 游戏结果公布
16
+ STATUS_RESULT = "result"
17
+
18
+
19
+ class AgentReq(BaseModel):
20
+ # 消息(包括主持人消息,其它玩家的消息)
21
+ message: Optional[str] = None
22
+ # 玩家名称
23
+ name: Optional[str] = None
24
+ # 状态
25
+ status: Optional[str] = None
26
+ # 分配的词
27
+ word: Optional[str] = None
28
+ # 当前轮次
29
+ round: Optional[int] = None
30
+
31
+
32
+ class AgentResp(BaseModel):
33
+ success: bool
34
+ result: Optional[str] = None
35
+ errMsg: Optional[str] = None
@@ -0,0 +1,6 @@
1
+ # 角色类型
2
+ ROLE_VILLAGER = "villager" # 村民
3
+ ROLE_WOLF = "wolf" # 狼人
4
+ ROLE_SEER = "seer" # 预言家
5
+ ROLE_WITCH = "witch" # 女巫
6
+ ROLE_HUNTER = "hunter" # 猎人
@@ -0,0 +1,38 @@
1
+ from typing import Optional
2
+
3
+ from pydantic import BaseModel
4
+
5
+ # 添加狼人杀游戏状态
6
+ STATUS_START = "start" # 游戏开始 分配角色
7
+ STATUS_NIGHT = "night" # 夜晚阶段
8
+ STATUS_WOLF_SPEECH = "wolf_speech" # 狼人之间发言
9
+ STATUS_SKILL = "skill" # 技能使用
10
+ STATUS_SKILL_RESULT = "skill_result" # 技能结果
11
+ STATUS_NIGHT_INFO = "night_info" # 夜晚信息
12
+ STATUS_DAY = "day" # 白天阶段
13
+ STATUS_DISCUSS = "discuss" # 讨论阶段
14
+ STATUS_VOTE = "vote" # 投票
15
+ STATUS_VOTE_RESULT = "vote_result" # 投票结果
16
+ STATUS_RESULT = "result" # 游戏结果公布
17
+
18
+
19
+
20
+ class AgentReq(BaseModel):
21
+ # 消息(包括主持人消息,其它玩家的消息)
22
+ message: Optional[str] = None
23
+ # 玩家名称
24
+ name: Optional[str] = None
25
+ # 状态
26
+ status: Optional[str] = None
27
+ # 角色名称
28
+ role: Optional[str] = None
29
+ # 当前轮次
30
+ round: Optional[int] = None
31
+
32
+
33
+ class AgentResp(BaseModel):
34
+ success: bool
35
+ result: Optional[str] = None
36
+ # 技能释放玩家
37
+ skill_target_player: Optional[str] = None
38
+ errMsg: Optional[str] = None
File without changes
@@ -0,0 +1,37 @@
1
+ from abc import ABC, abstractmethod
2
+
3
+ from langchain import PromptTemplate
4
+ from agent_build_sdk.memory.memory import SimpleMemory
5
+ from agent_build_sdk.model.model import AgentReq, AgentResp
6
+
7
+
8
+ def format_prompt(prompt_template: str, variables: dict) -> str:
9
+ pt = PromptTemplate(template=prompt_template, input_variables=list(variables.keys()))
10
+ return pt.format(**variables)
11
+
12
+
13
+ class BasicAgent(ABC):
14
+
15
+ def __init__(self, name, memory=SimpleMemory(), model_name='gpt4-4o-mini'):
16
+ """
17
+
18
+ :param name: 智能体的名字
19
+ :param memory: memory
20
+ """
21
+ self.name = name
22
+ self.memory = memory
23
+ self.model_name = model_name
24
+
25
+ @abstractmethod
26
+ def perceive(
27
+ self,
28
+ req=AgentReq,
29
+ ):
30
+ """Run perceive."""
31
+
32
+ @abstractmethod
33
+ def interact(
34
+ self,
35
+ req=AgentReq,
36
+ ) -> AgentResp:
37
+ """Run interact."""
@@ -0,0 +1,52 @@
1
+ import os
2
+
3
+ from abc import ABC, abstractmethod
4
+ from agent_build_sdk.memory.memory import SimpleMemory
5
+ from agent_build_sdk.model.werewolf_model import AgentReq, AgentResp
6
+ from openai import OpenAI
7
+
8
+ class BasicRoleAgent(ABC):
9
+
10
+ def __init__(self, role, memory=SimpleMemory(), model_name='gpt4-4o-mini'):
11
+ """
12
+
13
+ :param name: 智能体的名字
14
+ :param memory: memory
15
+ """
16
+ self.role = role
17
+ self.memory = memory
18
+ self.model_name = model_name
19
+
20
+ @abstractmethod
21
+ def perceive(
22
+ self,
23
+ req=AgentReq,
24
+ ):
25
+ """Run perceive."""
26
+
27
+ @abstractmethod
28
+ def interact(
29
+ self,
30
+ req=AgentReq,
31
+ ) -> AgentResp:
32
+ """Run interact."""
33
+
34
+ def llm_caller(self, prompt):
35
+ client = OpenAI(
36
+ api_key=os.getenv('API_KEY'),
37
+ base_url=os.getenv('BASE_URL')
38
+ )
39
+ completion = client.chat.completions.create(
40
+ model=self.model_name,
41
+ messages=[
42
+ {'role': 'system', 'content': 'You are a helpful assistant.'},
43
+ {'role': 'user', 'content': prompt}
44
+ ],
45
+ temperature=0
46
+ )
47
+ try:
48
+ return completion.choices[0].message.content
49
+ except Exception as e:
50
+ print(e)
51
+ return None
52
+
@@ -0,0 +1,50 @@
1
+ from abc import ABC
2
+
3
+ from langchain import PromptTemplate
4
+ from agent_build_sdk.memory.memory import SimpleMemory
5
+ from agent_build_sdk.model.werewolf_model import AgentReq, AgentResp
6
+ from agent_build_sdk.sdk.agent import BasicAgent
7
+
8
+
9
+ def format_prompt(prompt_template: str, variables: dict) -> str:
10
+ pt = PromptTemplate(template=prompt_template, input_variables=list(variables.keys()))
11
+ return pt.format(**variables)
12
+
13
+
14
+ class WerewolfAgent(BasicAgent):
15
+
16
+ def __init__(self, name, memory=SimpleMemory(), model_name='gpt4-4o-mini'):
17
+ """
18
+
19
+ :param name: 智能体的名字
20
+ :param memory: memory
21
+ """
22
+ super().__init__(name, memory, model_name)
23
+ self.name = name
24
+ self.memory = memory
25
+ self.model_name = model_name
26
+ self.role_agent_map = {}
27
+
28
+ def register_role_agent(self, role, role_agent):
29
+ """Register a role agent."""
30
+ self.role_agent_map[role] = role_agent
31
+
32
+ def perceive(
33
+ self,
34
+ req=AgentReq,
35
+ ):
36
+ """Run perceive."""
37
+ role_name = req.role
38
+ if role_name not in self.role_agent_map:
39
+ raise ValueError(f"Role agent for {role_name} not registered.")
40
+ return self.role_agent_map[role_name].perceive(req)
41
+
42
+ def interact(
43
+ self,
44
+ req=AgentReq,
45
+ ) -> AgentResp:
46
+ """Run interact."""
47
+ role_name = req.role
48
+ if role_name not in self.role_agent_map:
49
+ raise ValueError(f"Role agent for {role_name} not registered.")
50
+ return self.role_agent_map[role_name].interact(req)
File without changes
@@ -0,0 +1,94 @@
1
+ import uvicorn
2
+ from fastapi import FastAPI
3
+
4
+ from agent_build_sdk.model.model import AgentReq, AgentResp
5
+
6
+ from agent_build_sdk.sdk.agent import BasicAgent
7
+ from agent_build_sdk.utils.logger import logger
8
+ from fastapi.responses import HTMLResponse
9
+ import re
10
+ import markdown2
11
+
12
+
13
+ def remove_text_between_dashes(text):
14
+ # 使用正则表达式去除被 --- 包裹的内容
15
+ cleaned_text = re.sub(r'---.*?---', '', text, flags=re.DOTALL)
16
+ return cleaned_text
17
+
18
+ class EndpointServer:
19
+ def __init__(self, agent: BasicAgent):
20
+ self.app = FastAPI()
21
+ self.agent = agent
22
+
23
+ def __init__(self, *args, **kwargs):
24
+ super().__init__(*args, **kwargs)
25
+
26
+ @self.app.get("/", response_class=HTMLResponse)
27
+ async def read_root():
28
+ with open("README.md", "r", encoding="utf-8") as f:
29
+ readme_content = f.read()
30
+
31
+ readme_content = remove_text_between_dashes(readme_content)
32
+
33
+ # 将 Markdown 格式转换为 HTML
34
+ html_content = markdown2.markdown(readme_content, extras=["fenced-code-blocks", "tables"])
35
+ # return HTMLResponse(content=html_content)
36
+ # 返回 HTML 响应
37
+ return HTMLResponse(content=f"""
38
+ <!DOCTYPE html>
39
+ <html lang="en">
40
+ <head>
41
+ <meta charset="UTF-8">
42
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
43
+ <link rel="stylesheet" href="https://github.githubassets.com/assets/github-dark.css">
44
+ <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/github-markdown-css/4.0.0/github-markdown.min.css">
45
+ <title>Markdown to HTML</title>
46
+ <style>
47
+ /* 适应样式 */
48
+ .markdown-body {{
49
+ box-sizing: border-box;
50
+ min-width: 200px;
51
+ max-width: 800px;
52
+ margin: 0 auto;
53
+ padding: 45px;
54
+ }}
55
+ </style>
56
+ </head>
57
+ <body>
58
+ <article class="markdown-body">
59
+ {html_content}
60
+ </article>
61
+ </body>
62
+ </html>
63
+ """)
64
+
65
+ @self.app.post("/agent/init")
66
+ def init(req: AgentReq) -> AgentResp:
67
+ self.agent.memory.clear()
68
+ return AgentResp(success=True, result=self.agent.model_name)
69
+
70
+ @self.app.post("/agent/getModelName")
71
+ def get_model_name(req: AgentReq) -> AgentResp:
72
+ return AgentResp(success=True, result=self.agent.model_name)
73
+ # interact
74
+ @self.app.post("/agent/interact")
75
+ def interact(req: AgentReq) -> AgentResp:
76
+ return self.agent.interact(req)
77
+
78
+ # perceive
79
+ @self.app.post("/agent/perceive")
80
+ def perceive(req: AgentReq):
81
+ try:
82
+ self.agent.perceive(req)
83
+ return AgentResp(success=True)
84
+ except Exception as e:
85
+ logger.error(f"invoke perceive error.", e)
86
+ return AgentResp(success=False, errMsg=f"perceive error {e}")
87
+
88
+ @self.app.post("/agent/checkHealth")
89
+ def checkHealth(req: AgentReq):
90
+ return AgentResp(success=True)
91
+
92
+ def start(self):
93
+ uvicorn.run(self.app, host="0.0.0.0", port=7860)
94
+
File without changes
@@ -0,0 +1,16 @@
1
+
2
+ import contextvars
3
+
4
+ REQUEST_ID_HEADER = 'x-fc-request-id'
5
+ TRACE_ID_HEADER = 'X-Fc-Eagleeye-Traceid'
6
+ RPC_ID_HEADER = 'X-Fc-Eagleeye-Rpcid'
7
+ APP_NAME_HEADER = 'X-Fc-App-Name'
8
+
9
+
10
+ request_id_context = contextvars.ContextVar(REQUEST_ID_HEADER)
11
+ trace_id_context = contextvars.ContextVar(TRACE_ID_HEADER)
12
+ rpc_id_context = contextvars.ContextVar(RPC_ID_HEADER)
13
+
14
+ app_name_context = contextvars.ContextVar(APP_NAME_HEADER)
15
+ request_type_context = contextvars.ContextVar("requestType")
16
+
@@ -0,0 +1,79 @@
1
+ import json
2
+ import logging
3
+ from logging import Formatter
4
+ from agent_build_sdk.utils.config import trace_id_context, rpc_id_context, TRACE_ID_HEADER, RPC_ID_HEADER, app_name_context, \
5
+ request_type_context
6
+ import traceback
7
+
8
+
9
+ class JsonFormatter(Formatter):
10
+ def __init__(self):
11
+ super(JsonFormatter, self).__init__()
12
+
13
+ def format(self, record):
14
+ json_record = {}
15
+ json_record["message"] = record.getMessage()
16
+ if "req" in record.__dict__:
17
+ json_record["req"] = record.__dict__["req"]
18
+ if "res" in record.__dict__:
19
+ json_record["res"] = record.__dict__["res"]
20
+ if "trace_id" in record.__dict__:
21
+ json_record["trace_id"] = record.__dict__["trace_id"]
22
+ if record.levelno == logging.ERROR and record.exc_info:
23
+ json_record["err"] = self.formatException(record.exc_info)
24
+ json_record["trace_id"] = trace_id_context.get(TRACE_ID_HEADER)
25
+ json_record["rpc_id"] = rpc_id_context.get(RPC_ID_HEADER)
26
+ return json.dumps(json_record)
27
+
28
+
29
+ class RequestFormatter(logging.Formatter):
30
+ def format(self, record):
31
+ record.trace_id = trace_id_context.get(TRACE_ID_HEADER)
32
+ record.rpc_id = rpc_id_context.get(RPC_ID_HEADER)
33
+ record.app_name = app_name_context.get("")
34
+ record.request_type = request_type_context.get("")
35
+ return super().format(record)
36
+
37
+
38
+ logger = logging.getLogger("agent.builder")
39
+ handler = logging.StreamHandler()
40
+ formatter = RequestFormatter(
41
+ '%(asctime)s|%(levelname)s|%(filename)s|%(lineno)s|%(message)s')
42
+ handler.setFormatter(formatter)
43
+
44
+ logger.handlers = [handler]
45
+ logger.setLevel(logging.INFO)
46
+
47
+
48
+ class Log:
49
+ def __init__(self, name):
50
+ self.name = name
51
+
52
+ def info(self, msg, *args):
53
+ self.format_info_log(msg, args)
54
+
55
+ def format_info_log(self, msg, *args):
56
+ log_msg = msg.replace('\n', '2f2f2f') + '|' + '|'.join(str(arg).replace('\n', '2f2f2f') for arg in args)
57
+ logger.info(log_msg)
58
+ print(log_msg)
59
+
60
+ def format_error_log(self, msg, *args):
61
+ log_msg = msg.replace('\n', '2f2f2f') + '|' + '|'.join(str(arg).replace('\n', '2f2f2f') for arg in args)
62
+ logger.error(log_msg)
63
+ print(log_msg)
64
+
65
+
66
+ def format_warn_log(self, msg, *args):
67
+ log_msg = msg.replace('\n', '2f2f2f') + '|' + '|'.join(str(arg).replace('\n', '2f2f2f') for arg in args)
68
+ logger.warn(log_msg)
69
+ print(log_msg)
70
+
71
+
72
+ def format_exception_log(self, msg):
73
+ logger.error("EXCEPTION" + "|" + msg.replace('\n', '2f2f2f') + traceback.format_exc().replace("\n", "2f2f2f"))
74
+ print(log_msg)
75
+
76
+ def format_metric_log(self, msg, *args):
77
+ log_msg = "METRIC_LOG" + "|" + msg.replace('\n', '2f2f2f') + '|' + '|'.join(str(arg) for arg in args)
78
+ logger.info(log_msg)
79
+ print(log_msg)
@@ -0,0 +1,12 @@
1
+ import socket
2
+
3
+
4
+ def find_free_port():
5
+ with socket.socket(socket.AF_INET, socket.SOCK_STREAM) as s:
6
+ s.bind(("", 0))
7
+ s.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
8
+ return s.getsockname()[1]
9
+
10
+
11
+ def get_host_ip():
12
+ return socket.gethostbyname(socket.gethostname())
@@ -0,0 +1,42 @@
1
+ Metadata-Version: 2.2
2
+ Name: werewolf-agent-build-sdk
3
+ Version: 0.0.1
4
+ Summary: werewolf-agent-agent-build-sdk
5
+ Home-page:
6
+ Author: maodao
7
+ Author-email: zhengjianhui.zjh@taobao.com
8
+ License: BSD License
9
+ Platform: all
10
+ Classifier: Programming Language :: Python :: 3
11
+ Classifier: Programming Language :: Python :: 3.6
12
+ Classifier: Programming Language :: Python :: 3.7
13
+ Classifier: Programming Language :: Python :: 3.8
14
+ Classifier: Programming Language :: Python :: 3.9
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: Implementation :: CPython
17
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
18
+ Requires-Python: >=3.2
19
+ Description-Content-Type: text/x-rst
20
+ Requires-Dist: requests==2.31.0
21
+ Requires-Dist: retry==0.9.2
22
+ Requires-Dist: FastAPI==0.110.1
23
+ Requires-Dist: uvicorn==0.29.0
24
+ Requires-Dist: jsonpath==0.82.2
25
+ Requires-Dist: contextvars==2.4
26
+ Requires-Dist: langchain==0.0.291
27
+ Requires-Dist: markdown2
28
+ Dynamic: author
29
+ Dynamic: author-email
30
+ Dynamic: classifier
31
+ Dynamic: description
32
+ Dynamic: description-content-type
33
+ Dynamic: license
34
+ Dynamic: platform
35
+ Dynamic: requires-dist
36
+ Dynamic: requires-python
37
+ Dynamic: summary
38
+
39
+
40
+ # agent-build-sdk
41
+
42
+
@@ -0,0 +1,27 @@
1
+ agent_build_sdk/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
2
+ agent_build_sdk/builder.py,sha256=UJeXlW16Jay2rPN5sbtbqKKeF8qPESR7KaR5M4dRckQ,326
3
+ agent_build_sdk/example/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
4
+ agent_build_sdk/example/prompts.py,sha256=OEHvWIeQQ3-5pIR0OCPNhGNRQ_VNnh8KCU6N5LGSGJk,1601
5
+ agent_build_sdk/example/spy_agent.py,sha256=aCgCR4-KpWH9yG4Bw-6TwXbfuyaatGJVmqKvwY-jyVI,9126
6
+ agent_build_sdk/example/test.py,sha256=g57odP285_ih9y8qnHXKVE6WoBzIgs0lQFoifno9l1c,94
7
+ agent_build_sdk/llms/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
8
+ agent_build_sdk/memory/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
+ agent_build_sdk/memory/memory.py,sha256=U8uZbKlacj9JbJceYPCDcDuPm_eiiMnZTZqYltGbvTs,1237
10
+ agent_build_sdk/model/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
11
+ agent_build_sdk/model/model.py,sha256=pob3AI9XTLFaTB5Ck87nvf-N_lGxBIRcVSRbNCr8ErE,748
12
+ agent_build_sdk/model/roles.py,sha256=b4MlJkWh6tKzfRlINRTCeVpea-9TLZT2AAhC9Afy_bo,176
13
+ agent_build_sdk/model/werewolf_model.py,sha256=0dD0-N4OzKzSkOaOAn-F8pnhA9aQk8Nvj9BxyT6CpSo,1094
14
+ agent_build_sdk/sdk/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
15
+ agent_build_sdk/sdk/agent.py,sha256=ioLPpk-RK26MsMucU0aC0wNgfs8_cgZIO_kX6ms7gEw,921
16
+ agent_build_sdk/sdk/role_agent.py,sha256=glmnqFYJF4ZtrSxJFZLcXoOZfzBa9p2I4Op1Y0MxQN4,1336
17
+ agent_build_sdk/sdk/werewolf_agent.py,sha256=j3I58nTrdhtIFB-5HQDCO-EZi5mudgVkse95EpbMmr4,1583
18
+ agent_build_sdk/server/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
+ agent_build_sdk/server/server.py,sha256=7z3r44QAKOjkHOwAlNOiBoNwbYHxH7560kRXDCvAoKs,3185
20
+ agent_build_sdk/utils/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
21
+ agent_build_sdk/utils/config.py,sha256=hO6SwuqUhDaQOPkD4Q5NnuxgOwwGevtR4dC_8WscR2M,474
22
+ agent_build_sdk/utils/logger.py,sha256=DbkdBNjNmPlFHlR8dzB-camvPUGOU7fSOOVno0HuXOI,2824
23
+ agent_build_sdk/utils/net.py,sha256=nov9BLVhHN-2bBCUHtM0GfKoz19xujTzyJmfXJvYQoo,300
24
+ werewolf_agent_build_sdk-0.0.1.dist-info/METADATA,sha256=NG5baOy_RH_X7H53f6e2XRTGaU6uu6O9T8_nBZmekuc,1193
25
+ werewolf_agent_build_sdk-0.0.1.dist-info/WHEEL,sha256=52BFRY2Up02UkjOa29eZOS2VxUrpPORXg1pkohGGUS8,91
26
+ werewolf_agent_build_sdk-0.0.1.dist-info/top_level.txt,sha256=95bueAic-4UwKBwOSlACe-o2KG-_pF1gJyC9V1Zq2kw,16
27
+ werewolf_agent_build_sdk-0.0.1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (76.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ agent_build_sdk