Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion crates/openfang-api/static/js/pages/agents.js
Original file line number Diff line number Diff line change
Expand Up @@ -420,7 +420,7 @@ function agentsPage() {
lines.push('', '[model]');
lines.push('provider = "' + f.provider + '"');
lines.push('model = "' + f.model + '"');
lines.push('system_prompt = "' + f.systemPrompt.replace(/"/g, '\\"') + '"');
lines.push('system_prompt = """\n' + f.systemPrompt.replace(/\\/g, '\\\\').replace(/"""/g, '\\"\\"\\"') + '\n"""');
if (f.profile === 'custom') {
lines.push('', '[capabilities]');
if (f.caps.memory_read) lines.push('memory_read = ["*"]');
Expand Down
124 changes: 124 additions & 0 deletions crates/openfang-types/src/agent.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1169,4 +1169,128 @@ provider = "openai"
assert_eq!(cfg.model, "gpt-4o");
assert_eq!(cfg.provider, "openai");
}

// ----- Multi-line system_prompt TOML tests (wizard generateToml output) -----

#[test]
fn test_manifest_multiline_system_prompt_toml() {
// This is the exact TOML format the dashboard wizard generateToml() now produces
let toml_str = r#"
name = "brand-guardian"
module = "builtin:chat"

[model]
provider = "google"
model = "gemini-3-flash-preview"
system_prompt = """
You are Brand Guardian, an expert brand strategist.

Your Core Mission:
- Develop brand strategy including purpose, vision, mission, values
- Design complete visual identity systems
- Establish brand voice and messaging architecture

Critical Rules:
- Establish comprehensive brand foundation before tactical implementation
- Ensure all brand elements work as a cohesive system
"""
"#;
let manifest: AgentManifest = toml::from_str(toml_str).unwrap();
assert_eq!(manifest.name, "brand-guardian");
assert_eq!(manifest.model.provider, "google");
assert_eq!(manifest.model.model, "gemini-3-flash-preview");
assert!(manifest.model.system_prompt.contains("Brand Guardian"));
assert!(manifest.model.system_prompt.contains("Critical Rules:"));
// Verify newlines are preserved
assert!(manifest.model.system_prompt.contains('\n'));
}

#[test]
fn test_manifest_multiline_system_prompt_with_quotes() {
// System prompt containing double quotes (common in persona prompts)
let toml_str = r#"
name = "test-agent"

[model]
provider = "groq"
model = "llama-3.3-70b-versatile"
system_prompt = """
You are a "helpful" assistant.
When users say "hello", respond warmly.
"""
"#;
let manifest: AgentManifest = toml::from_str(toml_str).unwrap();
assert!(manifest.model.system_prompt.contains("\"helpful\""));
assert!(manifest.model.system_prompt.contains("\"hello\""));
}

#[test]
fn test_manifest_multiline_system_prompt_with_code_blocks() {
// System prompt containing markdown-style code blocks
let toml_str = r#"
name = "coder"

[model]
provider = "deepseek"
model = "deepseek-chat"
system_prompt = """
You are a coding assistant.

Example output format:
```python
def hello():
print("world")
```

Always use proper indentation.
"""
"#;
let manifest: AgentManifest = toml::from_str(toml_str).unwrap();
assert!(manifest.model.system_prompt.contains("```python"));
assert!(manifest.model.system_prompt.contains("def hello()"));
}

#[test]
fn test_manifest_single_line_system_prompt_still_works() {
// Ensure the old single-line format still parses fine
let toml_str = r#"
name = "simple"

[model]
provider = "groq"
model = "llama-3.3-70b-versatile"
system_prompt = "You are a helpful assistant."
"#;
let manifest: AgentManifest = toml::from_str(toml_str).unwrap();
assert_eq!(manifest.model.system_prompt, "You are a helpful assistant.");
}

#[test]
fn test_manifest_wizard_custom_profile_with_capabilities() {
// Full wizard output when profile=custom with capabilities block
let toml_str = r#"
name = "brand-guardian"
module = "builtin:chat"

[model]
provider = "google"
model = "gemini-3-flash-preview"
system_prompt = """
You are Brand Guardian.
Protect brand consistency across all touchpoints.
"""

[capabilities]
memory_read = ["*"]
memory_write = ["self.*"]
"#;
let manifest: AgentManifest = toml::from_str(toml_str).unwrap();
assert_eq!(manifest.name, "brand-guardian");
assert!(manifest.model.system_prompt.contains("Brand Guardian"));
assert_eq!(manifest.capabilities.memory_read, vec!["*".to_string()]);
assert_eq!(
manifest.capabilities.memory_write,
vec!["self.*".to_string()]
);
}
}