メモリーに関するクレート作成・ファイル構造の実装
This commit is contained in:
@@ -14,7 +14,10 @@ use serde::{Deserialize, Serialize};
|
||||
|
||||
use crate::defaults;
|
||||
use crate::model::{AuthRef, ModelManifest};
|
||||
use crate::{CompactionConfig, PodManifest, PodMeta, ScopeConfig, ToolOutputLimits, WorkerManifest};
|
||||
use crate::{
|
||||
CompactionConfig, MemoryConfig, PodManifest, PodMeta, ScopeConfig, ToolOutputLimits,
|
||||
WorkerManifest,
|
||||
};
|
||||
|
||||
/// Partial-form Pod manifest. Every field is optional; one or more
|
||||
/// instances merge via [`PodManifestConfig::merge`] before being
|
||||
@@ -35,6 +38,9 @@ pub struct PodManifestConfig {
|
||||
pub scope: ScopeConfig,
|
||||
#[serde(default)]
|
||||
pub compaction: Option<CompactionConfigPartial>,
|
||||
/// Memory subsystem opt-in. See [`MemoryConfig`].
|
||||
#[serde(default)]
|
||||
pub memory: Option<MemoryConfig>,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||
@@ -162,6 +168,11 @@ impl PodManifestConfig {
|
||||
for rule in &mut self.scope.deny {
|
||||
rule.target = join_if_relative(base, &rule.target);
|
||||
}
|
||||
if let Some(ref mut memory) = self.memory
|
||||
&& let Some(ref mut root) = memory.workspace_root
|
||||
{
|
||||
*root = join_if_relative(base, root);
|
||||
}
|
||||
if let Some(ref mut compaction) = self.compaction
|
||||
&& let Some(ref mut cp) = compaction.model
|
||||
{
|
||||
@@ -185,6 +196,15 @@ impl PodManifestConfig {
|
||||
upper.compaction,
|
||||
CompactionConfigPartial::merge,
|
||||
),
|
||||
memory: merge_option(self.memory, upper.memory, MemoryConfig::merge),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl MemoryConfig {
|
||||
fn merge(self, upper: Self) -> Self {
|
||||
Self {
|
||||
workspace_root: upper.workspace_root.or(self.workspace_root),
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -375,6 +395,7 @@ impl TryFrom<PodManifestConfig> for PodManifest {
|
||||
worker,
|
||||
scope: cfg.scope,
|
||||
compaction,
|
||||
memory: cfg.memory,
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -417,6 +438,7 @@ mod tests {
|
||||
deny: Vec::new(),
|
||||
},
|
||||
compaction: None,
|
||||
memory: None,
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -31,6 +31,25 @@ pub struct PodManifest {
|
||||
pub scope: ScopeConfig,
|
||||
#[serde(default)]
|
||||
pub compaction: Option<CompactionConfig>,
|
||||
/// Memory subsystem opt-in. Presence of `[memory]` in TOML enables
|
||||
/// the memory tools (MemoryRead / MemoryWrite / MemoryEdit) and
|
||||
/// causes Pod to deny generic write access to `<workspace>/memory/`
|
||||
/// and `<workspace>/knowledge/`. Absent ⇒ legacy behaviour, no
|
||||
/// memory tools registered.
|
||||
#[serde(default)]
|
||||
pub memory: Option<MemoryConfig>,
|
||||
}
|
||||
|
||||
/// Memory subsystem configuration. Presence in the manifest enables
|
||||
/// memory; the workspace root defaults to the Pod's pwd unless an
|
||||
/// explicit override is given.
|
||||
#[derive(Debug, Clone, Default, Serialize, Deserialize)]
|
||||
pub struct MemoryConfig {
|
||||
/// Override for the workspace root. When `None`, the Pod's pwd
|
||||
/// (resolved at construction time) is used. When set, must be an
|
||||
/// absolute path.
|
||||
#[serde(default)]
|
||||
pub workspace_root: Option<PathBuf>,
|
||||
}
|
||||
|
||||
/// Pod metadata.
|
||||
@@ -411,6 +430,33 @@ model_id = "claude-sonnet-4-20250514"
|
||||
assert!(manifest.compaction.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn omitted_memory_is_none() {
|
||||
let manifest = PodManifest::from_toml(MINIMAL_REQUIRED).unwrap();
|
||||
assert!(manifest.memory.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn empty_memory_section_enables_with_default_root() {
|
||||
let toml = format!("{MINIMAL_REQUIRED}\n[memory]\n");
|
||||
let manifest = PodManifest::from_toml(&toml).unwrap();
|
||||
let mem = manifest.memory.expect("memory section parsed");
|
||||
assert!(mem.workspace_root.is_none());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn memory_section_with_explicit_root() {
|
||||
let toml = format!(
|
||||
"{MINIMAL_REQUIRED}\n[memory]\nworkspace_root = \"/some/where\"\n"
|
||||
);
|
||||
let manifest = PodManifest::from_toml(&toml).unwrap();
|
||||
let mem = manifest.memory.unwrap();
|
||||
assert_eq!(
|
||||
mem.workspace_root.unwrap(),
|
||||
std::path::PathBuf::from("/some/where")
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn reject_unknown_scheme() {
|
||||
let toml =
|
||||
|
||||
Reference in New Issue
Block a user