ai-agent-book 精选快照(<2MB 代码与文档,来自 github.com/bojieli/ai-agent-book)
Build latest book artifacts / build (push) Canceled after 0s
dependency resolution / resolve (3.11) (push) Canceled after 0s
dependency resolution / resolve (3.13) (push) Canceled after 0s
deploy-pages / build (push) Canceled after 0s
deploy-pages / deploy (push) Canceled after 0s
i18n consistency check / check (push) Canceled after 0s
provider adoption tests / test (chapter2/context-compression) (push) Canceled after 0s
provider adoption tests / test (chapter2/prompt-injection) (push) Canceled after 0s
provider adoption tests / test (chapter2/system-hint) (push) Canceled after 0s
provider adoption tests / test (chapter3/log-sanitization) (push) Canceled after 0s
web-search-agent tests / test (push) Canceled after 0s
web-search-agent tests / agentbook (push) Canceled after 0s

This commit is contained in:
2026-08-20 13:12:50 +00:00
commit b119135836
10275 changed files with 3284984 additions and 0 deletions
@@ -0,0 +1,499 @@
import uuid
from abc import abstractmethod
from datetime import datetime
from pydantic import BaseModel, ConfigDict, Field
from typing import Any, Dict, List, Optional, Literal
from aworld.models.model_response import ToolCall
class MemoryItem(BaseModel):
id: str = Field(description="id")
content: Any = Field(description="content")
created_at: Optional[str] = Field(None, description="created at")
updated_at: Optional[str] = Field(None, description="updated at")
metadata: dict = Field(
description="metadata, use to store additional information, such as user_id, agent_id, run_id, task_id, etc.")
tags: list[str] = Field(description="tags")
histories: list["MemoryItem"] = Field(default_factory=list)
deleted: bool = Field(default=False)
memory_type: Literal["init", "message", "summary", "agent_experience", "user_profile", "fact", "conversation_summary"] = Field(default="message")
version: int = Field(description="version")
def __init__(self, **data):
# Set default values for optional fields
if "id" not in data:
data["id"] = str(uuid.uuid4())
if "created_at" not in data:
data["created_at"] = datetime.now().isoformat()
if "updated_at" not in data:
data["updated_at"] = data["created_at"]
if "metadata" not in data:
data["metadata"] = {}
if "tags" not in data:
data["tags"] = []
if "version" not in data:
data["version"] = 1
super().__init__(**data)
@classmethod
def from_dict(cls, data: dict) -> "MemoryItem":
"""Create a MemoryItem instance from a dictionary.
Args:
data (dict): A dictionary containing the memory item data.
Returns:
MemoryItem: An instance of MemoryItem.
"""
return cls(**data)
@property
def user_id(self) -> str:
return self.metadata.get('user_id')
@property
def session_id(self) -> str:
return self.metadata.get('session_id')
@property
def task_id(self) -> str:
return self.metadata.get('task_id')
@property
def agent_id(self) -> str:
return self.metadata.get('agent_id')
@property
def agent_name(self) -> str:
return self.metadata.get('agent_name')
@property
def application_id(self) -> str:
return self.metadata.get('application_id', 'default')
@property
def embedding_text(self) -> Optional[str]:
return self.content
def mark_has_summary(self):
self.metadata['summary'] = True
@property
def has_summary(self) -> bool:
return self.metadata.get('summary', False)
@property
def content_length(self) -> int:
return len(self.content)
@property
def status(self) -> str:
return self.metadata.get('status', 'ACCEPTED')
@status.setter
def status(self, value: Literal["DRAFT", "ACCEPTED", "DISCARD"]) -> None:
self.metadata['status'] = value
@abstractmethod
def to_openai_message(self) -> dict:
pass
class MessageMetadata(BaseModel):
"""
Metadata for memory messages, including user, session, task, and agent information.
Args:
user_id (str): The ID of the user.
session_id (str): The ID of the session.
task_id (str): The ID of the task.
agent_id (str): The ID of the agent.
"""
agent_id: str = Field(description="The ID of the agent")
agent_name: Optional[str] = Field(description="The name of the agent")
session_id: Optional[str] = Field(default=None,description="The ID of the session")
task_id: Optional[str] = Field(default=None,description="The ID of the task")
user_id: Optional[str] = Field(default=None, description="The ID of the user")
summary_content: Optional[str] = Field(default=None, description="The summary of the memory item")
model_config = ConfigDict(extra="allow")
@property
def to_dict(self) -> Dict[str, Any]:
return self.model_dump()
class AgentExperienceItem(BaseModel):
skill: str = Field(description="The skill demonstrated in the experience")
actions: List[str] = Field(description="The actions taken by the agent")
class AgentExperience(MemoryItem):
"""
Represents an agent's experience, including skills and actions.
All custom attributes are stored in content and metadata.
Args:
agent_id (str): The ID of the agent.
skill (str): The skill demonstrated in the experience.
actions (List[str]): The actions taken by the agent.
metadata (Optional[Dict[str, Any]]): Additional metadata.
"""
def __init__(self, agent_id: str, skill: str, actions: List[str], metadata: Optional[Dict[str, Any]] = None) -> None:
meta = metadata.copy() if metadata else {}
meta['agent_id'] = agent_id
agent_experience = AgentExperienceItem(skill=skill, actions=actions)
super().__init__(content=agent_experience, metadata=meta, memory_type="agent_experience")
@property
def agent_id(self) -> str:
return self.metadata['agent_id']
@property
def skill(self) -> str:
return self.content.skill
@property
def actions(self) -> List[str]:
return self.content.actions
@property
def embedding_text(self):
return f"skill:{self.skill}, actions:{self.actions}"
def to_openai_message(self) -> dict:
return {
"role": "system",
"content": self.content
}
class UserProfileItem(BaseModel):
key: str = Field(description="The key of the profile")
value: Any = Field(description="The value of the profile")
class UserProfile(MemoryItem):
"""
Represents a user profile key-value pair.
All custom attributes are stored in content and metadata.
Args:
user_id (str): The ID of the user.
key (str): The profile key.
value (Any): The profile value.
metadata (Optional[Dict[str, Any]]): Additional metadata.
"""
def __init__(self, user_id: str, key: str, value: Any, metadata: Optional[Dict[str, Any]] = None, **kwargs) -> None:
meta = metadata.copy() if metadata else {}
meta['user_id'] = user_id
user_profile = UserProfileItem(key=key, value=value)
super().__init__(content=user_profile, metadata=meta, memory_type="user_profile", **kwargs)
@property
def user_id(self) -> str:
return self.metadata['user_id']
@property
def key(self) -> str:
return self.content.key
@property
def value(self) -> Any:
return self.content.value
@property
def item(self) -> UserProfileItem:
return self.content
@property
def embedding_text(self):
return f"key:{self.key} value:{self.value}"
def to_openai_message(self) -> dict:
return {
"role": "system",
"content": self.content
}
class Fact(MemoryItem):
"""
Represents Fact from conversation.
Args:
user_id (str): The ID of the user.
content (str): fact.
metadata (Optional[Dict[str, Any]]): Additional metadata.
"""
def __init__(self, user_id: str = None, agent_id: str = None, content: str = None, metadata: Optional[Dict[str, Any]] = None, **kwargs) -> None:
meta = metadata.copy() if metadata else {}
if user_id:
meta['user_id'] = user_id
elif metadata.get('user_id'):
meta['user_id'] = metadata.get('user_id')
if 'memory_type' in kwargs:
kwargs.pop("memory_type")
super().__init__(content=content, metadata=meta, memory_type="fact", **kwargs)
@property
def key(self) -> str:
return self.content.key
@property
def value(self) -> Any:
return self.content.value
@property
def embedding_text(self):
return self.content
def to_openai_message(self) -> dict:
return {
"role": "user",
"content": self.content
}
class MemorySummary(MemoryItem):
"""
Represents a memory summary.
All custom attributes are stored in content and metadata.
Args:
item_ids (str): The IDS of the agent.
summary (str): The summary text.
metadata (Optional[Dict[str, Any]]): Additional metadata.
"""
def __init__(self, item_ids: list[str], summary: str, metadata: MessageMetadata, **kwargs) -> None:
meta = metadata.to_dict
meta['item_ids'] = item_ids
meta['role'] = "user"
super().__init__(content=summary, metadata=meta, memory_type="summary", **kwargs)
@property
def summary_item_ids(self):
return self.metadata['item_ids']
def to_openai_message(self) -> dict:
return {
"role": "user",
"content": self.content
}
class ConversationSummary(MemoryItem):
"""
Represents a conversation summary.
All custom attributes are stored in content and metadata.
Args:
user_id (str): The ID of the user.
session_id (str): The ID of the session.
summary (str): The summary text of the conversation.
metadata (MessageMetadata): Metadata object containing additional information.
"""
def __init__(self, user_id: str, session_id: str, summary: str, metadata: MessageMetadata, **kwargs) -> None:
meta = metadata.to_dict
meta['user_id'] = user_id
meta['session_id'] = session_id
super().__init__(content=summary, metadata=meta, memory_type="conversation_summary", **kwargs)
def to_openai_message(self) -> dict:
return {
"role": "assistant",
"content": self.content
}
class MemoryMessage(MemoryItem):
"""
Represents a memory message with role, user, session, task, and agent information.
Args:
role (str): The role of the message sender.
metadata (MessageMetadata): Metadata object containing user, session, task, and agent IDs.
content (Optional[Any]): Content of the message.
"""
def __init__(self, role: str, metadata: MessageMetadata, content: Optional[Any] = None, memory_type="message", **kwargs) -> None:
meta = metadata.to_dict
meta['role'] = role
super().__init__(content=content, metadata=meta, memory_type=memory_type, **kwargs)
@property
def role(self) -> str:
return self.metadata['role']
@property
def user_id(self) -> str:
return self.metadata['user_id']
@property
def session_id(self) -> str:
return self.metadata['session_id']
@property
def task_id(self) -> str:
return self.metadata['task_id']
def set_task_id(self, task_id):
self.metadata['task_id'] = task_id
@property
def agent_id(self) -> str:
return self.metadata['agent_id']
@abstractmethod
def to_openai_message(self) -> dict:
pass
class MemorySystemMessage(MemoryMessage):
"""
Represents a system message with role and content.
Args:
metadata (MessageMetadata): Metadata object containing user, session, task, and agent IDs.
content (str): The content of the message.
"""
def __init__(self, content: str, metadata: MessageMetadata, **kwargs) -> None:
super().__init__(role="system", metadata=metadata, content=content, memory_type="init", **kwargs)
def to_openai_message(self) -> dict:
return {
"role": self.role,
"content": self.content
}
@property
def embedding_text(self) -> Optional[str]:
return None
class MemoryHumanMessage(MemoryMessage):
"""
Represents a human message with role and content.
Args:
metadata (MessageMetadata): Metadata object containing user, session, task, and agent IDs.
content (str): The content of the message.
"""
def __init__(self, metadata: MessageMetadata, content: Any, memory_type = "init", **kwargs) -> None:
super().__init__(role="user", metadata=metadata, content=content, memory_type=memory_type, **kwargs)
def to_openai_message(self) -> dict:
return {
"role": self.role,
"content": self.content
}
class MemoryAIMessage(MemoryMessage):
"""
Represents an AI message with role and content.
Args:
metadata (MessageMetadata): Metadata object containing user, session, task, and agent IDs.
content (str): The content of the message.
"""
def __init__(self, content: str, tool_calls: Optional[List[ToolCall]] = [], metadata: MessageMetadata = None, **kwargs) -> None:
meta = metadata.to_dict
if tool_calls:
meta['tool_calls'] = [tool_call.to_dict() for tool_call in tool_calls]
super().__init__(role="assistant", metadata=MessageMetadata(**meta), content=content, **kwargs)
@property
def tool_calls(self) -> List[ToolCall]:
if "tool_calls" not in self.metadata or not self.metadata['tool_calls']:
return None
tc = [ToolCall(**tool_call) for tool_call in self.metadata['tool_calls']]
return tc if len(tc) > 0 else None
def to_openai_message(self) -> dict:
return {
"role": self.role,
"content": self.content,
"tool_calls": [tool_call.to_dict() for tool_call in self.tool_calls or []] or None
}
class MemoryToolMessage(MemoryMessage):
"""
Represents a tool message with role, content, tool_call_id, and status.
Args:
metadata (MessageMetadata): Metadata object containing user, session, task, and agent IDs.
tool_call_id (str): The ID of the tool call.
status (Literal["success", "error"]): The status of the tool call.
content (str): The content of the message.
"""
def __init__(self, tool_call_id: str, content: Any, status: Literal["success", "error"] = "success", metadata: MessageMetadata = None, **kwargs) -> None:
metadata.tool_call_id = tool_call_id
metadata.status = status
super().__init__(role="tool", metadata=metadata, content=content, **kwargs)
@property
def tool_call_id(self) -> str:
return self.metadata['tool_call_id']
@property
def status(self) -> str:
return self.metadata['status']
@property
def embedding_text(self) -> Optional[str]:
return None
def to_openai_message(self) -> dict:
return {
"role": self.role,
"content": self.content,
"tool_call_id": self.tool_call_id,
}
class LongTermExtractParams(BaseModel):
session_id: str = Field(description="The ID of the session")
task_id: Optional[str] = Field(description="The ID of the task")
memories: List[MemoryItem] = Field(default_factory=list, description="The list of memories to process")
application_id: Optional[str] = Field(default=None, description="The ID of the application")
extract_type: Literal["user_profile", "agent_experience"] = Field(description="The type of long-term extract")
def to_openai_messages(self) -> List[dict]:
return [memory.to_openai_message() for memory in self.memories]
class UserProfileExtractParams(LongTermExtractParams):
user_id: Optional[str] = Field(description="The ID of the user")
def __init__(self, user_id: str, session_id: str, task_id: str, memories: List[MemoryItem] = None, application_id: str = None, **kwargs) -> None:
kwargs = {
"user_id": user_id,
"session_id": session_id,
"task_id": task_id,
"memories": memories or [],
"application_id": application_id,
"extract_type": "user_profile",
**kwargs
}
super().__init__(**kwargs)
model_config = ConfigDict(extra="allow")
class AgentExperienceExtractParams(LongTermExtractParams):
agent_id: str = Field(default=None, description="The ID of the agent")
def __init__(self, agent_id: str, session_id: str, task_id: str, memories: List[MemoryItem] = None,
application_id: str = None,**kwargs) -> None:
super().__init__(session_id=session_id,
task_id=task_id,
memories=memories,
application_id=application_id,
extract_type="agent_experience", **kwargs)
self.agent_id = agent_id
model_config = ConfigDict(extra="allow")
class LongTermMemoryTriggerParams(BaseModel):
"""
Metadata for memory messages, including user, session, task, and agent information.
Args:
user_id (str): The ID of the user.
session_id (str): The ID of the session.
task_id (str): The ID of the task.
agent_id (str): The ID of the agent.
"""
agent_id: str = Field(default=None, description="The ID of the agent")
session_id: str = Field(default=None, description="The ID of the session")
task_id: str = Field(default=None, description="The ID of the task")
user_id: Optional[str] = Field(default=None, description="The ID of the user")
application_id: Optional[str] = Field(default="default", description="The ID of the application, namespace for memory")
force: Optional[bool] = Field(default=False, description="Whether to force trigger long-term memory")
model_config = ConfigDict(extra="allow")