feat(pod): wire knowledge slugs into # completion
This commit is contained in:
@@ -388,6 +388,12 @@ impl PodController {
|
||||
.map(|slug| crate::shared_state::WorkflowCandidate { slug })
|
||||
.collect(),
|
||||
);
|
||||
shared_state.set_knowledge(
|
||||
pod.knowledge_completions()
|
||||
.into_iter()
|
||||
.map(|slug| crate::shared_state::KnowledgeCandidate { slug })
|
||||
.collect(),
|
||||
);
|
||||
runtime_dir.write_manifest(&manifest_toml).await?;
|
||||
runtime_dir.write_status(&shared_state).await?;
|
||||
runtime_dir.write_history(&shared_state).await?;
|
||||
|
||||
@@ -102,7 +102,15 @@ async fn handle_connection(stream: tokio::net::UnixStream, handle: PodHandle) {
|
||||
is_dir: c.is_dir,
|
||||
})
|
||||
.collect(),
|
||||
protocol::CompletionKind::Knowledge => Vec::new(),
|
||||
protocol::CompletionKind::Knowledge => handle
|
||||
.shared_state
|
||||
.list_knowledge_completions(&prefix)
|
||||
.into_iter()
|
||||
.map(|c| protocol::CompletionEntry {
|
||||
value: c.slug,
|
||||
is_dir: false,
|
||||
})
|
||||
.collect(),
|
||||
protocol::CompletionKind::Workflow => handle
|
||||
.shared_state
|
||||
.list_workflow_completions(&prefix)
|
||||
|
||||
@@ -1237,6 +1237,13 @@ impl<C: LlmClient, St: Store> Pod<C, St> {
|
||||
self.workflow_registry.list_user_invocable("")
|
||||
}
|
||||
|
||||
pub fn knowledge_completions(&self) -> Vec<String> {
|
||||
self.memory_layout
|
||||
.as_ref()
|
||||
.map(memory::list_knowledge_slugs)
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
/// Flatten a typed segment list into the single string the Worker
|
||||
/// receives as the user message, and emit user-facing alerts for
|
||||
/// segments that fall through to placeholder (knowledge / workflow
|
||||
|
||||
@@ -12,6 +12,11 @@ pub struct WorkflowCandidate {
|
||||
pub slug: String,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||
pub struct KnowledgeCandidate {
|
||||
pub slug: String,
|
||||
}
|
||||
|
||||
/// Shared state between PodController and runtime directory.
|
||||
///
|
||||
/// Controller updates this in-memory; RuntimeDir writes it to disk.
|
||||
@@ -37,6 +42,7 @@ pub struct PodSharedState {
|
||||
/// directly without spinning up a controller).
|
||||
fs_view: OnceLock<PodFsView>,
|
||||
workflows: OnceLock<Vec<WorkflowCandidate>>,
|
||||
knowledge: OnceLock<Vec<KnowledgeCandidate>>,
|
||||
}
|
||||
|
||||
impl PodSharedState {
|
||||
@@ -56,6 +62,7 @@ impl PodSharedState {
|
||||
user_segments: RwLock::new(Vec::new()),
|
||||
fs_view: OnceLock::new(),
|
||||
workflows: OnceLock::new(),
|
||||
knowledge: OnceLock::new(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -88,6 +95,23 @@ impl PodSharedState {
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
pub fn set_knowledge(&self, knowledge: Vec<KnowledgeCandidate>) {
|
||||
let _ = self.knowledge.set(knowledge);
|
||||
}
|
||||
|
||||
pub fn list_knowledge_completions(&self, prefix: &str) -> Vec<KnowledgeCandidate> {
|
||||
self.knowledge
|
||||
.get()
|
||||
.map(|items| {
|
||||
items
|
||||
.iter()
|
||||
.filter(|candidate| candidate.slug.starts_with(prefix))
|
||||
.cloned()
|
||||
.collect()
|
||||
})
|
||||
.unwrap_or_default()
|
||||
}
|
||||
|
||||
pub fn user_segments(&self) -> Vec<Vec<Segment>> {
|
||||
self.user_segments
|
||||
.read()
|
||||
@@ -230,4 +254,38 @@ mod tests {
|
||||
assert!(parsed.is_array());
|
||||
assert_eq!(parsed[0]["role"], "assistant");
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn knowledge_completions_empty_when_unset() {
|
||||
let state = test_state();
|
||||
assert!(state.list_knowledge_completions("").is_empty());
|
||||
assert!(state.list_knowledge_completions("foo").is_empty());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn knowledge_completions_filter_by_prefix() {
|
||||
let state = test_state();
|
||||
state.set_knowledge(vec![
|
||||
KnowledgeCandidate {
|
||||
slug: "alpha".into(),
|
||||
},
|
||||
KnowledgeCandidate {
|
||||
slug: "alphabet".into(),
|
||||
},
|
||||
KnowledgeCandidate {
|
||||
slug: "beta".into(),
|
||||
},
|
||||
]);
|
||||
let all = state.list_knowledge_completions("");
|
||||
assert_eq!(all.len(), 3);
|
||||
let alpha = state.list_knowledge_completions("alpha");
|
||||
assert_eq!(
|
||||
alpha
|
||||
.iter()
|
||||
.map(|c| c.slug.as_str())
|
||||
.collect::<Vec<_>>(),
|
||||
vec!["alpha", "alphabet"]
|
||||
);
|
||||
assert!(state.list_knowledge_completions("zzz").is_empty());
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user