Skip to main content

hoist_core/resources/
knowledge_base.rs

1//! Knowledge Base resource definition (Agentic Search Preview)
2
3use serde::{Deserialize, Serialize};
4use serde_json::Value;
5
6use super::traits::{Resource, ResourceKind};
7
8/// Azure AI Search Knowledge Base definition (Preview API)
9#[derive(Debug, Clone, Serialize, Deserialize)]
10#[serde(rename_all = "camelCase")]
11pub struct KnowledgeBase {
12    pub name: String,
13    #[serde(skip_serializing_if = "Option::is_none")]
14    pub description: Option<String>,
15    #[serde(skip_serializing_if = "Option::is_none")]
16    pub storage_connection_string_secret: Option<String>,
17    #[serde(skip_serializing_if = "Option::is_none")]
18    pub storage_container: Option<String>,
19    #[serde(skip_serializing_if = "Option::is_none")]
20    pub identity: Option<Value>,
21    /// Catch-all for additional fields from preview API
22    #[serde(flatten)]
23    pub extra: std::collections::HashMap<String, Value>,
24}
25
26impl Resource for KnowledgeBase {
27    fn kind() -> ResourceKind {
28        ResourceKind::KnowledgeBase
29    }
30
31    fn name(&self) -> &str {
32        &self.name
33    }
34
35    fn volatile_fields() -> &'static [&'static str] {
36        &[
37            "@odata.etag",
38            "@odata.context",
39            "storageConnectionStringSecret",
40        ]
41    }
42
43    // knowledgeSources is a normal pushable field — you can add/remove knowledge sources
44    // from a KB via PUT. It is NOT read-only despite being managed in the portal UI.
45}
46
47#[cfg(test)]
48mod tests {
49    use super::*;
50
51    #[test]
52    fn test_knowledge_base_kind() {
53        assert_eq!(KnowledgeBase::kind(), ResourceKind::KnowledgeBase);
54    }
55
56    #[test]
57    fn test_knowledge_base_volatile_fields() {
58        let fields = KnowledgeBase::volatile_fields();
59        assert!(fields.contains(&"storageConnectionStringSecret"));
60        // knowledgeSources is a normal pushable field, NOT volatile
61        assert!(!fields.contains(&"knowledgeSources"));
62    }
63
64    #[test]
65    fn test_knowledge_base_knowledge_sources_is_pushable() {
66        // knowledgeSources is editable via PUT — you can add/remove KS from a KB
67        let volatile = KnowledgeBase::volatile_fields();
68        let read_only = KnowledgeBase::read_only_fields();
69        assert!(!volatile.contains(&"knowledgeSources"));
70        assert!(!read_only.contains(&"knowledgeSources"));
71    }
72
73    #[test]
74    fn test_knowledge_base_deserialize() {
75        let json = r#"{
76            "name": "my-kb",
77            "description": "test kb"
78        }"#;
79        let kb: KnowledgeBase = serde_json::from_str(json).unwrap();
80        assert_eq!(kb.name, "my-kb");
81        assert_eq!(kb.description.as_deref(), Some("test kb"));
82    }
83}