feat: resume時のscope claimを過去の有効scopeに揃える
This commit is contained in:
@@ -41,11 +41,12 @@ pub use logged_item::{LoggedContentPart, LoggedItem, LoggedRole, from_logged, to
|
||||
pub use session::{
|
||||
SessionStartState, create_compacted_session, create_session, create_session_with_id,
|
||||
ensure_head_or_fork, fork, fork_at, restore, save_config_changed, save_delta, save_extension,
|
||||
save_run_completed, save_run_errored, save_turn_end, save_usage, save_user_input,
|
||||
save_pod_scope, save_run_completed, save_run_errored, save_turn_end, save_usage,
|
||||
save_user_input,
|
||||
};
|
||||
pub use session_log::{
|
||||
EntryHash, HashedEntry, LogEntry, RestoredState, SessionOrigin, build_chain, collect_state,
|
||||
compute_hash,
|
||||
EntryHash, HashedEntry, LogEntry, POD_SCOPE_EXTENSION_DOMAIN, PodScopeSnapshot, RestoredState,
|
||||
SessionOrigin, build_chain, collect_state, compute_hash,
|
||||
};
|
||||
pub use store::{Store, StoreError};
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
|
||||
use crate::SessionId;
|
||||
use crate::logged_item::{LoggedItem, to_logged};
|
||||
use crate::session_log::{self, EntryHash, HashedEntry, LogEntry, SessionOrigin};
|
||||
use crate::session_log::{self, EntryHash, HashedEntry, LogEntry, PodScopeSnapshot, SessionOrigin};
|
||||
use crate::store::{Store, StoreError};
|
||||
use llm_worker::WorkerResult;
|
||||
use llm_worker::llm_client::RequestConfig;
|
||||
@@ -360,6 +360,24 @@ pub async fn save_extension(
|
||||
.await
|
||||
}
|
||||
|
||||
/// Log the Pod's latest runtime scope snapshot.
|
||||
pub async fn save_pod_scope(
|
||||
store: &impl Store,
|
||||
session_id: SessionId,
|
||||
head_hash: &mut Option<EntryHash>,
|
||||
snapshot: &PodScopeSnapshot,
|
||||
) -> Result<(), StoreError> {
|
||||
let payload = serde_json::to_value(snapshot)?;
|
||||
save_extension(
|
||||
store,
|
||||
session_id,
|
||||
head_hash,
|
||||
session_log::POD_SCOPE_EXTENSION_DOMAIN,
|
||||
payload,
|
||||
)
|
||||
.await
|
||||
}
|
||||
|
||||
/// Log a `ConfigChanged` entry.
|
||||
pub async fn save_config_changed(
|
||||
store: &impl Store,
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
use llm_worker::llm_client::types::{Item, RequestConfig};
|
||||
use llm_worker::{UsageRecord, WorkerResult};
|
||||
use protocol::Segment;
|
||||
use protocol::{ScopeRule, Segment};
|
||||
use serde::{Deserialize, Serialize};
|
||||
use sha2::{Digest, Sha256};
|
||||
|
||||
@@ -197,6 +197,16 @@ pub struct SessionOrigin {
|
||||
pub at_hash: EntryHash,
|
||||
}
|
||||
|
||||
/// Domain used by Pod to persist its latest effective runtime scope.
|
||||
pub const POD_SCOPE_EXTENSION_DOMAIN: &str = "pod.scope";
|
||||
|
||||
/// Payload stored in `LogEntry::Extension { domain: "pod.scope", .. }`.
|
||||
#[derive(Debug, Clone, Serialize, Deserialize, PartialEq, Eq)]
|
||||
pub struct PodScopeSnapshot {
|
||||
pub allow: Vec<ScopeRule>,
|
||||
pub deny: Vec<ScopeRule>,
|
||||
}
|
||||
|
||||
/// State collected from log entries.
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct RestoredState {
|
||||
@@ -214,6 +224,9 @@ pub struct RestoredState {
|
||||
/// `LogEntry::Extension` を replay 順に積んだもの。`(domain, payload)`。
|
||||
/// session-store は domain を不透明扱いし、各ドメインが自前で fold する。
|
||||
pub extensions: Vec<(String, serde_json::Value)>,
|
||||
/// Latest runtime scope snapshot persisted by the Pod. `None` means
|
||||
/// the session predates scope persistence or the payload was corrupt.
|
||||
pub pod_scope: Option<PodScopeSnapshot>,
|
||||
/// User submissions in original typed form, in submit order.
|
||||
/// One entry per `LogEntry::UserInput`; the K-th entry corresponds to
|
||||
/// the K-th `Item::user_message` derived during replay (modulo
|
||||
@@ -234,6 +247,7 @@ pub fn collect_state(entries: &[HashedEntry]) -> RestoredState {
|
||||
head_hash: None,
|
||||
usage_history: Vec::new(),
|
||||
extensions: Vec::new(),
|
||||
pod_scope: None,
|
||||
user_segments: Vec::new(),
|
||||
};
|
||||
|
||||
@@ -296,6 +310,9 @@ pub fn collect_state(entries: &[HashedEntry]) -> RestoredState {
|
||||
LogEntry::Extension {
|
||||
domain, payload, ..
|
||||
} => {
|
||||
if domain == POD_SCOPE_EXTENSION_DOMAIN {
|
||||
state.pod_scope = serde_json::from_value(payload.clone()).ok();
|
||||
}
|
||||
state.extensions.push((domain.clone(), payload.clone()));
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user