Returns pairs of user and assistant messages to include as context in the message history including both summaries and context files if available, and the dropped context files. TODO: - Either add support for multiple context messages if the context is too large to fit inside a single user message, or handle this case more gracefully. For now, always return 2 messages. - Cache this return for som
(
&mut self,
os: &Os,
additional_context: Option<String>,
)
| 802 | /// messages. |
| 803 | /// - Cache this return for some period of time. |
| 804 | async fn context_messages( |
| 805 | &mut self, |
| 806 | os: &Os, |
| 807 | additional_context: Option<String>, |
| 808 | ) -> (Option<Vec<HistoryEntry>>, Vec<(String, String)>) { |
| 809 | let mut context_content = String::new(); |
| 810 | let mut dropped_context_files = Vec::new(); |
| 811 | if let Some((summary, _)) = &self.latest_summary { |
| 812 | context_content.push_str(CONTEXT_ENTRY_START_HEADER); |
| 813 | context_content.push_str("This summary contains ALL relevant information from our previous conversation including tool uses, results, code analysis, and file operations. YOU MUST reference this information when answering questions and explicitly acknowledge specific details from the summary when they're relevant to the current question.\n\n"); |
| 814 | context_content.push_str("SUMMARY CONTENT:\n"); |
| 815 | context_content.push_str(summary); |
| 816 | context_content.push('\n'); |
| 817 | context_content.push_str(CONTEXT_ENTRY_END_HEADER); |
| 818 | } |
| 819 | |
| 820 | // Add context files if available |
| 821 | if let Some(context_manager) = self.context_manager.as_mut() { |
| 822 | match context_manager.collect_context_files_with_limit(os).await { |
| 823 | Ok((files_to_use, files_dropped)) => { |
| 824 | if !files_dropped.is_empty() { |
| 825 | dropped_context_files.extend(files_dropped); |
| 826 | } |
| 827 | |
| 828 | if !files_to_use.is_empty() { |
| 829 | context_content.push_str(CONTEXT_ENTRY_START_HEADER); |
| 830 | for (filename, content) in files_to_use { |
| 831 | context_content.push_str(&format!("[{}]\n{}\n", filename, content)); |
| 832 | } |
| 833 | context_content.push_str(CONTEXT_ENTRY_END_HEADER); |
| 834 | } |
| 835 | }, |
| 836 | Err(e) => { |
| 837 | warn!("Failed to get context files: {}", e); |
| 838 | }, |
| 839 | } |
| 840 | } |
| 841 | |
| 842 | if let Some(context) = additional_context { |
| 843 | context_content.push_str(&context); |
| 844 | } |
| 845 | |
| 846 | if let Some(agent_prompt) = self.agents.get_active().and_then(|a| a.prompt.as_ref()) { |
| 847 | context_content.push_str(&format!("Follow this instruction: {}", agent_prompt)); |
| 848 | } |
| 849 | |
| 850 | if !context_content.is_empty() { |
| 851 | self.context_message_length = Some(context_content.len()); |
| 852 | let user = UserMessage::new_prompt(context_content, None); |
| 853 | let assistant = AssistantMessage::new_response(None, "I will fully incorporate this information when generating my responses, and explicitly acknowledge relevant parts of the summary when answering questions.".into()); |
| 854 | ( |
| 855 | Some(vec![HistoryEntry { |
| 856 | user, |
| 857 | assistant, |
| 858 | request_metadata: None, |
| 859 | }]), |
| 860 | dropped_context_files, |
| 861 | ) |
no test coverage detected