The ChatArea.tsx toolSteps/subtasks rendering uses helper functions to avoid TypeScript strict mode && chain producing unknown type in JSX children. Add SubscriptionPanel component for subscription status display in SaaS billing section.
Sprint 2: 产品体验打磨 + 行业模板
- Create PipelineResultPreview component with tab-based output switching
- Connect workflow/hand messages to PresentationContainer in ChatArea
- Add auto-trigger first Hand after onboarding (industry-specific queries)
- Seed 3 industry agent templates (education, healthcare, design-shantou)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Model Groups provide logical model names that map to multiple physical
models across providers, with automatic failover when one provider's
key pool is exhausted.
Backend:
- New model_groups + model_group_members tables with FK constraints
- Full CRUD API (7 endpoints) with admin-only write permissions
- Cache layer: DashMap-backed CachedModelGroup with load_from_db
- Relay integration: ModelResolution enum for Direct/Group routing
- Cross-provider failover: sort_candidates_by_quota + OnceLock cache
- Relay failure path: record failure usage + relay_dequeue (fixes
queue counter leak that caused connection pool exhaustion)
- add_group_member: validate model_id exists before insert
Frontend:
- saas-relay-client: accept getModel() callback for dynamic model selection
- connectionStore: prefer conversationStore.currentModel over first available
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Kernel orchestration bridge: execute_orchestration, auto_compose_skills,
validate_orchestration methods on Kernel struct
- True parallel execution: replace sequential for-loop with tokio::JoinSet
for concurrent node execution within parallel groups
- Tauri commands: orchestration_execute (auto-compose or pre-defined graph),
orchestration_validate (dry-run validation)
- Full type conversions: OrchestrationRequest/Response with camelCase serde
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- MCPServices.tsx now calls real Tauri commands (start/stop/list)
instead of only toggling config flags
- Show running service count, discovered tools per service
- Expand/collapse tool list for each running MCP service
- Extended QuickConfig mcpServices type with command/args/env/cwd
- Config change persists enabled state, MCP start/stop happens live
Full E2E test suite for agent chat functionality including:
- Message send/receive flow
- Streaming response verification
- Model switching behavior
- Error handling scenarios
- Multi-turn conversation context
Includes test report documenting coverage and known gaps.
S6 MCP Protocol:
- Fix McpTransport::initialize() — store actual server capabilities instead
of discarding them and storing empty ServerCapabilities::default()
- Add send_notification() method to McpTransport for JSON-RPC notifications
- Send notifications/initialized after MCP handshake (spec requirement)
- Add McpToolAdapter: bridges MCP server tools into the tool execution path
- Add McpServiceManager: lifecycle management for MCP server connections
- Add 4 Tauri commands: mcp_start_service, mcp_stop_service,
mcp_list_services, mcp_call_tool
- Register zclaw-protocols dependency in desktop Cargo.toml
New files:
- crates/zclaw-protocols/src/mcp_tool_adapter.rs (153 lines)
- desktop/src-tauri/src/kernel_commands/mcp.rs (145 lines)
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- ChatArea.tsx: remove duplicate useState(searchOpen) declaration on line 70
- scheduled_task/mod.rs: fix route from /api/scheduler/tasks to /api/v1/scheduler/tasks
(matches admin-v2 service baseURL pattern and all other modules)
- scheduled_task/handlers.rs: remove @reserved annotations (now has Admin V2 frontend)
- scheduled_task/handlers.rs: update doc comments with correct /api/v1/ paths
- Add welcomeMessage/quickCommands fields to Clone interface
- Persist template welcome/quick data via updateClone after creation
- FirstConversationPrompt: prefer template-provided welcome message
over dynamically generated one
- FirstConversationPrompt: render template quick_commands as chips
instead of hardcoded QUICK_ACTIONS when available
- Tighten assign/unassign template endpoint permissions from model:read
to relay:use (self-service operation for all authenticated users)
- Fix seed template tools to match actual runtime tool names
(file_read/file_write/shell_exec/web_fetch)
- Persist system_prompt/temperature/max_tokens via identity system
in agentStore.createFromTemplate()
- Fire-and-forget assignTemplate() in AgentOnboardingWizard
- Fix saas-relay-client unused variable warning
- Make pgvector extension optional in knowledge_base migration
- Increase StreamBridge timeout from 30s to 90s for thinking models
Root cause: ChatArea.tsx called listen() from @tauri-apps/api/event
directly on component mount without checking isTauriRuntime(). When
accessed from a regular browser (not Tauri WebView), window.__TAURI_INTERNALS__
is undefined, causing "Cannot read properties of undefined (reading 'transformCallback')".
Solution:
- Created lib/safe-tauri.ts with safe wrappers (safeInvoke, safeListen,
safeListenEvent, requireInvoke) that gracefully degrade when Tauri
IPC is unavailable
- Replaced direct listen() call in ChatArea.tsx with safeListenEvent()
Step 5 (embedding config) and Step 5b (summary driver) in App.tsx
bootstrap called invoke() without checking if Tauri IPC is available.
When accessing http://localhost:1420/ in a regular browser, this caused
"Cannot read properties of undefined (reading 'transformCallback')".
Also added __TAURI_INTERNALS__ guard in saasStore kernel config sync.
SessionStreamGuard and StreamCancelFlags were type aliases to the same
Arc<DashMap<String, Arc<AtomicBool>>> type. Tauri distinguishes managed
state by Rust type, so registering both caused a runtime panic:
"state for type ... is already being managed".
Changed to newtype structs with Deref impl to the inner Arc<DashMap>,
keeping all call sites compatible without changes.
- STABILIZATION_DIRECTIVE.md: feature freeze rules, banned actions, priorities
- TRUTH.md: single source of truth for system state (crate counts, store counts)
- AI_SESSION_PROMPTS.md: three-layer prompt system for AI sessions
- Industry agent delivery design spec
- Stabilization test suite for regression prevention
- Delete stale ISSUE-TRACKER.md
- Add .dockerignore for container builds
- Add brainstorm session artifacts
Replace error-swallowing let _ = patterns with tracing::warn! in browser,
classroom, gateway, intelligence, memory, pipeline, secure_storage, and
viking command handlers. Ensures errors are observable in production logs.
Server side:
- POST /api/v1/billing/usage/increment endpoint with dimension whitelist
(hand_executions, pipeline_runs, relay_requests) and count validation (1-100)
- Returns updated usage quota after increment
Desktop side:
- New saas-billing.ts mixin with incrementUsageDimension() and
reportUsageFireAndForget() (non-blocking, safe for finally blocks)
- handStore.triggerHand: reports hand_executions after successful run
- PipelinesPanel.handleRunComplete: reports pipeline_runs on completion
- SaaSClient type declarations for new billing methods
Billing pipeline now covers all three dimensions:
relay_requests → relay handler (server-side, real-time)
hand_executions → handStore (client-side, fire-and-forget)
pipeline_runs → PipelinesPanel (client-side, fire-and-forget)
Replace the inline ResultModal with the full-featured
PipelineResultPreview component. This gives users JSON/Markdown/
Classroom mode switching, file download cards, and classroom export
support instead of the previous basic PresentationContainer wrapper.
Remove unused ResultModal component and PresentationContainer import.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Tailor first-conversation prompts to the three target user groups:
- Education: AI tool comparison, digital transformation research
- Healthcare: administrative optimization proposal
- Design/Shantou: toy industry export trend analysis
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
- Fix inconsistent 'KernelClient' logger name to 'KernelHands' in listApprovals
- Replace console.error with logger.error in gateway-api triggerHand
- No functional changes, only logging consistency improvements
1. App.tsx: add restoreSession() call on startup to prevent redirect
to login page after refresh (isRestoring guard + BootstrapScreen)
2. CloneManager: call syncAgents() after loadClones() to restore
currentAgent and conversation history on app load
3. zclaw-memory: add get_or_create_session() so frontend session UUID
is persisted directly — kernel no longer creates mismatched IDs
4. openai.rs: assistant message content must be non-empty for
Kimi/Qwen APIs — replace empty content with meaningful placeholders
Also includes admin-v2 ModelServices unified page (merge providers +
models + API keys into expandable row layout)
- Add AgentTemplateAvailable/AgentTemplateFull types and fetchAvailableTemplates/fetchTemplateFull API methods to saas-client
- Add llm_routing field to SaaSAccountInfo for admin-configured routing priority
- Add availableTemplates state and fetchAvailableTemplates action to saasStore with background fetch on login
- Add admin llm_routing priority check in connectionStore connect() to force relay or local mode
- Add createFromTemplate action to agentStore with SOUL.md persistence
- Add Step 0 template selection to AgentOnboardingWizard with grid layout for template browsing