1mod dream;
2mod guidebook;
3mod introspect;
4mod mcp;
5mod reflect;
6mod sense;
7
8pub use dream::DreamTemplate;
9pub use guidebook::GuidebookTemplate;
10pub use introspect::IntrospectTemplate;
11pub use mcp::McpTemplate;
12pub use reflect::ReflectTemplate;
13pub use sense::SenseTemplate;
14
15#[cfg(test)]
16mod tests {
17 use super::*;
18 use oneiros_model::*;
19
20 fn test_agent() -> Agent {
21 Agent::init(
22 "A curious explorer agent",
23 "You explore and discover.",
24 AgentName::new("atlas"),
25 PersonaName::new("explorer"),
26 )
27 }
28
29 fn test_persona() -> Persona {
30 Persona::init(
31 PersonaName::new("explorer"),
32 "An explorer persona.",
33 "Explore with curiosity.",
34 )
35 }
36
37 #[test]
38 fn dream_template_renders_identity_and_persona() {
39 let context = DreamContext {
40 agent: test_agent(),
41 persona: test_persona(),
42 memories: vec![],
43 cognitions: vec![],
44 experiences: vec![],
45 connections: vec![],
46 textures: vec![],
47 levels: vec![],
48 sensations: vec![],
49 natures: vec![],
50 urges: vec![],
51 pressures: vec![],
52 };
53 let rendered = DreamTemplate::new(&context).to_string();
54
55 assert!(rendered.contains("You are waking as atlas."));
56 assert!(rendered.contains("## Your Identity"));
57 assert!(rendered.contains("A curious explorer agent"));
58 assert!(rendered.contains("You explore and discover."));
59 assert!(rendered.contains("## Your Persona"));
60 assert!(rendered.contains("An explorer persona."));
61 assert!(rendered.contains("## Agent Definition"));
62 assert!(rendered.contains(".claude/agents/atlas.md"));
63 assert!(rendered.contains(".agents/atlas.md"));
64 assert!(rendered.contains("## Instructions"));
65 }
66
67 #[test]
68 fn dream_template_omits_empty_sections() {
69 let context = DreamContext {
70 agent: test_agent(),
71 persona: test_persona(),
72 memories: vec![],
73 cognitions: vec![],
74 experiences: vec![],
75 connections: vec![],
76 textures: vec![],
77 levels: vec![],
78 sensations: vec![],
79 natures: vec![],
80 urges: vec![],
81 pressures: vec![],
82 };
83 let rendered = DreamTemplate::new(&context).to_string();
84
85 assert!(!rendered.contains("## Your Memories"));
86 assert!(!rendered.contains("## Your Cognitions"));
87 assert!(!rendered.contains("## Your Connections"));
88 assert!(!rendered.contains("## Cognitive Textures"));
89 assert!(!rendered.contains("## Memory Levels"));
90 }
91
92 #[test]
93 fn dream_template_renders_memories() {
94 let context = DreamContext {
95 agent: test_agent(),
96 persona: test_persona(),
97 memories: vec![Memory::create(
98 AgentId::new(),
99 LevelName::new("core"),
100 Content::new("I remember the beginning."),
101 )],
102 cognitions: vec![],
103 experiences: vec![],
104 connections: vec![],
105 textures: vec![],
106 levels: vec![],
107 sensations: vec![],
108 natures: vec![],
109 urges: vec![],
110 pressures: vec![],
111 };
112 let rendered = DreamTemplate::new(&context).to_string();
113
114 assert!(rendered.contains("## Your Memories"));
115 assert!(rendered.contains("[core] I remember the beginning."));
116 }
117
118 #[test]
119 fn dream_template_renders_cognitions() {
120 let context = DreamContext {
121 agent: test_agent(),
122 persona: test_persona(),
123 memories: vec![],
124 cognitions: vec![Cognition::create(
125 AgentId::new(),
126 TextureName::new("analytical"),
127 Content::new("Patterns emerge from repetition."),
128 )],
129 experiences: vec![],
130 connections: vec![],
131 textures: vec![],
132 levels: vec![],
133 sensations: vec![],
134 natures: vec![],
135 urges: vec![],
136 pressures: vec![],
137 };
138 let rendered = DreamTemplate::new(&context).to_string();
139
140 assert!(rendered.contains("## Your Cognitions"));
141 assert!(rendered.contains("[analytical] Patterns emerge from repetition."));
142 }
143
144 #[test]
145 fn dream_template_renders_textures_and_levels() {
146 let context = DreamContext {
147 agent: test_agent(),
148 persona: test_persona(),
149 memories: vec![],
150 cognitions: vec![],
151 experiences: vec![],
152 connections: vec![],
153 textures: vec![Texture::init(
154 TextureName::new("analytical"),
155 "Analytical thinking",
156 "Think analytically.",
157 )],
158 levels: vec![Level::init(
159 LevelName::new("core"),
160 "Core memories",
161 "Fundamental knowledge.",
162 )],
163 sensations: vec![],
164 natures: vec![],
165 urges: vec![],
166 pressures: vec![],
167 };
168 let rendered = DreamTemplate::new(&context).to_string();
169
170 assert!(rendered.contains("## Cognitive Textures"));
171 assert!(rendered.contains("analytical — Think analytically."));
172 assert!(rendered.contains("## Memory Levels"));
173 assert!(rendered.contains("core — Fundamental knowledge."));
174 }
175
176 #[test]
177 fn dream_template_references_guidebook() {
178 let context = DreamContext {
179 agent: test_agent(),
180 persona: test_persona(),
181 memories: vec![],
182 cognitions: vec![],
183 experiences: vec![],
184 connections: vec![],
185 textures: vec![],
186 levels: vec![],
187 sensations: vec![],
188 natures: vec![],
189 urges: vec![],
190 pressures: vec![],
191 };
192 let rendered = DreamTemplate::new(&context).to_string();
193
194 assert!(rendered.contains("oneiros guidebook atlas"));
195 assert!(rendered.contains("garden"));
196 }
197
198 #[test]
199 fn guidebook_template_renders_identity_and_sections() {
200 let context = DreamContext {
201 agent: test_agent(),
202 persona: test_persona(),
203 memories: vec![],
204 cognitions: vec![],
205 experiences: vec![],
206 connections: vec![],
207 textures: vec![],
208 levels: vec![],
209 sensations: vec![],
210 natures: vec![],
211 urges: vec![],
212 pressures: vec![],
213 };
214 let rendered = GuidebookTemplate::new(&context).to_string();
215
216 assert!(rendered.contains("# Cognitive Guidebook for atlas"));
217 assert!(rendered.contains("## Your Identity"));
218 assert!(rendered.contains("A curious explorer agent"));
219 assert!(rendered.contains("## Your Capabilities"));
220 assert!(rendered.contains("## Your Lifecycle"));
221 assert!(rendered.contains("## Your Agency"));
222 }
223
224 #[test]
225 fn guidebook_template_renders_cli_commands_with_agent_name() {
226 let context = DreamContext {
227 agent: test_agent(),
228 persona: test_persona(),
229 memories: vec![],
230 cognitions: vec![],
231 experiences: vec![],
232 connections: vec![],
233 textures: vec![],
234 levels: vec![],
235 sensations: vec![],
236 natures: vec![],
237 urges: vec![],
238 pressures: vec![],
239 };
240 let rendered = GuidebookTemplate::new(&context).to_string();
241
242 assert!(rendered.contains("oneiros cognition add atlas"));
243 assert!(rendered.contains("oneiros memory add atlas"));
244 assert!(rendered.contains("oneiros cognition list atlas"));
245 assert!(rendered.contains("oneiros memory list atlas"));
246 assert!(rendered.contains("oneiros wake atlas"));
247 assert!(rendered.contains("oneiros reflect atlas"));
248 assert!(rendered.contains("oneiros introspect atlas"));
249 }
250
251 #[test]
252 fn guidebook_template_renders_textures_and_levels() {
253 let context = DreamContext {
254 agent: test_agent(),
255 persona: test_persona(),
256 memories: vec![],
257 cognitions: vec![],
258 experiences: vec![],
259 connections: vec![],
260 textures: vec![Texture::init(
261 TextureName::new("analytical"),
262 "Analytical thinking",
263 "Think analytically.",
264 )],
265 levels: vec![Level::init(
266 LevelName::new("core"),
267 "Core memories",
268 "Fundamental knowledge.",
269 )],
270 sensations: vec![],
271 natures: vec![],
272 urges: vec![],
273 pressures: vec![],
274 };
275 let rendered = GuidebookTemplate::new(&context).to_string();
276
277 assert!(rendered.contains("**analytical** — Think analytically."));
278 assert!(rendered.contains("**core** — Fundamental knowledge."));
279 }
280
281 #[test]
282 fn guidebook_template_omits_empty_textures_and_levels() {
283 let context = DreamContext {
284 agent: test_agent(),
285 persona: test_persona(),
286 memories: vec![],
287 cognitions: vec![],
288 experiences: vec![],
289 connections: vec![],
290 textures: vec![],
291 levels: vec![],
292 sensations: vec![],
293 natures: vec![],
294 urges: vec![],
295 pressures: vec![],
296 };
297 let rendered = GuidebookTemplate::new(&context).to_string();
298
299 assert!(!rendered.contains("Your current textures:"));
300 assert!(!rendered.contains("Your current levels:"));
301 }
302
303 #[test]
304 fn guidebook_template_documents_agency() {
305 let context = DreamContext {
306 agent: test_agent(),
307 persona: test_persona(),
308 memories: vec![],
309 cognitions: vec![],
310 experiences: vec![],
311 connections: vec![],
312 textures: vec![],
313 levels: vec![],
314 sensations: vec![],
315 natures: vec![],
316 urges: vec![],
317 pressures: vec![],
318 };
319 let rendered = GuidebookTemplate::new(&context).to_string();
320
321 assert!(rendered.contains("oneiros texture set"));
322 assert!(rendered.contains("oneiros level set"));
323 assert!(rendered.contains("oneiros emerge"));
324 }
325
326 #[test]
327 fn introspect_template_renders_agent_name() {
328 let agent = test_agent();
329 let rendered =
330 IntrospectTemplate::new(&agent, RelevantPressures::from_pressures(vec![])).to_string();
331
332 assert!(rendered.contains("You are atlas."));
333 assert!(rendered.contains("oneiros memory add atlas"));
334 assert!(rendered.contains("oneiros cognition add atlas"));
335 assert!(rendered.contains("compact"));
336 }
337
338 #[test]
339 fn reflect_template_renders_agent_name() {
340 let agent = test_agent();
341 let rendered =
342 ReflectTemplate::new(&agent, RelevantPressures::from_pressures(vec![])).to_string();
343
344 assert!(rendered.contains("You are atlas."));
345 assert!(rendered.contains("oneiros memory add atlas"));
346 assert!(rendered.contains("oneiros cognition add atlas"));
347 assert!(rendered.contains("shifted"));
348 }
349
350 #[test]
351 fn sense_template_renders_agent_name() {
352 let agent = test_agent();
353 let rendered =
354 SenseTemplate::new(&agent, "", RelevantPressures::from_pressures(vec![])).to_string();
355
356 assert!(rendered.contains("You are atlas."));
357 assert!(rendered.contains("oneiros cognition add atlas"));
358 assert!(rendered.contains("sensing"));
359 }
360
361 #[test]
362 fn sense_template_includes_event_data_when_present() {
363 let agent = test_agent();
364 let event_json = r#"{"event": "PreCompact", "data": {}}"#;
365 let rendered = SenseTemplate::new(
366 &agent,
367 event_json,
368 RelevantPressures::from_pressures(vec![]),
369 )
370 .to_string();
371
372 assert!(rendered.contains("## What You Sensed"));
373 assert!(rendered.contains("PreCompact"));
374 }
375
376 #[test]
377 fn sense_template_omits_event_section_when_empty() {
378 let agent = test_agent();
379 let rendered =
380 SenseTemplate::new(&agent, "", RelevantPressures::from_pressures(vec![])).to_string();
381
382 assert!(!rendered.contains("## What You Sensed"));
383 }
384
385 #[test]
386 fn mcp_template_renders_url_and_token() {
387 use std::net::SocketAddr;
388 let addr: SocketAddr = "127.0.0.1:2100".parse().unwrap();
389 let rendered = McpTemplate::new(&addr, "test-token-123").to_string();
390
391 assert!(rendered.contains("http://127.0.0.1:2100/mcp"));
392 assert!(rendered.contains("Bearer test-token-123"));
393 assert!(rendered.contains("oneiros-local"));
394 let _: serde_json::Value = serde_json::from_str(&rendered).unwrap();
396 }
397}