Skip to content

Commit ec2afe9

Browse files
committed
add mofa framework usage standards to claude rules
1 parent 74379c3 commit ec2afe9

1 file changed

Lines changed: 298 additions & 0 deletions

File tree

.claude/mofa-framework-usage.md

Lines changed: 298 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,298 @@
1+
# MoFA Framework Integration Standards
2+
3+
This codebase uses the **MoFA framework** (`mofa-sdk` crate) as the foundation for LLM interactions, agent management, and tool execution. All new code should integrate with MoFA components to ensure standardization and reusability.
4+
5+
## Core MoFA Components
6+
7+
### 1. LLM Provider Setup
8+
9+
**Always use MoFA's provider abstractions:**
10+
11+
```rust
12+
use mofa_sdk::llm::openai::{OpenAIConfig, OpenAIProvider};
13+
use std::sync::Arc;
14+
15+
// Create provider using MoFA's standardized config
16+
let openai_config = OpenAIConfig::new(&api_key)
17+
.with_model(&model)
18+
.with_base_url(api_base); // Works with OpenRouter, vLLM, etc.
19+
let provider = Arc::new(OpenAIProvider::with_config(openai_config));
20+
```
21+
22+
**Do NOT:**
23+
- Create custom HTTP clients for LLM calls
24+
- Use provider-specific APIs directly
25+
- Bypass MoFA's provider abstraction
26+
27+
### 2. Agent Creation
28+
29+
**Always use `LLMAgentBuilder` for agent creation:**
30+
31+
```rust
32+
use mofa_sdk::llm::LLMAgentBuilder;
33+
use std::sync::Arc;
34+
35+
// Build system prompt first
36+
let system_prompt = context.build_system_prompt(None).await?;
37+
38+
// Create LLMAgent with tools and executor
39+
let llm_agent = Arc::new(
40+
LLMAgentBuilder::new()
41+
.with_id("agent-id")
42+
.with_name("Agent Name")
43+
.with_provider(provider.clone())
44+
.with_system_prompt(system_prompt)
45+
.with_tool_executor(tool_executor) // Use ToolRegistryExecutor
46+
.build_async()
47+
.await,
48+
);
49+
```
50+
51+
**Pattern:**
52+
- Use `LLMAgentBuilder` builder pattern
53+
- Always provide `with_id`, `with_name`, `with_provider`, `with_system_prompt`
54+
- Use `ToolRegistryExecutor` to bridge mofaclaw tools with MoFA agents
55+
- Use `build_async()` for async construction
56+
57+
### 3. Tool Integration
58+
59+
**Bridge mofaclaw tools with MoFA using `ToolRegistryExecutor`:**
60+
61+
```rust
62+
use mofaclaw_core::tools::{ToolRegistry, ToolRegistryExecutor};
63+
use std::sync::Arc;
64+
use tokio::sync::RwLock;
65+
66+
// Create tool registry
67+
let tools = Arc::new(RwLock::new(ToolRegistry::new()));
68+
69+
// Register tools
70+
let mut tools_guard = tools.write().await;
71+
AgentLoop::register_default_tools(&mut tools_guard, &workspace, brave_api_key, bus.clone());
72+
drop(tools_guard);
73+
74+
// Create executor for MoFA
75+
let tool_executor = Arc::new(ToolRegistryExecutor::new(tools.clone()));
76+
```
77+
78+
**Pattern:**
79+
- Use `ToolRegistry` for tool management
80+
- Use `ToolRegistryExecutor` to make tools available to MoFA agents
81+
- Register tools before creating the agent
82+
83+
### 4. Agent Loop Integration
84+
85+
**Use `AgentLoop::with_agent_and_tools` for full integration:**
86+
87+
```rust
88+
use mofaclaw_core::AgentLoop;
89+
90+
let agent = Arc::new(
91+
AgentLoop::with_agent_and_tools(
92+
&config,
93+
llm_agent, // From LLMAgentBuilder
94+
provider, // MoFA provider
95+
bus.clone(),
96+
sessions.clone(),
97+
tools.clone(), // ToolRegistry
98+
)
99+
.await?,
100+
);
101+
```
102+
103+
**For custom configurations (role-based agents):**
104+
105+
```rust
106+
let agent = Arc::new(
107+
AgentLoop::with_agent_and_tools_custom(
108+
&config,
109+
llm_agent,
110+
provider,
111+
bus.clone(),
112+
sessions.clone(),
113+
tools.clone(),
114+
max_iterations_override, // Optional: role-specific limits
115+
temperature_override, // Optional: role-specific temperature
116+
)
117+
.await?,
118+
);
119+
```
120+
121+
### 5. Task Orchestration (Subagents)
122+
123+
**Use MoFA's `TaskOrchestrator` for parallel task execution:**
124+
125+
```rust
126+
use mofa_sdk::llm::task_orchestrator::{TaskOrchestrator, TaskOrigin};
127+
128+
// TaskOrchestrator is created internally by AgentLoop
129+
// Access via agent's task_orchestrator field when needed
130+
```
131+
132+
**Pattern:**
133+
- `TaskOrchestrator` is automatically created in `AgentLoop`
134+
- Use for spawning subagents and parallel task execution
135+
- Follow MoFA's task origin patterns
136+
137+
### 6. Skills Management
138+
139+
**Use MoFA's `SkillsManager` when working with skills:**
140+
141+
```rust
142+
use mofa_sdk::skills::SkillsManager;
143+
144+
// SkillsManager handles skill loading and execution
145+
// Skills are defined in workspace/skills/ or bundled in skills/
146+
```
147+
148+
## Standard Patterns
149+
150+
### Complete Agent Setup Pattern
151+
152+
```rust
153+
// 1. Load config
154+
let config = load_config().await?;
155+
156+
// 2. Create MoFA provider
157+
let openai_config = OpenAIConfig::new(&api_key)
158+
.with_model(&model)
159+
.with_base_url(api_base);
160+
let provider = Arc::new(OpenAIProvider::with_config(openai_config));
161+
162+
// 3. Create infrastructure
163+
let bus = MessageBus::new();
164+
let sessions = Arc::new(SessionManager::new(&config));
165+
let tools = Arc::new(RwLock::new(ToolRegistry::new()));
166+
167+
// 4. Register tools
168+
{
169+
let mut tools_guard = tools.write().await;
170+
AgentLoop::register_default_tools(&mut tools_guard, &workspace, brave_api_key, bus.clone());
171+
}
172+
173+
// 5. Create tool executor
174+
let tool_executor = Arc::new(ToolRegistryExecutor::new(tools.clone()));
175+
176+
// 6. Build system prompt
177+
let context = ContextBuilder::new(&config);
178+
let system_prompt = context.build_system_prompt(None).await?;
179+
180+
// 7. Create LLMAgent using MoFA
181+
let llm_agent = Arc::new(
182+
LLMAgentBuilder::new()
183+
.with_id("agent-id")
184+
.with_name("Agent Name")
185+
.with_provider(provider.clone())
186+
.with_system_prompt(system_prompt)
187+
.with_tool_executor(tool_executor)
188+
.build_async()
189+
.await,
190+
);
191+
192+
// 8. Create AgentLoop
193+
let agent = Arc::new(
194+
AgentLoop::with_agent_and_tools(
195+
&config,
196+
llm_agent,
197+
provider,
198+
bus.clone(),
199+
sessions.clone(),
200+
tools.clone(),
201+
)
202+
.await?,
203+
);
204+
```
205+
206+
## Import Standards
207+
208+
**Always import MoFA components from `mofa_sdk`:**
209+
210+
```rust
211+
// LLM components
212+
use mofa_sdk::llm::{
213+
LLMAgent, LLMAgentBuilder, LLMProvider,
214+
openai::{OpenAIConfig, OpenAIProvider},
215+
task_orchestrator::{TaskOrchestrator, TaskOrigin},
216+
};
217+
218+
// Skills
219+
use mofa_sdk::skills::SkillsManager;
220+
221+
// Re-exported types (use from mofaclaw_core when available)
222+
use mofaclaw_core::provider::{OpenAIConfig, OpenAIProvider}; // Re-exported
223+
```
224+
225+
## Benefits of Standardization
226+
227+
1. **Reusability**: Code using MoFA components can be reused across different projects
228+
2. **Consistency**: All agents follow the same patterns and interfaces
229+
3. **Maintainability**: Changes to MoFA framework propagate automatically
230+
4. **Interoperability**: Agents can work together seamlessly
231+
5. **Future-proofing**: New MoFA features become available automatically
232+
233+
## Anti-Patterns to Avoid
234+
235+
**Don't create custom LLM clients:**
236+
```rust
237+
// BAD
238+
let client = reqwest::Client::new();
239+
let response = client.post("https://api.openai.com/v1/chat/completions")...
240+
```
241+
242+
**Use MoFA providers:**
243+
```rust
244+
// GOOD
245+
let provider = Arc::new(OpenAIProvider::with_config(openai_config));
246+
```
247+
248+
**Don't bypass AgentLoop:**
249+
```rust
250+
// BAD
251+
let response = llm_agent.call_llm_directly(...);
252+
```
253+
254+
**Use AgentLoop for message processing:**
255+
```rust
256+
// GOOD
257+
let response = agent.process_direct(&message, &session).await?;
258+
```
259+
260+
**Don't create custom tool execution:**
261+
```rust
262+
// BAD
263+
match tool_name {
264+
"read_file" => read_file_manually(...),
265+
...
266+
}
267+
```
268+
269+
**Use ToolRegistry and ToolRegistryExecutor:**
270+
```rust
271+
// GOOD
272+
let tool_executor = Arc::new(ToolRegistryExecutor::new(tools.clone()));
273+
```
274+
275+
## Multi-Agent Collaboration
276+
277+
When creating multi-agent systems:
278+
279+
1. **Each agent should use MoFA components:**
280+
- Create agents using `LLMAgentBuilder`
281+
- Use `AgentLoop::with_agent_and_tools` or `with_agent_and_tools_custom`
282+
- Share `ToolRegistry` instances when appropriate
283+
284+
2. **Standardize agent creation:**
285+
- Use consistent patterns for all agents in a team
286+
- Apply role-specific overrides via `with_agent_and_tools_custom`
287+
- Ensure all agents use the same provider configuration
288+
289+
3. **Tool sharing:**
290+
- Share `ToolRegistry` across agents when they need the same tools
291+
- Use `ToolRegistryExecutor` for each agent's tool execution
292+
293+
## References
294+
295+
- MoFA SDK: `mofa-sdk` crate (version 0.1.0)
296+
- Core integration: `core/src/agent/loop_.rs`
297+
- Provider abstraction: `core/src/provider/mod.rs`
298+
- Example usage: `cli/src/main.rs` (see `command_gateway` and `command_agent`)

0 commit comments

Comments
 (0)