Skip to content

Refactor agent loop and AI initialization for better lifecycle management#7

Open
hua-bang wants to merge 1 commit intomasterfrom
claude/enhance-agent-skills-Mv9qt
Open

Refactor agent loop and AI initialization for better lifecycle management#7
hua-bang wants to merge 1 commit intomasterfrom
claude/enhance-agent-skills-Mv9qt

Conversation

@hua-bang
Copy link
Copy Markdown
Owner

@hua-bang hua-bang commented Feb 8, 2026

Summary

This PR refactors the agent loop architecture and AI initialization to improve lifecycle management, add comprehensive instrumentation hooks, and simplify the tool execution flow. The main changes include:

  • Lazy AI initialization: Moved from static tool setup to explicit initializeAI() call after skill registry is ready
  • Structured loop results: Replaced string returns with LoopResult objects containing turn-by-turn telemetry
  • Lifecycle hooks: Added comprehensive LoopHooks for observability (turn start/end, tool execution, text generation, errors)
  • Removed unnecessary LLM calls: Eliminated the checkLoopFinish() function that made an extra LLM call every turn; now uses standard ReAct pattern (no tool calls = done)
  • Improved CLI UX: Added slash command support for direct skill invocation (/skill-name), skill listing (/skills), and better formatted output with timing/metrics

Key Changes

AI & Loop Architecture

  • ai.ts: Removed static BuiltinToolsMap initialization; added initializeAI(tools) function that must be called after skill registry setup
  • loop.ts: Complete rewrite with structured LoopResult return type, LoopHooks for lifecycle events, and removal of the extra checkLoopFinish() LLM call
  • core.ts: Updated initialization sequence: registry → build tools → initialize AI; added slash command parsing and skill invocation
  • Removed generateObject() function (was unused and relied on tool-calling for structured output)

Tools & Skills

  • tools/index.ts: Introduced buildTools() factory function; separated static tools from dynamic skill tool
  • tools/skill.ts: Changed from static export to createSkillTool() factory; now reads from initialized registry with fuzzy search fallback
  • prompt/system.ts: Added buildSkillsSection() to dynamically include loaded skills in system prompt

Type System

  • typings/index.ts: Added LoopResult, TurnInfo, ToolCallInfo, LoopHooks, and LoopOptions interfaces for better type safety and observability
  • Added abortSignal to Context for external loop cancellation

CLI Improvements

  • Slash command support: /skill-name [args] invokes skills directly
  • /skills command lists all loaded skills
  • Better output formatting with turn count, tool call count, duration, and finish reason
  • Per-turn and per-tool lifecycle hooks for detailed logging

Implementation Details

  • The loop now follows the standard ReAct pattern: if the model returns text without tool calls, the task is complete
  • Tool execution is sequential with hooks fired before/after each call for observability
  • Error handling tracks consecutive errors and stops after MAX_ERROR_COUNT
  • All timing is captured at turn and tool granularity for performance analysis
  • Skill tool uses exact match first, then fuzzy search, with helpful error messages listing available skills

https://claude.ai/code/session_01Q5TnLskGfMzuS7VZLLXRCS

Agent Loop:
- Remove wasteful checkLoopFinish (extra LLM call per turn)
- Use standard ReAct pattern: no tool calls + text = done
- Add lifecycle hooks (onTurnStart, onTurnEnd, onToolCallStart,
  onToolCallEnd, onText, onError)
- Add abort signal support via AbortController
- Track turns with structured TurnInfo and return LoopResult
- Properly preserve text alongside tool calls in messages

Skill System:
- Fix skill tool to use SkillRegistry singleton instead of re-scanning
- Inject skill list into system prompt (as designed in docs)
- Add slash command support (/skill-name args) in CLI
- Add /skills command to list available skills
- Add fuzzy matching fallback in skill tool
- Lazy tool construction: buildTools() called after registry init

Types:
- Add ToolCallInfo, TurnInfo, LoopResult, LoopHooks, LoopOptions
- Add abortSignal to Context

https://claude.ai/code/session_01Q5TnLskGfMzuS7VZLLXRCS
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants