Skip to content

refactor(agent): align core agent & tool system with CC engineering patterns#188

Open
nmhjklnm wants to merge 20 commits intomainfrom
refactor/agent-optimize
Open

refactor(agent): align core agent & tool system with CC engineering patterns#188
nmhjklnm wants to merge 20 commits intomainfrom
refactor/agent-optimize

Conversation

@nmhjklnm
Copy link
Copy Markdown
Collaborator

@nmhjklnm nmhjklnm commented Apr 2, 2026

Summary

Systematic alignment of Mycel's core agent and tool system with Claude Code's engineering patterns, extracted from CC source analysis.

  • QueryLoop: Replace ad-hoc create_agent with a proper QueryLoop driving LangGraph, add CleanupRegistry for priority-ordered teardown, and introduce three-layer state models (InputState, AgentState, OutputState)
  • Tool system: Align Grep/Glob/Read/Write/Edit/Agent/task tool descriptions and schemas with CC conventions; add is_concurrency_safe / is_read_only flags; add sub-agent tool filtering per agent type
  • LSP service: Full 9-operation LSP tool (goToDefinition, findReferences, hover, documentSymbol, workspaceSymbol, goToImplementation, prepareCallHierarchy, incomingCalls, outgoingCalls) via multilspy (Jedi) + pyright-langserver dual backend; sessions are process-level singletons surviving agent restarts
  • Compactor: Align with CC L4b Legacy Compact design
  • Context fork: Sub-agents spawn via context fork for proper isolation

Test plan

  • Unit tests: tests/test_state.py, tests/test_cleanup.py, tests/test_fork.py, tests/test_loop.py
  • Integration test: tests/test_agent_astream.py
  • LSP smoke test: goToDefinition, prepareCallHierarchy, outgoingCalls on Python files
  • uv tool install . --force and verify leon starts cleanly

nmhjklnm and others added 20 commits April 1, 2026 22:48
- Add docs/architecture/ with 11 deep-dive docs covering CC patterns:
  query loop, tool execution, state/agents, security/permissions,
  API/prompt infra, PowerShell, plugins, settings/platform,
  compaction pipeline (4-layer, SM-Compact, Legacy Compact details)
- Add cc-patterns.md master blueprint with LangChain mapping,
  implementation priority roadmap (Phase 1-5), and PARTIAL gap registry
- Refactor core agent modules: chat_tool_service, delivery, service,
  agent runtime, registry, filesystem/search/wechat tool services
- Add core/runtime/prompts.py
- Phase 1: slim system prompt — move tool usage guidance to descriptions,
  keep only sub-agent type routing in system prompt
- Phase 2: rewrite all tool descriptions to convey non-intuitive boundary
  conditions (Read/Write/Edit/Glob/Grep/Bash/Agent/WebSearch/WebFetch/
  TaskOutput/TaskStop/TaskCreate/tool_search/load_skill)
- Phase 3: add pages param to Read schema; add line_numbers param to Grep
  schema and handler; add subagent_type enum to Agent schema
- Phase 4: mark WebSearch/WebFetch/tool_search/load_skill/TaskGet/TaskList/
  wechat_contacts as is_concurrency_safe + is_read_only
- Phase 5: sub-agent tool filtering — AGENT_DISALLOWED/EXPLORE_ALLOWED/
  PLAN_ALLOWED/BASH_ALLOWED constants; LeonAgent accepts extra_blocked_tools
  and allowed_tools; _run_agent applies per-type filters
- Phase 6: add LSP placeholder to tool_catalog (deferred, default=False)
- Extras: search_hint for Agent/TaskOutput/TaskStop/chat tools/wechat_send;
  TaskOutput marked is_read_only; Edit description adds .ipynb workaround;
  fix prompt caching to place cache_control on system_message content block;
  add forkContext parent message inheritance with _filter_fork_messages;
  expose set_current_messages ContextVar for sub-agent context passing
- Add --max-columns 500 to suppress minified/base64 output
- Add missing VCS excludes: .svn, .hg, .bzr, .jj, .sl
- Default head_limit 250 (matches CC's undocumented cap)
Registers a DEFERRED LSP tool providing code intelligence:
goToDefinition, findReferences, hover, documentSymbol, workspaceSymbol.

- _LSPSession: holds multilspy LanguageServer alive in a background asyncio
  task using start_server() context manager + Event-based lifecycle control
- LSPService: lazy per-language session pool, auto-detects language from
  file extension, converts absolute paths to workspace-relative
- Integrated into LeonAgent._init_services() with CleanupRegistry at priority 1
- Optional dep: pip install multilspy (or leonai[lsp])
- Supported: python, typescript, javascript, go, rust, java, ruby, kotlin, csharp
- Language servers auto-downloaded on first use per multilspy design
- multilspy moved from optional to core dependencies (avoid restart cost)
- Add 10 MB file size limit (matches CC LSP spec)
- Add gitignore filtering on returned locations via git check-ignore,
  batched in groups of 50 (matches CC batch size)
- Remove multilspy availability check from handler (always available now)
Adds 4 missing LSP operations via multilspy internal API:
- goToImplementation (textDocument/implementation)
- prepareCallHierarchy (textDocument/prepareCallHierarchy)
- incomingCalls (callHierarchy/incomingCalls)
- outgoingCalls (callHierarchy/outgoingCalls)

Total supported operations: 9 (matches CC LSP tool surface).
incomingCalls/outgoingCalls take the 'item' output from prepareCallHierarchy.
Language auto-detected from item.uri for call hierarchy ops.
- _fmt_symbol: handle both SymbolInformation (workspaceSymbol, has location.uri)
  and DocumentSymbol (documentSymbol, has top-level range/selectionRange)
- request_definition/references/hover/document_symbols: catch AssertionError
  from multilspy when server returns None (maps to empty result / no hover)
…langserver

Python's Jedi server doesn't support goToImplementation or call hierarchy.
Add _PyrightSession — a minimal asyncio LSP client over stdio — that talks to
pyright-langserver (bundled with `pip install pyright`, already a core dep).

Changes:
- _PyrightSession: JSON-RPC/Content-Length stdio client, initialize handshake,
  textDocument/didOpen, callHierarchy/{incomingCalls,outgoingCalls},
  textDocument/{implementation,prepareCallHierarchy}
- Acks server-to-client requests (window/workDoneProgress/create etc.)
- Keeps files open for session lifetime (required for call hierarchy)
- LSPService routes Python advanced ops to pyright, other languages to multilspy
- Fix _fmt_symbol: handle both SymbolInformation (workspaceSymbol) and
  DocumentSymbol (documentSymbol) response formats
- Fix AssertionError from multilspy null responses → empty result
- pyproject.toml: add core.tools.lsp to packages list (was missing — would
  cause lsp tool to be absent after pip install leonai)
- pyproject.toml: add pyright>=1.1.0 as core dep (required by _PyrightSession)
- lsp/service.py: remove unused _wait_for_idle, _active_progress, _idle_event,
  _progress_started from _PyrightSession (pyright doesn't send $/progress)
- plan-tool-alignment.md: replace Phase 6 placeholder with actual implementation
  summary (9 operations, dual-backend architecture, deps)
Language servers (multilspy + pyright) now live in a module-level
_LSPSessionPool instead of per-LSPService instances. Sessions are keyed
by (language, workspace_root), start lazily on first use, and survive
agent restarts. Cleanup moved from CleanupRegistry to the backend
lifespan finally block via `await lsp_pool.close_all()`.

- Add _LSPSessionPool with asyncio.Task-based dedup for concurrent starts
- Simplify LSPService to delegate all session management to lsp_pool
- Remove _cleanup_lsp_service from LeonAgent and CleanupRegistry
- Add lsp_pool.close_all() to backend/web/core/lifespan.py shutdown

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@OpenDCAI OpenDCAI deleted a comment from f-2j Apr 4, 2026
@OpenDCAI OpenDCAI deleted a comment from f-2j Apr 4, 2026
@OpenDCAI OpenDCAI deleted a comment from f-2j Apr 4, 2026
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.

1 participant