perf(agent): rombak alur AI agent — adaptif, hemat token, self-healing

Ganti explore phase MANDATORY (3 subagent tiap turn, boros) dengan
tool explore_codebase yang DIPUTUSKAN agent sendiri (lazy, token-aware):
- hapus ExploreService trait + with_explore + Phase 0 dari turn loop
- ExploreServiceImpl kini jadi tool 'explore_codebase' (1 context-scout
  subagent, read-only, cap output 4k chars)
- system prompt: instruksi TOKEN BUDGET (jawab langsung utk query simple,
  panggil explore_codebase sekali utk task kompleks)

Loop utama kini adaptif & self-healing:
- max_tokens adaptif (800/1600/4096 by request length) — bukan selalu 4096
- temperature 0.2 saat tool-calling, 0.7 utk final answer
- ErrorTracker: deteksi tool error berulang → inject recovery note,
  stop setelah 8 error total (bukan 50 iterasi sia-sia)
- auto-compact history > 60k chars sebelum LLM call
- tool output di-truncate ke 12k chars sebelum masuk konteks

Tambah 8 unit test (truncation, adaptive tokens, error tracker).
This commit is contained in:
asepharyana
2026-08-27 23:06:37 +07:00
parent 14f3eae62a
commit eac0443c4c
9 changed files with 422 additions and 448 deletions
+1 -25
View File
@@ -110,13 +110,6 @@ pub fn spawn_agent_turn(state: &mut AppStateRest, text: String) {
api_base: api_base.clone(),
};
// Clone credentials before moving into LlmClient.
let explore_api_key = api_key.clone();
let explore_model = model.clone();
let explore_base_url = api_base
.clone()
.unwrap_or_else(|| "https://api.openai.com/v1".to_string());
let client = std::sync::Arc::new(LlmClient::new(api_key, model, api_base));
let tool_ctx = ToolCtx::builder()
@@ -125,29 +118,12 @@ pub fn spawn_agent_turn(state: &mut AppStateRest, text: String) {
.turn_events(turn_events)
.build();
// Clone ToolCtx for the explore service (before moving into executor).
let explore_ctx = tool_ctx.clone();
let tool_executor = std::sync::Arc::new(InfrastructureToolExecutor::new(tool_ctx));
let tools = all_tools();
let defs = tool_defs(&tools);
// Wire the mandatory explore phase (3+ parallel subagents).
let explore_creds = zesdex_infrastructure::best_practice::explore::Credentials {
base_url: explore_base_url,
api_key: explore_api_key,
model: explore_model,
};
let explore_service = std::sync::Arc::new(
zesdex_infrastructure::best_practice::explore::ExploreServiceImpl::new(
explore_ctx,
explore_creds,
),
);
let turn_service =
AgentTurnServiceImpl::new(client, tool_executor, defs).with_explore(explore_service);
let turn_service = AgentTurnServiceImpl::new(client, tool_executor, defs);
tokio::spawn(async move {
let _ = turn_service.run_turn(params).await;