refactor(agent): align core agent & tool system with CC engineering patterns#188
Open
refactor(agent): align core agent & tool system with CC engineering patterns#188
Conversation
- 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>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Systematic alignment of Mycel's core agent and tool system with Claude Code's engineering patterns, extracted from CC source analysis.
create_agentwith a properQueryLoopdriving LangGraph, addCleanupRegistryfor priority-ordered teardown, and introduce three-layer state models (InputState,AgentState,OutputState)Grep/Glob/Read/Write/Edit/Agent/tasktool descriptions and schemas with CC conventions; addis_concurrency_safe/is_read_onlyflags; add sub-agent tool filtering per agent typeTest plan
tests/test_state.py,tests/test_cleanup.py,tests/test_fork.py,tests/test_loop.pytests/test_agent_astream.pygoToDefinition,prepareCallHierarchy,outgoingCallson Python filesuv tool install . --forceand verifyleonstarts cleanly