Skip to content

Commit 1f0185e

Browse files
author
kiran-garre
committed
Merge branch 'main' of github.com:aws/amazon-q-developer-cli into kiran-garre/todo-list-usage
2 parents dcc8e52 + 5eb5d55 commit 1f0185e

File tree

6 files changed

+81
-12
lines changed

6 files changed

+81
-12
lines changed

crates/chat-cli/src/cli/chat/cli/profile.rs

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -96,20 +96,31 @@ pub enum AgentSubcommand {
9696
Swap { name: Option<String> },
9797
}
9898

99-
fn prompt_mcp_server_selection(servers: &[McpServerInfo]) -> eyre::Result<Vec<&McpServerInfo>> {
99+
fn prompt_mcp_server_selection(servers: &[McpServerInfo]) -> eyre::Result<Option<Vec<&McpServerInfo>>> {
100100
let items: Vec<String> = servers
101101
.iter()
102102
.map(|server| format!("{} ({})", server.name, server.config.command))
103103
.collect();
104104

105-
let selections = MultiSelect::new()
105+
let selections = match MultiSelect::new()
106106
.with_prompt("Select MCP servers (use Space to toggle, Enter to confirm)")
107107
.items(&items)
108-
.interact()?;
109-
110-
let selected_servers: Vec<&McpServerInfo> = selections.iter().filter_map(|&i| servers.get(i)).collect();
108+
.interact_on_opt(&dialoguer::console::Term::stdout())
109+
{
110+
Ok(sel) => sel,
111+
Err(dialoguer::Error::IO(ref e)) if e.kind() == std::io::ErrorKind::Interrupted => {
112+
return Ok(None);
113+
},
114+
Err(e) => return Err(eyre::eyre!("Failed to get MCP server selection: {e}")),
115+
};
116+
117+
let selected_servers: Vec<&McpServerInfo> = selections
118+
.unwrap_or_default()
119+
.iter()
120+
.filter_map(|&i| servers.get(i))
121+
.collect();
111122

112-
Ok(selected_servers)
123+
Ok(Some(selected_servers))
113124
}
114125

115126
impl AgentSubcommand {
@@ -280,7 +291,12 @@ impl AgentSubcommand {
280291
let selected_servers = if mcp_servers.is_empty() {
281292
Vec::new()
282293
} else {
283-
prompt_mcp_server_selection(&mcp_servers).map_err(|e| ChatError::Custom(e.to_string().into()))?
294+
match prompt_mcp_server_selection(&mcp_servers)
295+
.map_err(|e| ChatError::Custom(e.to_string().into()))?
296+
{
297+
Some(servers) => servers,
298+
None => return Ok(ChatState::default()),
299+
}
284300
};
285301

286302
let mcp_servers_json = if !selected_servers.is_empty() {

crates/chat-cli/src/cli/chat/conversation.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -665,6 +665,7 @@ IMPORTANT: Return ONLY raw JSON with NO markdown formatting, NO code blocks, NO
665665
Your task is to generate an agent configuration file for an agent named '{}' with the following description: {}\n\n\
666666
The configuration must conform to this JSON schema:\n{}\n\n\
667667
We have a prepopulated template: {} \n\n\
668+
Please change the useLegacyMcpJson field to false.
668669
Please generate the prompt field using user provided description, and fill in the MCP tools that user has selected {}.
669670
Return only the JSON configuration, no additional text.",
670671
agent_name, agent_description, schema, prepopulated_content, selected_servers

crates/chat-cli/src/cli/chat/line_tracker.rs

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ pub struct FileLineTracker {
1313
pub before_fswrite_lines: usize,
1414
/// Line count after `fs_write` executes
1515
pub after_fswrite_lines: usize,
16+
/// Lines added by agent in the current operation
17+
pub lines_added_by_agent: usize,
18+
/// Lines removed by agent in the current operation
19+
pub lines_removed_by_agent: usize,
1620
/// Whether or not this is the first `fs_write` invocation
1721
pub is_first_write: bool,
1822
}
@@ -23,6 +27,8 @@ impl Default for FileLineTracker {
2327
prev_fswrite_lines: 0,
2428
before_fswrite_lines: 0,
2529
after_fswrite_lines: 0,
30+
lines_added_by_agent: 0,
31+
lines_removed_by_agent: 0,
2632
is_first_write: true,
2733
}
2834
}
@@ -34,7 +40,6 @@ impl FileLineTracker {
3440
}
3541

3642
pub fn lines_by_agent(&self) -> isize {
37-
let lines = (self.after_fswrite_lines as isize) - (self.before_fswrite_lines as isize);
38-
lines.abs()
43+
(self.lines_added_by_agent + self.lines_removed_by_agent) as isize
3944
}
4045
}

crates/chat-cli/src/cli/chat/prompt.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,7 @@ pub const COMMANDS: &[&str] = &[
6767
"/agent rename",
6868
"/agent set",
6969
"/agent schema",
70+
"/agent generate",
7071
"/prompts",
7172
"/context",
7273
"/context help",

crates/chat-cli/src/cli/chat/tools/fs_write.rs

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,11 +247,57 @@ impl FsWrite {
247247

248248
let tracker = line_tracker.entry(path.to_string_lossy().to_string()).or_default();
249249
tracker.after_fswrite_lines = after_lines;
250+
251+
// Calculate actual lines added and removed by analyzing the diff
252+
let (lines_added, lines_removed) = self.calculate_diff_lines(os).await?;
253+
tracker.lines_added_by_agent = lines_added;
254+
tracker.lines_removed_by_agent = lines_removed;
255+
250256
tracker.is_first_write = false;
251257

252258
Ok(())
253259
}
254260

261+
async fn calculate_diff_lines(&self, os: &Os) -> Result<(usize, usize)> {
262+
let path = self.path(os);
263+
264+
let result = match self {
265+
FsWrite::Create { .. } => {
266+
// For create operations, all lines in the new file are added
267+
let new_content = os.fs.read_to_string(&path).await?;
268+
let lines_added = new_content.lines().count();
269+
(lines_added, 0)
270+
},
271+
FsWrite::StrReplace { old_str, new_str, .. } => {
272+
// Use actual diff analysis for accurate line counting
273+
let diff = similar::TextDiff::from_lines(old_str, new_str);
274+
let mut lines_added = 0;
275+
let mut lines_removed = 0;
276+
277+
for change in diff.iter_all_changes() {
278+
match change.tag() {
279+
similar::ChangeTag::Insert => lines_added += 1,
280+
similar::ChangeTag::Delete => lines_removed += 1,
281+
similar::ChangeTag::Equal => {},
282+
}
283+
}
284+
(lines_added, lines_removed)
285+
},
286+
FsWrite::Insert { new_str, .. } => {
287+
// For insert operations, all lines in new_str are added
288+
let lines_added = new_str.lines().count();
289+
(lines_added, 0)
290+
},
291+
FsWrite::Append { new_str, .. } => {
292+
// For append operations, all lines in new_str are added
293+
let lines_added = new_str.lines().count();
294+
(lines_added, 0)
295+
},
296+
};
297+
298+
Ok(result)
299+
}
300+
255301
pub fn queue_description(&self, os: &Os, output: &mut impl Write) -> Result<()> {
256302
let cwd = os.env.current_dir()?;
257303
self.print_relative_path(os, output)?;

docs/knowledge-management.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -177,7 +177,7 @@ Each agent maintains its own isolated knowledge base, ensuring that knowledge co
177177
Knowledge bases are stored in the following directory structure:
178178

179179
```
180-
~/.q/knowledge_bases/
180+
~/.aws/amazonq/knowledge_bases/
181181
├── q_cli_default/ # Default agent knowledge base
182182
│ ├── contexts.json # Metadata for all contexts
183183
│ ├── context-id-1/ # Individual context storage
@@ -186,13 +186,13 @@ Knowledge bases are stored in the following directory structure:
186186
│ └── context-id-2/
187187
│ ├── data.json
188188
│ └── bm25_data.json
189-
├── my-custom-agent/ # Custom agent knowledge base
189+
├── my-custom-agent_<alphanumeric-code>/ # Custom agent knowledge base
190190
│ ├── contexts.json
191191
│ ├── context-id-3/
192192
│ │ └── data.json
193193
│ └── context-id-4/
194194
│ └── data.json
195-
└── another-agent/ # Another agent's knowledge base
195+
└── another-agent_<alphanumeric-code>/ # Another agent's knowledge base
196196
├── contexts.json
197197
└── context-id-5/
198198
└── data.json

0 commit comments

Comments
 (0)