Add skill_search tool so agent can search for skills before installing.
Update skill_install description to guide LLM to search first.
Update system prompt to use skill_search -> skill_install flow.
This fixes the issue where agent returns empty when asked to find a skill.
- Settings API: reverse-resolve env vars to preserve ${VAR} refs in yaml,
write new API keys to .env instead of agentkit.yaml, extract env_key
from existing ${VAR} reference when updating providers
- Onboarding: merge-update instead of overwrite when config exists,
use config_arg to determine output path, .env merge instead of overwrite
- Unified templates: bailian-coding provider name, full model_aliases,
docker-compose with postgres, expanded .env.example
- Optional ruamel.yaml for comment/format preservation in Settings API
- clients.yaml: add _deep_resolve for ${VAR} env var references
- All CLI commands use load_config_with_dotenv() consistently
- Tests: mock find_config_path and CWD auto-discovery to avoid env leaks
Key improvements:
- Low-complexity queries (<0.3) now try IntentRouter keyword match
before falling back to DIRECT_CHAT, fixing 0% F1 on keyword_match
- SemanticRouter similarity_low lowered from 0.6 to 0.4
- Short text (<20 chars) uses effective_low = max(0.25, low - 0.15)
- Short text with no semantic match forces LLM classify fallback
- Added colloquial keywords to 7 skill YAMLs
- Fixed code_reviewer.yaml output_schema placement
- Fixed SemanticRouter build in e2e tests
- Fixed base_url detection for bailian-coding API keys
Results: keyword_match F1 0->60.87%, colloquial F1 0->100%, mixed_lang F1 0->100%
When path starts with /api/, treat it as an absolute URL instead of
prepending baseUrl. This fixes installSkill/uninstallSkill URL
concatenation that produced /api/v1/skill-management/api/v1/skills/...
- QuadrantPanel: persist activeTab and collapsed state to localStorage via watch
- TopNav: remove v-if="false" dead code for TaskSelector, remove unused ASelect import
- SplitPane: add null guard before containerRef.value access in onMouseDown
- Router: fix /agent/code route loading ChatView instead of WorkflowView
- Router: add default redirect for /legacy to /legacy/chat
- EvolutionView: simplify from 6 sub-panels to 3 tabs (概览+指标, 经验+坑点, 用量)
- SettingsView: group into 4 tabs (LLM, 技能, 知识库, 系统), each with independent save
- SkillsView: replace hardcoded colors with Design Tokens
- All three views: replace hardcoded colors with Design Token references
- TerminalView: replace native HTML confirmation with Ant Design Modal,
make command history sidebar collapsible (default collapsed)
- TerminalEmulator: use One Dark Pro CSS variables for ANSI colors,
replace all hardcoded colors with Design Tokens
- CommandHistory: replace all hardcoded colors with Design Tokens
- Create AgentLayout.vue with CSS Grid four-quadrant layout
- Create SplitPane.vue with draggable divider and localStorage persistence
- Create TopNav.vue with logo, status indicator, and settings entry
- Create QuadrantPanel.vue with tab switching and collapse support
- Restructure router: /agent as main route, legacy routes redirect
- App.vue now uses router-view for layout switching
- Create tokens.css with CSS custom properties for colors, spacing,
radius, fonts, shadows, transitions, and code theme
- Create theme.ts mapping tokens to Ant Design Vue ConfigProvider
- Create styles/index.ts as unified entry point
- Inject theme into App.vue ConfigProvider
- Import styles in main.ts
Primary color unified to #7c3aed (purple gradient brand color).
- Add HeuristicClassifier to replace LLM quick_classify with zero-cost
local heuristic (keyword/length/code-pattern scoring), gated by
router.classifier config (default: heuristic)
- Add parallel tool execution in ReActEngine via asyncio.gather for
multiple independent tool_calls, gated by parallel_tools param
- Add AsyncWriteQueue for non-blocking session persistence with WAL
buffer, gated by async_writes param on SessionManager
- Add httpx.Limits connection pool config to all LLM providers
- Add router config section to ServerConfig and agentkit.yaml
- All optimizations have config switches for safe rollback
Critical:
- C1: Add verifier_timeout_seconds for independent Verifier timeout
- C2: Verifier parse failure raises RuntimeError instead of dead-loop
Major:
- M1: Inject previous_output into Worker retry context
- M2: Add Pydantic ge/le constraint on ReviewFeedback.score
- M3: Use Literal type for feedback_mode enum validation
- M4: Use Literal types for ReviewIssue severity and category
- M5: Merge error messages when escalation agent also fails
Tests: 8 new test cases added (19 total), all passing
Add ReviewIssue, ReviewFeedback, AdversarialState models and extend
PipelineStage with verifier, max_adversarial_rounds, feedback_mode,
and escalate_on_exhaust fields for Worker-Verifier adversarial loop.
DeepSeek-chat has limited/partial function calling support. Qwen3-coder-plus
(DashScope) has robust OpenAI-compatible function calling.
Also added tool usage instructions to system prompt and enhanced logging
to trace tool propagation through the pipeline.
1. Loading indicator: three-dot bouncing animation appears after
sending a message and disappears when server starts responding.
2. Tool descriptions: resolve_skill_routing now appends available
tools (name + description + parameters) to the system prompt so
the LLM knows what tools it can call.
Root cause: app.py registers tools via agent._tool_registry.register()
which adds to the ToolRegistry but NOT to agent._tools (which is only
populated by use_tool() from config). Both get_tools() and
get_system_prompt() were reading only _tools, missing all post-init
registered tools. Now both methods merge _tools with
_tool_registry.list_tools().
Previously get_system_prompt() only returned identity/instructions but
did not tell the LLM what tools are available. The LLM would therefore
refuse to call tools even when they were registered, saying it had no
tools. Now the system prompt includes a '## 可用工具' section listing
all registered tools with their descriptions and parameters.
e.isComposing is a standard KeyboardEvent property that's true during
IME composition. More reliable than compositionstart/compositionend
which can fire at unpredictable timing relative to keydown.
Added compositionstart/compositionend event listeners to track IME
composing state. Enter key now only submits when not composing,
so Chinese/Japanese/Korean input methods work correctly.
When IntentRouter matches a direct-mode agent (no tools), but the task
content suggests tool needs (shell, search, file ops, etc.), the routing
now falls through to the default agent which has full tool access.
This fixes the issue where "帮我执行个命令" would be routed to
direct_agent and fail because direct mode doesn't support tool calling.
Also restored "你好" in direct_agent keywords since it's correctly
handled now — greetings don't need tools, direct mode is fine.
1. InMemoryMessageBus.request(): fix param name (timeout→timeout_seconds) to match ABC
2. InMemoryMessageBus: track consumer tasks, cancel on unsubscribe
3. InMemoryMessageBus: _try_resolve_pending() in queue consumer path
4. evolve_soul(): use "default" category when patterns is empty
5. quick_classify(): use delimiter-based prompt to mitigate injection risk
6. Use asyncio.get_running_loop() instead of deprecated get_event_loop()
1. Critical: Add missing TaskResult import in plan_exec_engine.py
2. Critical: Fix ReWOOEngine param name (max_steps → max_plan_steps)
3. Major: Remove duplicate token counting in reflexion.py
4. Major: LLM audit failure now passes (trusts rule check) instead of failing
5. Major: Fix dict iteration with del using list() copy in lifecycle.py
6. Major: Fix Chinese content tokenization using regex split instead of space split
7. Minor: _is_positive_mention now checks all occurrences, not just the first
Phase B:
- U1: CostAwareRouter with 3-layer routing (rule/LLM/capability matching)
- U6: OrganizationContext with agent profiles and capability-based discovery
- U7: AlignmentGuard with constraint injection and cascade detection
Phase C:
- U8: Soul dynamic evolution with version tracking and reflection-triggered updates
- U9: Auction mechanism as optional advanced routing mode
- U10: Server integration + end-to-end integration tests
250 new tests passing across all units.
- Shell whitelist: use exact binary match instead of startswith
- Shell audit log: use deque(maxlen=10000) to cap memory
- Terminal history: use deque(maxlen) for O(1) eviction
- Path optimizer: cap _pending_paths at 50 entries per task_type
- Pitfall detector: only add tips to matching steps, not all
- Experience store: handle non-numeric _parse_time_window input
- Extract shared is_safe_url() to utils/security.py (DRY)
- Workflow condition evaluator: handle float() ValueError
- Enhanced chat CLI with adaptive mode and session management
- Added pipeline reflection and schema extensions
- Upgraded BaiduSearch and WebSearch tools with advanced capabilities
- Expanded server routes for skills and chat
- Added session store enhancements
- New chat module and pipeline reflection support
- Orchestrator accepts optional message_bus parameter; workers publish
task.progress messages via MessageBus after each subtask execution
- AgentPool accepts optional message_bus; auto-registers agents on
create and auto-unregisters on remove
- app.py initializes MessageBus from config and injects into AgentPool
- ServerConfig adds bus configuration field
- 5 new tests, all passing
- AgentMessage: message model with sender/recipient/topic/payload/correlation_id
- MessageBus Protocol: publish/subscribe/unsubscribe/request/broadcast/health_check
- InMemoryMessageBus: asyncio.Queue-based implementation for testing
- RedisMessageBus: Redis Streams (XADD/XREADGROUP) implementation with
consumer groups, message acknowledgment, and dead letter queue
- create_message_bus() factory with graceful Redis→InMemory fallback
- Request-response pattern via correlation_id + asyncio.Future
- 13 new tests, all passing
- AskHumanTool: Human-in-the-Loop tool for Chat mode, pushes questions
via WebSocket callback and waits for user reply via asyncio.Future
- Token streaming: execute_stream() now uses chat_stream() instead of
chat(), yielding token-type ReActEvents for each StreamChunk
- _build_response_from_stream() static method constructs LLMResponse
from accumulated stream data
- Export AskHumanTool from tools/__init__.py
- 12 new tests (7 AskHumanTool + 5 token streaming), all passing
Add HeadroomRetrieveTool that allows LLM to retrieve original
uncompressed data from CCR cache via Function Calling. Auto-registered
when HeadroomCompressor is active and available.
Add compression config to ServerConfig (following telemetry pattern),
create compressor in create_app, pass through AgentPool to
ConfigDrivenAgent, and inject into ReActEngine.execute() calls.
Add HeadroomCompressor implementing CompressionStrategy Protocol with
content-type routing (JSON→SmartCrusher, code→CodeCompressor), CCR
reversible compression cache, and graceful degradation when headroom-ai
is not installed.
Add runtime-checkable CompressionStrategy Protocol with compress(),
compress_tool_result(), and is_available() methods. Add compress_tool_result
and is_available to existing ContextCompressor. Add create_compressor()
factory function with headroom/summary provider routing and ImportError
fallback.
Add telemetry module with tracing (agent/tool/llm/pipeline_step spans),
metrics (5 histograms/counters), and setup with optional OTLP exporters.
Uses no-op pattern when opentelemetry not installed. GenAI Semantic
Conventions for LLM spans. Integrated into ReactEngine, LLMGateway,
ToolBase, and FastAPI app.
Add StepRetryPolicy with jitter-based exponential backoff, SagaOrchestrator
with LIFO compensation pattern, integrate retry_policy and compensate
fields into PipelineStage/PipelineStep schema, add GEO pipeline
compensation definitions for all 7 steps.
Add PipelineStateMemory/Redis/PG backends, PipelineStateManager with
Redis Sorted Set hot state + PostgreSQL JSONB cold persistence.
Integrated into PipelineEngine with state persistence calls at each
step transition.
Add WebCrawlTool (Crawl4AI wrapper with graceful degradation),
SchemaExtractTool (extruct-based Schema.org extraction), and
SchemaGenerateTool (JSON-LD generation with optional pydantic-schemaorg
validation). All tools work without optional dependencies.
Add MCPServerConfig dataclass with stdio/streamable_http/sse transport
validation, MCPManager for declarative YAML-driven MCP server lifecycle
(start_all/stop_all), tool discovery and registration. Integrated
into FastAPI lifespan startup/shutdown.
Add StdioTransport class supporting stdio JSON-RPC over subprocess
stdin/stdout with asyncio.create_subprocess_exec, pending futures
for request/response matching, and stderr forwarding.
- Added _acquire_status_lock with timeout (30s) to prevent deadlocks
- Added _release_status_lock for safe lock release
- Added config_version tracking on BaseAgent
- Config hot-reload now increments version and propagates to agents
- Audit logging with config version in _on_config_change
- WenxinProvider: Baidu ERNIE via Qianfan v2 OpenAI-compatible API, AK/SK token auth
- DoubaoProvider: ByteDance Doubao via Volcengine Ark API
- YuanbaoProvider: Tencent Hunyuan via OpenAI-compatible API with enhancement mode
- All inherit from OpenAICompatibleProvider for retry/circuit breaker support
- 16 tests passing
- EpisodeModel ORM model with pgvector embedding support
- create_episodic_session_factory for async PostgreSQL sessions
- Server app.py now resolves session_factory from database_url config
- Graceful fallback when database_url not configured
U5: TaskStore - in-memory task state with TTL cleanup and max records
U6: BackgroundRunner - async task execution with semaphore concurrency control
U7: Task status/result API + cancel endpoint + async submit mode
45 tests passing (28 new + 17 existing, no regression).