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
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -186,3 +186,4 @@ idd-state.graphson
todo.md
*.spec.md
journal.md
.aider*
41 changes: 20 additions & 21 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -240,8 +240,7 @@ rustc-hash = "2.1.1"
bytes = "1.6"

# Memory allocator + profiling
tikv-jemallocator = { version = "0.6.0", default-features = true }
tikv-jemalloc-ctl = "0.6.0"
mimalloc = "0.1.48"
backtrace = "0.3"

# Configuration
Expand Down
11 changes: 5 additions & 6 deletions crates/codegraph-core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ clap = { workspace = true }
colored = { workspace = true }
indicatif = { workspace = true }
once_cell = { workspace = true }
tikv-jemallocator = { workspace = true }
mimalloc = { workspace = true }
hashbrown = { workspace = true }
rustc-hash = { workspace = true }
sha2 = { workspace = true }
Expand All @@ -52,10 +52,10 @@ bytes = { workspace = true }
bumpalo = "3.15"
rkyv = { workspace = true }

[target.'cfg(unix)'.dependencies]
[target.'cfg(target_family = "unix")'.dependencies]
libc = "0.2"

[target.'cfg(windows)'.dependencies]
[target.'cfg(target_family = "windows")'.dependencies]
windows-sys = { version = "0.61", features = [
"Win32_Foundation",
"Win32_System_Memory"
Expand All @@ -71,6 +71,5 @@ name = "core_micro"
harness = false

[features]
# Enable jemalloc as the global allocator and expose jemalloc controls
default = ["jemalloc"]
jemalloc = []
default = ["mimalloc"]
mimalloc = []
6 changes: 3 additions & 3 deletions crates/codegraph-core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ pub use types::*;
pub use versioning::*;
pub use watch::*;

// Use jemalloc as the global allocator when the feature is enabled
#[cfg(feature = "jemalloc")]
// Use mimalloc as the global allocator when the feature is enabled
#[cfg(feature = "mimalloc")]
#[global_allocator]
static GLOBAL: tikv_jemallocator::Jemalloc = tikv_jemallocator::Jemalloc;
static GLOBAL: mimalloc::MiMalloc = mimalloc::MiMalloc;
74 changes: 47 additions & 27 deletions crates/codegraph-mcp-autoagents/src/autoagents/agent_builder.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
// ABOUTME: Factory for creating AutoAgents with CodeGraph-specific configuration
// ABOUTME: Factory for creating AutoAgents with CodeGraph-specific configuration
// ABOUTME: Bridges codegraph_ai LLM providers to AutoAgents ChatProvider
// ABOUTME: Builder for tier-aware CodeGraph agents with graph analysis tools

use async_trait::async_trait;
#[cfg(test)]
use autoagents::llm::chat::ChatMessageBuilder;
use autoagents::llm::chat::ChatProvider;
use autoagents::llm::chat::{ChatMessage, ChatResponse, ChatRole, MessageType, Tool};
use autoagents::llm::chat::{
ChatMessage, ChatResponse, ChatRole, MessageType, StructuredOutputFormat, Tool,
};
use autoagents::llm::completion::{CompletionProvider, CompletionRequest, CompletionResponse};
use autoagents::llm::embedding::EmbeddingProvider;
use autoagents::llm::error::LLMError;
Expand Down Expand Up @@ -51,6 +53,7 @@ pub(crate) fn read_memory_window_config() -> usize {
}

use crate::autoagents::progress_notifier::ProgressCallback;
use codegraph_mcp_core::context_aware_limits::ContextTier;

/// Adapter that bridges codegraph_ai::LLMProvider to AutoAgents ChatProvider
pub struct CodeGraphChatAdapter {
Expand Down Expand Up @@ -156,20 +159,18 @@ impl CodeGraphChatAdapter {

Some(tokens)
}
}

#[async_trait]
impl ChatProvider for CodeGraphChatAdapter {
async fn chat(
/// Internal helper that does the actual chat call, with optional structured output
async fn chat_internal(
&self,
messages: &[ChatMessage],
tools: Option<&[Tool]>,
json_schema: Option<autoagents::llm::chat::StructuredOutputFormat>,
json_schema: Option<StructuredOutputFormat>,
) -> Result<Box<dyn ChatResponse>, LLMError> {
// Log tool and message info
let tool_count = tools.map_or(0, |t| t.len());
tracing::info!(
"📨 chat() called with {} messages, {} tools",
"📨 chat_internal() called with {} messages, {} tools",
messages.len(),
tool_count
);
Expand Down Expand Up @@ -347,12 +348,33 @@ impl ChatProvider for CodeGraphChatAdapter {
step_counter: Arc::new(AtomicU64::new(1)),
}))
}
}

#[async_trait]
impl ChatProvider for CodeGraphChatAdapter {
async fn chat(
&self,
messages: &[ChatMessage],
json_schema: Option<StructuredOutputFormat>,
) -> Result<Box<dyn ChatResponse>, LLMError> {
// Plain chat: no structured output schema
self.chat_internal(messages, None, json_schema).await
}

async fn chat_with_tools(
&self,
messages: &[ChatMessage],
tools: Option<&[Tool]>,
json_schema: Option<StructuredOutputFormat>,
) -> Result<Box<dyn ChatResponse>, LLMError> {
// Full-featured chat: tools + optional structured output
self.chat_internal(messages, tools, json_schema).await
}

async fn chat_stream(
&self,
_messages: &[ChatMessage],
_tools: Option<&[Tool]>,
_json_schema: Option<autoagents::llm::chat::StructuredOutputFormat>,
_json_schema: Option<StructuredOutputFormat>,
) -> Result<
std::pin::Pin<Box<dyn futures::Stream<Item = Result<String, LLMError>> + Send>>,
LLMError,
Expand All @@ -364,7 +386,7 @@ impl ChatProvider for CodeGraphChatAdapter {
&self,
_messages: &[ChatMessage],
_tools: Option<&[Tool]>,
_json_schema: Option<autoagents::llm::chat::StructuredOutputFormat>,
_json_schema: Option<StructuredOutputFormat>,
) -> Result<
std::pin::Pin<
Box<
Expand All @@ -385,7 +407,7 @@ impl CompletionProvider for CodeGraphChatAdapter {
async fn complete(
&self,
_req: &CompletionRequest,
_json_schema: Option<autoagents::llm::chat::StructuredOutputFormat>,
_json_schema: Option<StructuredOutputFormat>,
) -> Result<CompletionResponse, LLMError> {
Err(LLMError::Generic(
"Completion not supported - use ChatProvider instead".to_string(),
Expand Down Expand Up @@ -626,6 +648,12 @@ impl ChatResponse for CodeGraphChatResponse {
// Tier-Aware ReAct Agent Wrapper
// ============================================================================

use autoagents::core::agent::prebuilt::executor::ReActAgent;
use autoagents::core::agent::{
AgentDeriveT, AgentExecutor, AgentHooks, Context, DirectAgentHandle, ExecutorConfig,
};
use autoagents::core::tool::{shared_tools_to_boxes, ToolT};

/// Wrapper around ReActAgent that overrides max_turns configuration
/// This allows tier-aware max_turns without forking AutoAgents
#[derive(Debug)]
Expand All @@ -649,11 +677,11 @@ impl<T: AgentDeriveT + AgentHooks + Clone> TierAwareReActAgent<T> {
impl<T: AgentDeriveT + AgentHooks + Clone> AgentDeriveT for TierAwareReActAgent<T> {
type Output = T::Output;

fn description(&self) -> &'static str {
fn description(&self) -> &str {
self.inner_derive.description()
}

fn name(&self) -> &'static str {
fn name(&self) -> &str {
self.inner_derive.name()
}

Expand Down Expand Up @@ -717,18 +745,12 @@ use crate::autoagents::tier_plugin::TierAwarePromptPlugin;
use crate::autoagents::tools::graph_tools::*;
use crate::autoagents::tools::tool_executor_adapter::GraphToolFactory;
use codegraph_mcp_core::analysis::AnalysisType;
use codegraph_mcp_core::context_aware_limits::ContextTier;
use codegraph_mcp_tools::GraphToolExecutor;

use crate::autoagents::codegraph_agent::CodeGraphAgentOutput;
use autoagents::core::agent::memory::SlidingWindowMemory;
use autoagents::core::agent::prebuilt::executor::ReActAgent;
use autoagents::core::agent::AgentBuilder;
use autoagents::core::agent::{
AgentDeriveT, AgentExecutor, AgentHooks, Context, DirectAgentHandle, ExecutorConfig,
};
use autoagents::core::error::Error as AutoAgentsError;
use autoagents::core::tool::{shared_tools_to_boxes, ToolT};

/// Agent implementation for CodeGraph with manual tool registration
#[derive(Debug, Clone)]
Expand All @@ -743,13 +765,11 @@ pub struct CodeGraphReActAgent {
impl AgentDeriveT for CodeGraphReActAgent {
type Output = CodeGraphAgentOutput;

fn description(&self) -> &'static str {
// Use Box::leak to convert runtime String to &'static str
// This is the standard AutoAgents pattern for dynamic descriptions
Box::leak(self.system_prompt.clone().into_boxed_str())
fn description(&self) -> &str {
&self.system_prompt
}

fn name(&self) -> &'static str {
fn name(&self) -> &str {
"codegraph_agent"
}

Expand Down Expand Up @@ -842,7 +862,7 @@ impl CodeGraphAgentBuilder {
// Get executor adapter for tool construction
let executor_adapter = self.tool_factory.adapter();

// Manually construct all 6 tools with the executor (Arc-wrapped for sharing)
// Manually construct all tools with the executor (Arc-wrapped for sharing)
let tools: Vec<Arc<dyn ToolT>> = vec![
Arc::new(SemanticCodeSearch::new(executor_adapter.clone())),
Arc::new(GetTransitiveDependencies::new(executor_adapter.clone())),
Expand Down Expand Up @@ -1110,7 +1130,7 @@ mod tests {
let adapter = CodeGraphChatAdapter::new(mock_llm, ContextTier::Medium);

let messages = vec![ChatMessage::user().content("Hello").build()];
let response = adapter.chat(&messages, None, None).await.unwrap();
let response = adapter.chat(&messages, None).await.unwrap();

assert_eq!(response.text(), Some("Echo: Hello".to_string()));
}
Expand Down
Loading