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,98 @@
# Checkpoint Module
## Overview
The Checkpoint module provides a robust and extensible framework for managing state snapshots (checkpoints) in Python applications. It is designed for scenarios where you need to persist, restore, and version the state of a process, session, or task.
```mermaid
sequenceDiagram
participant Application
participant CheckpointRepository
participant BackendStorage
Note over Application,BackendStorage: Create and store a checkpoint
%% Create and store a checkpoint
Application->>CheckpointRepository: create checkpoint
CheckpointRepository->>BackendStorage: put(checkpoint)
BackendStorage-->>CheckpointRepository: success
CheckpointRepository-->>Application: ack
Note over Application,BackendStorage: Retrieve the latest checkpoint by session
%% Retrieve the latest checkpoint by session
Application->>CheckpointRepository: get checkpoint by session_id
CheckpointRepository->>BackendStorage: get_by_session(session_id)
BackendStorage-->>CheckpointRepository: Checkpoint
CheckpointRepository-->>Application: Checkpoint
```
## Key Features
- **Structured Data Model**: Uses Pydantic's `BaseModel` for strong typing and validation of checkpoint data and metadata.
- **Versioning Support**: Built-in version management utilities for checkpoint evolution and comparison.
- **Extensible Repository Pattern**: Abstract base class (`BaseCheckpointRepository`) defines a standard interface for checkpoint storage, supporting both synchronous and asynchronous operations.
- **In-Memory Implementation**: Includes a simple, ready-to-use in-memory repository for development and testing.
- **Utility Functions**: Helper methods for creating, copying, and managing checkpoints.
## Data Structures
```mermaid
classDiagram
class Application {
+CheckpointRepository repo
+create_checkpoint()
+get_checkpoint_by_session()
}
class CheckpointRepository {
+put(checkpoint)
+get_by_session(session_id)
+delete_by_session(session_id)
-BackendStorage backend
}
class BackendStorage {
+put(checkpoint)
+get_by_session(session_id)
+delete_by_session(session_id)
}
Application --> CheckpointRepository : uses
CheckpointRepository --> BackendStorage : delegates
class Checkpoint {
+id: str
+ts: str
+metadata: CheckpointMetadata
+values: dict
+version: int
+parent_id: str
+namespace: str
}
class CheckpointMetadata {
+session_id: str
+task_id: str
}
Checkpoint o-- CheckpointMetadata
CheckpointRepository o-- Checkpoint
BackendStorage o-- Checkpoint
```
## Usage Example
```python
from aworld.checkpoint import (
Checkpoint, CheckpointMetadata, empty_checkpoint, create_checkpoint, InMemoryCheckpointRepository
)
# Create a new checkpoint
metadata = CheckpointMetadata(session_id="session-123", task_id="task-456")
values = {"step": 1, "score": 100}
checkpoint = create_checkpoint(values=values, metadata=metadata)
# Store and retrieve using the in-memory repository
repo = InMemoryCheckpointRepository()
repo.put(checkpoint)
restored = repo.get(checkpoint.id)
```
## Extensibility
- Implement custom repositories by inheriting from `BaseCheckpointRepository` (e.g., for database, file, or cloud storage).
- Extend versioning logic via the `VersionUtils` class.
@@ -0,0 +1,245 @@
from typing import Any, Dict, Optional, List
import copy
import uuid
from datetime import datetime, timezone
from abc import ABC, abstractmethod
import asyncio
from pydantic import BaseModel, Field, ConfigDict
class CheckpointMetadata(BaseModel):
"""
Metadata for a checkpoint, including session and task identifiers.
Attributes:
session_id (str): The session identifier (required).
task_id (Optional[str]): The task identifier (optional).
artifact_id (Optional[str]): The artifact identifier (optional).
"""
session_id: str = Field(..., description="The session identifier.")
task_id: Optional[str] = Field(None, description="The task identifier.")
artifact_id: Optional[str] = Field(None, description="The artifact identifier.")
model_config = ConfigDict(extra="allow")
class Checkpoint(BaseModel):
"""
Core structure for a state checkpoint.
Attributes:
id (str): Unique identifier for the checkpoint.
ts (str): Timestamp of the checkpoint.
metadata (CheckpointMetadata): Metadata associated with the checkpoint.
values (dict[str, Any]): State values stored in the checkpoint.
version (str): Version of the checkpoint format.
parent_id (Optional[str]): Parent checkpoint identifier, if any.
namespace (str): Namespace for the checkpoint, default is 'aworld'.
"""
id: str = Field(..., description="Unique identifier for the checkpoint.")
ts: str = Field(..., description="Timestamp of the checkpoint.")
metadata: CheckpointMetadata = Field(..., description="Metadata associated with the checkpoint.")
values: Dict[str, Any] = Field(..., description="State values stored in the checkpoint.")
version: int = Field(..., description="Version of the checkpoint format.")
parent_id: Optional[str] = Field(default=None, description="Parent checkpoint identifier, if any.")
namespace: str = Field(default="aworld", description="Namespace for the checkpoint, default is 'aworld'.")
def empty_checkpoint() -> Checkpoint:
"""
Create an empty checkpoint with default values.
Returns:
Checkpoint: An empty checkpoint structure.
"""
return Checkpoint(
id=str(uuid.uuid4()),
ts=datetime.now(timezone.utc).isoformat(),
metadata=CheckpointMetadata(session_id="", task_id=None),
values={},
version=1,
parent_id=None,
namespace="aworld",
)
def copy_checkpoint(checkpoint: Checkpoint) -> Checkpoint:
"""
Create a deep copy of a checkpoint.
Args:
checkpoint (Checkpoint): The checkpoint to copy.
Returns:
Checkpoint: A deep copy of the provided checkpoint.
"""
return copy.deepcopy(checkpoint)
def create_checkpoint(
values: Dict[str, Any],
metadata: CheckpointMetadata,
parent_id: Optional[str] = None,
version: int = 1,
namespace: str = 'aworld',
) -> Checkpoint:
"""
Create a new checkpoint from provided state values and metadata.
Args:
values (dict[str, Any]): State values to store in the checkpoint.
metadata (CheckpointMetadata): Metadata for the checkpoint.
parent_id (Optional[str]): Parent checkpoint identifier, if any.
version (str): Version of the checkpoint format.
namespace (str): Namespace for the checkpoint.
Returns:
Checkpoint: The newly created checkpoint.
"""
return Checkpoint(
id=str(uuid.uuid4()),
ts=datetime.now(timezone.utc).isoformat(),
metadata=metadata,
values=values,
version=version,
parent_id=parent_id,
namespace=namespace,
)
class BaseCheckpointRepository(ABC):
"""
Abstract base class for a checkpoint repository.
Provides synchronous and asynchronous methods for checkpoint management.
"""
@abstractmethod
def get(self, checkpoint_id: str) -> Optional[Checkpoint]:
"""
Retrieve a checkpoint by its unique identifier.
Args:
checkpoint_id (str): The unique identifier of the checkpoint.
Returns:
Optional[Checkpoint]: The checkpoint if found, otherwise None.
"""
pass
@abstractmethod
def list(self, params: Dict[str, Any]) -> List[Checkpoint]:
"""
List checkpoints matching the given parameters.
Args:
params (dict): Parameters to filter checkpoints.
Returns:
List[Checkpoint]: List of matching checkpoints.
"""
pass
@abstractmethod
def put(self, checkpoint: Checkpoint) -> None:
"""
Store a checkpoint.
Args:
checkpoint (Checkpoint): The checkpoint to store.
"""
pass
@abstractmethod
def get_by_session(self, session_id: str) -> Optional[Checkpoint]:
"""
Get the latest checkpoint for a session.
Args:
session_id (str): The session identifier.
Returns:
Optional[Checkpoint]: The latest checkpoint if found, otherwise None.
"""
pass
@abstractmethod
def delete_by_session(self, session_id: str) -> None:
"""
Delete all checkpoints related to a session.
Args:
session_id (str): The session identifier.
"""
pass
# Async methods
async def aget(self, checkpoint_id: str) -> Optional[Checkpoint]:
"""
Asynchronously retrieve a checkpoint by its unique identifier.
Args:
checkpoint_id (str): The unique identifier of the checkpoint.
Returns:
Optional[Checkpoint]: The checkpoint if found, otherwise None.
"""
return await asyncio.to_thread(self.get, checkpoint_id)
async def alist(self, params: Dict[str, Any]) -> List[Checkpoint]:
"""
Asynchronously list checkpoints matching the given parameters.
Args:
params (dict): Parameters to filter checkpoints.
Returns:
List[Checkpoint]: List of matching checkpoints.
"""
return await asyncio.to_thread(self.list, params)
async def aput(self, checkpoint: Checkpoint) -> None:
"""
Asynchronously store a checkpoint.
Args:
checkpoint (Checkpoint): The checkpoint to store.
"""
await asyncio.to_thread(self.put, checkpoint)
async def aget_by_session(self, session_id: str) -> Optional[Checkpoint]:
"""
Asynchronously get the latest checkpoint for a session.
Args:
session_id (str): The session identifier.
Returns:
Optional[Checkpoint]: The latest checkpoint if found, otherwise None.
"""
return await asyncio.to_thread(self.get_by_session, session_id)
async def adelete_by_session(self, session_id: str) -> None:
"""
Asynchronously delete all checkpoints related to a session.
Args:
session_id (str): The session identifier.
"""
await asyncio.to_thread(self.delete_by_session, session_id)
class VersionUtils:
@staticmethod
def get_next_version(version: int) -> int:
"""
Get the next version of the checkpoint.
"""
return version + 1
@staticmethod
def get_previous_version(version: int) -> int:
"""
Get the previous version of the checkpoint.
"""
return version - 1
@staticmethod
def is_version_greater(checkpoint: Checkpoint, version: int) -> bool:
"""
Check if the checkpoint version is greater than the given version.
"""
return checkpoint.version > version
@staticmethod
def is_version_less(checkpoint: Checkpoint, version: int) -> bool:
"""
Check if the checkpoint version is less than the given version.
"""
return checkpoint.version < version
@@ -0,0 +1,116 @@
from typing import Any, Dict, List, Optional
from . import Checkpoint, BaseCheckpointRepository, VersionUtils
class InMemoryCheckpointRepository(BaseCheckpointRepository):
"""
In-memory implementation of BaseCheckpointRepository.
Stores checkpoints in a simple in-memory dictionary.
Thread safety is not guaranteed.
"""
def __init__(self) -> None:
"""
Initialize the in-memory checkpoint repository.
"""
self._checkpoints: Dict[str, Checkpoint] = {}
self._session_index: Dict[str, List[str]] = {}
def get(self, checkpoint_id: str) -> Optional[Checkpoint]:
"""
Retrieve a checkpoint by its unique identifier.
Args:
checkpoint_id (str): The unique identifier of the checkpoint.
Returns:
Optional[Checkpoint]: The checkpoint if found, otherwise None.
"""
return self._checkpoints.get(checkpoint_id)
def list(self, params: Dict[str, Any]) -> List[Checkpoint]:
"""
List checkpoints matching the given parameters.
Args:
params (dict): Parameters to filter checkpoints.
Returns:
List[Checkpoint]: List of matching checkpoints.
"""
result = []
for cp in self._checkpoints.values():
match = True
for k, v in params.items():
if k == 'session_id':
if cp.metadata.session_id != v:
match = False
break
elif k == 'task_id':
if cp.metadata.task_id != v:
match = False
break
elif cp.get(k) != v:
match = False
break
if match:
result.append(cp)
return result
def put(self, checkpoint: Checkpoint) -> None:
"""
Store a checkpoint.
Args:
checkpoint (Checkpoint): The checkpoint to store.
"""
# Find last version checkpoint by session_id
last_checkpoint = self.get_by_session(checkpoint.metadata.session_id)
if last_checkpoint:
# Compare versions to ensure optimistic locking
if VersionUtils.is_version_less(checkpoint, last_checkpoint.version):
raise ValueError(f"New checkpoint version {checkpoint.version} must be greater than last version {last_checkpoint.version}")
# Store the new checkpoint
self._checkpoints[checkpoint.id] = checkpoint
# Update session index
session_id = checkpoint.metadata.session_id
if session_id:
if session_id not in self._session_index:
self._session_index[session_id] = []
self._session_index[session_id].append(checkpoint.id)
def get_by_session(self, session_id: str) -> Optional[Checkpoint]:
"""
Get the latest checkpoint for a session.
Args:
session_id (str): The session identifier.
Returns:
Optional[Checkpoint]: The latest checkpoint if found, otherwise None.
"""
ids = self._session_index.get(session_id, [])
if not ids:
return None
# Assume the last one is the latest
last_id = ids[-1]
return self._checkpoints.get(last_id)
def delete_by_session(self, session_id: str) -> None:
"""
Delete all checkpoints related to a session.
Args:
session_id (str): The session identifier.
"""
ids = self._session_index.pop(session_id, [])
for cid in ids:
self._checkpoints.pop(cid, None)
async def alist(self, params: Dict[str, Any]) -> List[Checkpoint]:
return self.list(params)
async def aget(self, checkpoint_id: str) -> Optional[Checkpoint]:
return self.get(checkpoint_id)
async def aput(self, checkpoint: Checkpoint) -> None:
self.put(checkpoint)
async def aget_by_session(self, session_id: str) -> Optional[Checkpoint]:
return self.get_by_session(session_id)
async def adelete_by_session(self, session_id: str) -> None:
self.delete_by_session(session_id)