1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
//! The `knowledge_base` technique (R1) as a memory provider.
//!
//! When a profile lists `knowledge_base` (`docs/design/technique-library.md`),
//! this provider injects the authoritative PyO3 import surface — the FFI manifest
//! ([`crate::ffi_manifest`]) — into the frozen system prompt, so the model imports
//! real paths (`newt_agent._newt_agent.core`) instead of guessing `newt_core` from
//! the crate name (the cross-family confabulation, `docs/findings/`). It rides the
//! same provider seam as [`crate::AgentsProvider`], so the block survives every
//! system-prompt rebuild. A **no-op on a non-PyO3 workspace** (empty manifest → no
//! block) — the technique generalizes safely.
//!
//! **Compression role (#661 group E).** Because the surface lives in the frozen
//! system prompt — the compressor's protected head ([`super::agentic::compress`]
//! `head_len`) — it is a **stable base that is NEVER summarized away**: the model
//! keeps an exact import surface even after the middle is compacted, so the lossy
//! summary has less it must preserve, and an import detail can't be lost to
//! compression. This is the "inject the authoritative import surface as a stable
//! base so there's less to summarize" half of the summarizer-effectiveness suite,
//! verified by `compress::tests::knowledge_base_stable_base_survives_compression`.
use async_trait::async_trait;
use std::path::Path;
use crate::ffi_manifest::FfiManifest;
use crate::memory::{MemMessage, MemoryProvider, SessionContext};
use crate::metrics::TurnMetrics;
/// Injects the workspace's FFI import surface into the system prompt.
#[derive(Default)]
pub struct FfiSurfaceProvider {
/// The rendered surface block, computed once at [`initialize`](Self::initialize).
/// `None` when the workspace has no PyO3 bindings.
block: Option<String>,
}
impl FfiSurfaceProvider {
/// A provider that resolves its surface from the session workspace.
#[must_use]
pub fn new() -> Self {
Self::default()
}
}
#[async_trait]
impl MemoryProvider for FfiSurfaceProvider {
fn name(&self) -> &str {
"knowledge_base"
}
async fn initialize(&mut self, ctx: &SessionContext) -> anyhow::Result<()> {
let manifest = FfiManifest::from_workspace(Path::new(&ctx.workspace)).unwrap_or_default();
let n = manifest.len();
self.block = if manifest.is_empty() {
None
} else {
Some(manifest.render_block())
};
if self.block.is_some() {
tracing::info!(crates = n, "knowledge_base: FFI import surface injected");
}
Ok(())
}
fn system_prompt_block(&self) -> Option<String> {
self.block.clone()
}
fn build_messages(&self, _system_prompt: &str, _new_task: &str) -> Vec<MemMessage> {
// System-prompt-only provider; history is managed elsewhere.
Vec::new()
}
async fn sync_turn(&mut self, _user: &str, _assistant: &str, _metrics: &TurnMetrics) {}
}
#[cfg(test)]
mod tests {
use super::*;
fn ctx(workspace: &str) -> SessionContext {
SessionContext {
workspace: workspace.to_string(),
session_id: "s".into(),
}
}
fn write_binding(root: &Path, krate: &str, submodule: &str) {
let dir = root.join(krate).join("src");
std::fs::create_dir_all(&dir).unwrap();
std::fs::write(
dir.join("pyo3_module.rs"),
format!("#[pyclass(name = \"X\", module = \"newt_agent._newt_agent.{submodule}\")] struct X;"),
)
.unwrap();
}
#[tokio::test]
async fn injects_surface_for_a_pyo3_workspace() {
let dir = tempfile::tempdir().unwrap();
write_binding(dir.path(), "newt-core", "core");
let mut p = FfiSurfaceProvider::new();
p.initialize(&ctx(dir.path().to_str().unwrap()))
.await
.unwrap();
let block = p.system_prompt_block().expect("a surface block");
assert!(block.contains("newt_agent._newt_agent.core"));
assert!(block.contains("authoritative"));
}
#[tokio::test]
async fn no_op_on_non_pyo3_workspace() {
let dir = tempfile::tempdir().unwrap();
std::fs::write(dir.path().join("README.md"), "no bindings here").unwrap();
let mut p = FfiSurfaceProvider::new();
p.initialize(&ctx(dir.path().to_str().unwrap()))
.await
.unwrap();
assert!(p.system_prompt_block().is_none(), "should inject nothing");
}
}