Skip to content

Commit 50f8b65

Browse files
committed
fix(cli): preserve dotted agent references
1 parent 7954d02 commit 50f8b65

2 files changed

Lines changed: 60 additions & 4 deletions

File tree

src/cortex-cli/src/export_cmd.rs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@ use cortex_engine::rollout::get_rollout_path;
1212
use cortex_engine::rollout::reader::{RolloutItem, get_session_meta, read_rollout};
1313
use cortex_protocol::{ConversationId, EventMsg};
1414

15+
pub(crate) const AGENT_MENTION_REGEX: &str = r"@([a-zA-Z][a-zA-Z0-9_-]*(?:\.[a-zA-Z0-9_-]+)*)";
16+
1517
/// Export format for sessions.
1618
#[derive(Debug, Clone, Copy, Default, PartialEq, Eq, clap::ValueEnum)]
1719
pub enum ExportFormat {
@@ -358,8 +360,8 @@ fn extract_messages(
358360
fn extract_agent_refs(messages: &[ExportMessage]) -> Vec<String> {
359361
use std::collections::HashSet;
360362

361-
// Regex to match @agent mentions (e.g., @explore, @general, @my-custom-agent)
362-
let re = regex::Regex::new(r"@([a-zA-Z][a-zA-Z0-9_-]*)").unwrap();
363+
// Regex to match @agent mentions (e.g., @explore, @my-custom-agent, @acme.deploy)
364+
let re = regex::Regex::new(AGENT_MENTION_REGEX).unwrap();
363365

364366
let mut agent_refs: HashSet<String> = HashSet::new();
365367

@@ -443,6 +445,28 @@ mod tests {
443445
assert!(refs.contains(&"my-agent".to_string()));
444446
}
445447

448+
#[test]
449+
fn test_extract_agent_refs_with_dotted_names() {
450+
let messages = vec![ExportMessage {
451+
role: "user".to_string(),
452+
content: "Run @acme.deploy, then @foo.bar. Keep @my-agent too.".to_string(),
453+
tool_calls: None,
454+
tool_call_id: None,
455+
timestamp: None,
456+
}];
457+
458+
let refs = extract_agent_refs(&messages);
459+
assert_eq!(
460+
refs,
461+
vec![
462+
"acme.deploy".to_string(),
463+
"foo.bar".to_string(),
464+
"my-agent".to_string()
465+
]
466+
);
467+
assert!(!refs.contains(&"acme".to_string()));
468+
}
469+
446470
#[test]
447471
fn test_extract_agent_refs_no_duplicates() {
448472
let messages = vec![

src/cortex-cli/src/import_cmd.rs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use cortex_protocol::{
1616
};
1717

1818
use crate::agent_cmd::load_all_agents;
19-
use crate::export_cmd::{ExportMessage, SessionExport};
19+
use crate::export_cmd::{AGENT_MENTION_REGEX, ExportMessage, SessionExport};
2020

2121
/// Maximum depth for processing messages to prevent stack overflow from deeply nested structures.
2222
const MAX_PROCESSING_DEPTH: usize = 10000;
@@ -289,7 +289,7 @@ fn validate_agent_references(export: &SessionExport) -> Result<Vec<String>> {
289289
}
290290

291291
// Also scan messages for @agent mentions (in case they weren't pre-extracted)
292-
let re = regex::Regex::new(r"@([a-zA-Z][a-zA-Z0-9_-]*)").unwrap();
292+
let re = regex::Regex::new(AGENT_MENTION_REGEX).unwrap();
293293
for message in &export.messages {
294294
for cap in re.captures_iter(&message.content) {
295295
if let Some(agent_name) = cap.get(1) {
@@ -650,6 +650,38 @@ mod tests {
650650
assert!(missing.contains(&"yet-another-missing".to_string()));
651651
}
652652

653+
#[test]
654+
fn test_validate_agent_references_with_dotted_missing_agent() {
655+
use crate::export_cmd::SessionMetadata;
656+
657+
let export = SessionExport {
658+
version: 1,
659+
session: SessionMetadata {
660+
id: "test-123".to_string(),
661+
title: None,
662+
created_at: "2024-01-01T00:00:00Z".to_string(),
663+
cwd: None,
664+
model: None,
665+
agent: None,
666+
agent_refs: None,
667+
},
668+
messages: vec![ExportMessage {
669+
role: "user".to_string(),
670+
content: "Please run @acme.deploy for me, then @foo.bar.".to_string(),
671+
tool_calls: None,
672+
tool_call_id: None,
673+
timestamp: None,
674+
}],
675+
};
676+
677+
let missing = validate_agent_references(&export).unwrap();
678+
679+
assert!(missing.contains(&"acme.deploy".to_string()));
680+
assert!(missing.contains(&"foo.bar".to_string()));
681+
assert!(!missing.contains(&"acme".to_string()));
682+
assert!(!missing.contains(&"foo".to_string()));
683+
}
684+
653685
#[test]
654686
fn test_validate_agent_references_with_builtin_agents() {
655687
use crate::export_cmd::SessionMetadata;

0 commit comments

Comments
 (0)