Skip to main content Skills Marktplatz Entdecken und erkunden Sie KI-Skills, die von der Community erstellt wurden.
Mit Codex oder Claude installieren Kopieren Sie diesen Prompt, fügen Sie ihn in Codex, Claude oder einen anderen Assistant ein und lassen Sie die Skill-Seite prüfen und installieren.
Prompt kopierenPrompt-Details anzeigen Ein direkter Befehl überspringt den Prüf-Prompt. Prüfen Sie die Quelle, bevor Sie ihn ausführen.
npx skills add https://github.com/majiayu000/sage --skill sage-checkpoint-systemDer Befehl bleibt in einer Zeile. Scrollen Sie horizontal, um ihn vor dem Kopieren vollständig zu prüfen.
Sie bevorzugen eine lokale Kopie? Laden Sie die Dateien herunter, die SkillsMP derzeit vorliegen.
ZIP herunterladen Herunterladen... Mehr aus diesem Repository
Verwandte Berufe SOC
Basierend auf der SOC-Berufsklassifikation
name sage-checkpoint-system description Sage 独有的检查点系统设计,包含状态快照、文件追踪、回滚恢复机制 when_to_use 当需要实现状态恢复、设计撤销功能、或处理事务性操作时使用 allowed_tools ["Read","Grep","Glob","Edit","Write"] user_invocable true priority 75
Sage 检查点系统指南
概述
Sage 的 checkpoints/ 模块是独有的竞争优势 ,提供:
状态快照 : 保存完整执行状态
文件追踪 : 追踪所有文件变更
差异计算 : 高效计算和存储差异
回滚恢复 : 安全回滚到任意检查点
模块结构
checkpoints/
├── mod.rs # 公开接口
├── manager.rs # 检查点管理器
├── storage/ # 存储实现
│ ├── mod.rs
│ ├── file.rs # 文件存储
│ └── memory.rs # 内存存储(测试用)
├── snapshot.rs # 快照类型
├── diff.rs # 差异计算
├── detector.rs # 变更检测
└── restore.rs # 恢复逻辑
检查点类型
{
Auto,
Manual,
PreToolExecution,
Session,
}
{
id: CheckpointId,
checkpoint_type: CheckpointType,
created_at: DateTime<Utc>,
description: < >,
file_states: <FileSnapshot>,
conversation: ConversationSnapshot,
token_usage: TokenUsageSnapshot,
tool_executions: <ToolExecutionRecord>,
}
pub
enum
CheckpointType
pub
struct
Checkpoint
pub
pub
pub
pub
Option
String
pub
Vec
pub
pub
pub
Vec
检查点管理器
初始化 use sage_core::checkpoints::{CheckpointManager, CheckpointManagerConfig};
let config = CheckpointManagerConfig {
storage_path: PathBuf::from (".sage/checkpoints" ),
max_checkpoints: 50 ,
auto_checkpoint_interval: Duration::from_secs (300 ),
retention_policy: RetentionPolicy::KeepLast (20 ),
};
let manager = CheckpointManager::new (config).await ?;
创建检查点
let checkpoint = manager.create_checkpoint (
CheckpointType::Manual,
Some ("Before refactoring" .to_string ()),
).await ?;
println! ("Checkpoint created: {}" , checkpoint.id);
let checkpoint = manager.create_pre_tool_checkpoint (&tool_call).await ?;
列出检查点 let checkpoints = manager.list_checkpoints ().await ?;
for cp in checkpoints {
println! ("{} - {} - {:?}" ,
cp.id,
cp.created_at.format("%Y-%m-%d %H:%M:%S" ),
cp.checkpoint_type,
);
}
恢复检查点 use sage_core::checkpoints::{RestoreOptions, RestorePreview};
let preview = manager.preview_restore (&checkpoint_id).await ?;
println! ("Files to restore: {}" , preview.files_to_restore.len ());
println! ("Files to delete: {}" , preview.files_to_delete.len ());
for file in &preview.files_to_restore {
println! (" {} ({:+} lines)" , file.path, file.line_diff);
}
let options = RestoreOptions {
restore_files: true ,
restore_conversation: false ,
dry_run: false ,
};
let result = manager.restore (&checkpoint_id, options).await ?;
println! ("Restored {} files" , result.files_restored);
文件状态快照
FileSnapshot 结构 pub struct FileSnapshot {
pub path: PathBuf,
pub state: FileState,
pub content_hash: String ,
pub size: u64 ,
pub modified_at: DateTime<Utc>,
pub permissions: Option <u32 >,
}
pub enum FileState {
Exists { content: Vec <u8 > },
ExistsDiff { base_hash: String , diff: TextDiff },
NotExists,
}
变更检测 use sage_core::checkpoints::ChangeDetector;
let detector = ChangeDetector::new (&working_dir);
let changes = detector.detect_changes (&previous_checkpoint).await ?;
for change in changes {
match change {
FileChange::Created (path) => println! ("+ {}" , path),
FileChange::Modified (path) => println! ("M {}" , path),
FileChange::Deleted (path) => println! ("- {}" , path),
}
}
差异计算
文本差异 use sage_core::checkpoints::{TextDiff, DiffHunk};
let diff = TextDiff::compute (&old_content, &new_content);
println! ("Hunks: {}" , diff.hunks.len ());
for hunk in &diff.hunks {
println! ("@@ -{},{} +{},{} @@" ,
hunk.old_start, hunk.old_lines,
hunk.new_start, hunk.new_lines,
);
for line in &hunk.lines {
match line {
DiffLine::Context (s) => println! (" {}" , s),
DiffLine::Added (s) => println! ("+{}" , s),
DiffLine::Removed (s) => println! ("-{}" , s),
}
}
}
let restored = diff.apply (&old_content)?;
assert_eq! (restored, new_content);
增量存储 impl CheckpointStorage for FileCheckpointStorage {
async fn store (&self , checkpoint: &Checkpoint) -> Result <()> {
for file in &checkpoint.file_states {
match &file.state {
FileState::Exists { content } => {
if let Some (base) = self .find_base (&file.content_hash).await ? {
let diff = TextDiff::compute (&base, content);
if diff.size () < content.len () / 2 {
self .store_diff (&file.path, &checkpoint.id, diff).await ?;
continue ;
}
}
self .store_full (&file.path, &checkpoint.id, content).await ?;
}
FileState::NotExists => {
self .store_deletion (&file.path, &checkpoint.id).await ?;
}
_ => {}
}
}
Ok (())
}
}
会话快照 pub struct ConversationSnapshot {
pub messages: Vec <ConversationMessage>,
pub mode: AgentMode,
pub active_skills: Vec <String >,
pub context_variables: HashMap<String , String >,
}
pub struct TokenUsageSnapshot {
pub total_tokens: u64 ,
pub input_tokens: u64 ,
pub output_tokens: u64 ,
pub cost_usd: f64 ,
}
恢复策略
选择性恢复 pub struct RestoreOptions {
pub restore_files: bool ,
pub restore_conversation: bool ,
pub restore_token_usage: bool ,
pub file_filter: Option <Vec <PathBuf>>,
pub exclude_files: Vec <PathBuf>,
pub dry_run: bool ,
pub backup_before_restore: bool ,
}
let options = RestoreOptions {
restore_files: true ,
restore_conversation: false ,
file_filter: Some (vec! [
PathBuf::from ("src/main.rs" ),
PathBuf::from ("src/lib.rs" ),
]),
dry_run: true ,
..Default ::default ()
};
let preview = manager.restore (&checkpoint_id, options).await ?;
冲突处理 pub enum ConflictResolution {
PreferCheckpoint,
PreferCurrent,
CreateConflictFile,
AskUser,
}
impl CheckpointManager {
pub async fn restore_with_conflicts (
&self ,
checkpoint_id: &CheckpointId,
resolution: ConflictResolution,
) -> Result <RestoreResult> {
let preview = self .preview_restore (checkpoint_id).await ?;
for conflict in preview.conflicts {
match resolution {
ConflictResolution::PreferCheckpoint => {
self .restore_file (&conflict.path, checkpoint_id).await ?;
}
ConflictResolution::PreferCurrent => {
}
ConflictResolution::CreateConflictFile => {
let conflict_path = format! ("{}.checkpoint" , conflict.path);
self .restore_file_to (&conflict.path, checkpoint_id, &conflict_path).await ?;
}
ConflictResolution::AskUser => {
self .emit_conflict_event (&conflict).await ?;
}
}
}
Ok (RestoreResult { })
}
}
与其他模块集成
与 Tools 集成 impl ToolExecutor {
pub async fn execute_with_checkpoint (&self , call: &ToolCall) -> Result <ToolResult> {
let checkpoint = self .checkpoint_manager
.create_pre_tool_checkpoint (call)
.await ?;
let result = self .execute_inner (call).await ;
match &result {
Ok (_) => {
self .checkpoint_manager
.record_tool_execution (&checkpoint.id, call, &result)
.await ?;
}
Err (e) if e.is_recoverable () => {
log::warn!("Tool execution failed, checkpoint available: {}" , checkpoint.id);
}
Err (_) => {
self .checkpoint_manager
.restore (&checkpoint.id, RestoreOptions::files_only ())
.await ?;
}
}
result
}
}
与 Agent 集成 impl AgentExecutor {
pub async fn run_with_checkpoints (&mut self , task: &Task) -> Result <()> {
let session_checkpoint = self .checkpoint_manager
.create_checkpoint (CheckpointType::Session, None )
.await ?;
let auto_checkpoint_task = tokio::spawn (async move {
loop {
tokio::time::sleep (Duration::from_secs (300 )).await ;
self .checkpoint_manager
.create_checkpoint (CheckpointType::Auto, None )
.await ?;
}
});
let result = self .execute (task).await ;
auto_checkpoint_task.abort ();
result
}
}
与 Commands 集成
pub struct CheckpointCommand ;
impl SlashCommand for CheckpointCommand {
fn name (&self ) -> &str { "checkpoint" }
async fn execute (&self , args: &str , ctx: &CommandContext) -> Result <String > {
match args.split_whitespace ().next () {
Some ("create" ) => {
let desc = args.strip_prefix ("create" ).map (|s| s.trim ().to_string ());
let cp = ctx.checkpoint_manager
.create_checkpoint (CheckpointType::Manual, desc)
.await ?;
Ok (format! ("Checkpoint created: {}" , cp.id))
}
Some ("list" ) => {
let checkpoints = ctx.checkpoint_manager.list_checkpoints ().await ?;
let output = checkpoints.iter ()
.map (|cp| format! ("{} - {}" , cp.id.short (), cp.created_at))
.collect::<Vec <_>>()
.join ("\n" );
Ok (output)
}
Some ("restore" ) => {
let id = args.strip_prefix ("restore" )
.and_then (|s| s.trim ().parse ().ok ())
.ok_or (Error::InvalidArgs)?;
let result = ctx.checkpoint_manager
.restore (&id, RestoreOptions::default ())
.await ?;
Ok (format! ("Restored {} files" , result.files_restored))
}
_ => Ok ("Usage: /checkpoint [create|list|restore <id>]" .to_string ())
}
}
}
存储优化
压缩存储 impl CheckpointStorage {
async fn store_compressed (&self , content: &[u8 ]) -> Result <Vec <u8 >> {
use flate2::write::GzEncoder;
use flate2::Compression;
let mut encoder = GzEncoder::new (Vec ::new (), Compression::default ());
encoder.write_all (content)?;
Ok (encoder.finish ()?)
}
}
去重存储 impl CheckpointStorage {
async fn store_deduplicated (&self , file: &FileSnapshot) -> Result <()> {
if self .content_exists (&file.content_hash).await ? {
self .store_reference (&file.path, &file.content_hash).await ?;
} else {
self .store_content (&file.content_hash, &file.content).await ?;
}
Ok (())
}
}
配置建议 CheckpointManagerConfig {
storage_path: PathBuf::from (".sage/checkpoints" ),
max_checkpoints: 50 ,
auto_checkpoint_interval: 300 ,
retention_policy: RetentionPolicy::KeepLast (20 ),
max_checkpoint_size: 100 * 1024 * 1024 ,
compression: true ,
deduplication: true ,
auto_checkpoint_before_dangerous: true ,
}