One context log per session
This commit is contained in:
@@ -254,6 +254,7 @@ pub struct Agent {
|
|||||||
providers: ProviderRegistry,
|
providers: ProviderRegistry,
|
||||||
config: Config,
|
config: Config,
|
||||||
context_window: ContextWindow,
|
context_window: ContextWindow,
|
||||||
|
session_id: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Agent {
|
impl Agent {
|
||||||
@@ -307,6 +308,7 @@ impl Agent {
|
|||||||
providers,
|
providers,
|
||||||
config,
|
config,
|
||||||
context_window,
|
context_window,
|
||||||
|
session_id: None,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -431,6 +433,11 @@ impl Agent {
|
|||||||
) -> Result<String> {
|
) -> Result<String> {
|
||||||
let _provider = self.providers.get(None)?;
|
let _provider = self.providers.get(None)?;
|
||||||
|
|
||||||
|
// Generate session ID based on the initial prompt if this is a new session
|
||||||
|
if self.session_id.is_none() {
|
||||||
|
self.session_id = Some(self.generate_session_id(description));
|
||||||
|
}
|
||||||
|
|
||||||
// Only add system message if this is the first interaction (empty conversation history)
|
// Only add system message if this is the first interaction (empty conversation history)
|
||||||
if self.context_window.conversation_history.is_empty() {
|
if self.context_window.conversation_history.is_empty() {
|
||||||
let system_prompt = "You are G3, a general-purpose AI agent. Your goal is to analyze and solve problems by writing code.
|
let system_prompt = "You are G3, a general-purpose AI agent. Your goal is to analyze and solve problems by writing code.
|
||||||
@@ -555,16 +562,47 @@ The tool will execute immediately and you'll receive the result (success or erro
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Save the entire context window to a file for debugging purposes
|
/// Generate a session ID based on the initial prompt
|
||||||
|
fn generate_session_id(&self, description: &str) -> String {
|
||||||
|
use std::collections::hash_map::DefaultHasher;
|
||||||
|
use std::hash::{Hash, Hasher};
|
||||||
|
|
||||||
|
// Clean and truncate the description for a readable filename
|
||||||
|
let clean_description = description
|
||||||
|
.chars()
|
||||||
|
.filter(|c| c.is_alphanumeric() || c.is_whitespace() || *c == '-' || *c == '_')
|
||||||
|
.collect::<String>()
|
||||||
|
.split_whitespace()
|
||||||
|
.take(5) // Take first 5 words
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join("_")
|
||||||
|
.to_lowercase();
|
||||||
|
|
||||||
|
// Create a hash for uniqueness
|
||||||
|
let mut hasher = DefaultHasher::new();
|
||||||
|
description.hash(&mut hasher);
|
||||||
|
let hash = hasher.finish();
|
||||||
|
|
||||||
|
// Format: clean_description_hash
|
||||||
|
format!("{}_{:x}", clean_description, hash)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Save the entire context window to a per-session file
|
||||||
fn save_context_window(&self, status: &str) {
|
fn save_context_window(&self, status: &str) {
|
||||||
let timestamp = std::time::SystemTime::now()
|
let timestamp = std::time::SystemTime::now()
|
||||||
.duration_since(std::time::UNIX_EPOCH)
|
.duration_since(std::time::UNIX_EPOCH)
|
||||||
.unwrap_or_default()
|
.unwrap_or_default()
|
||||||
.as_secs();
|
.as_secs();
|
||||||
|
|
||||||
let filename = format!("g3_context_{}.json", timestamp);
|
// Use session-based filename if we have a session ID, otherwise fall back to timestamp
|
||||||
|
let filename = if let Some(ref session_id) = self.session_id {
|
||||||
|
format!("g3_session_{}.json", session_id)
|
||||||
|
} else {
|
||||||
|
format!("g3_context_{}.json", timestamp)
|
||||||
|
};
|
||||||
|
|
||||||
let context_data = serde_json::json!({
|
let context_data = serde_json::json!({
|
||||||
|
"session_id": self.session_id,
|
||||||
"timestamp": timestamp,
|
"timestamp": timestamp,
|
||||||
"status": status,
|
"status": status,
|
||||||
"context_window": {
|
"context_window": {
|
||||||
|
|||||||
Reference in New Issue
Block a user