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
- code_reviewer.yaml: Verifier Agent skill config for adversarial review
with structured output schema for ReviewFeedback format
- coding_harness.yaml: Example pipeline with adversarial loop
develop → test → review (Worker↔Verifier) → archive
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.
Hardcoded model names like 'openai/gpt-4o-mini' or 'anthropic/claude-sonnet'
cause 'No provider available' errors when the specific provider isn't configured.
Using 'default' lets the system pick the available provider automatically.
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.