feat: DeerFlow 2.0 core capabilities — Phase 1.0 + 1.1
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
Some checks failed
CI / Lint & TypeCheck (push) Has been cancelled
CI / Unit Tests (push) Has been cancelled
CI / Build Frontend (push) Has been cancelled
CI / Rust Check (push) Has been cancelled
CI / Security Scan (push) Has been cancelled
CI / E2E Tests (push) Has been cancelled
Phase 1.0 — Butler Mode UI: - Hide "自动化" and "技能市场" entries from sidebar navigation - Remove AutomationPanel and SkillMarket view rendering from App.tsx - Simplify MainViewType to only 'chat' - Main interface is now: chat + conversation list + detail panel only Phase 1.1 — Mode Differentiation: - Add subagent_enabled field to ChatModeConfig (Rust), StreamChatRequest (Tauri), gateway-client, kernel-client, saas-relay-client, and streamStore - TaskTool is now only registered when subagent_enabled=true (Ultra mode) - System prompt includes sub-agent delegation instructions only in Ultra mode - Frontend transmits subagent_enabled from ChatMode config through the full stack This connects the 4-tier mode selector (Flash/Thinking/Pro/Ultra) to actual backend behavioral differences — Ultra mode now truly enables sub-agent delegation.
This commit is contained in:
@@ -4,12 +4,13 @@ use tokio::sync::mpsc;
|
|||||||
use zclaw_types::{AgentId, Result};
|
use zclaw_types::{AgentId, Result};
|
||||||
|
|
||||||
/// Chat mode configuration passed from the frontend.
|
/// Chat mode configuration passed from the frontend.
|
||||||
/// Controls thinking, reasoning, and plan mode behavior.
|
/// Controls thinking, reasoning, plan mode, and sub-agent behavior.
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub struct ChatModeConfig {
|
pub struct ChatModeConfig {
|
||||||
pub thinking_enabled: Option<bool>,
|
pub thinking_enabled: Option<bool>,
|
||||||
pub reasoning_effort: Option<String>,
|
pub reasoning_effort: Option<String>,
|
||||||
pub plan_mode: Option<bool>,
|
pub plan_mode: Option<bool>,
|
||||||
|
pub subagent_enabled: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
use zclaw_runtime::{AgentLoop, tool::builtin::PathValidator};
|
use zclaw_runtime::{AgentLoop, tool::builtin::PathValidator};
|
||||||
@@ -45,7 +46,8 @@ impl Kernel {
|
|||||||
let model = self.config.model().to_string();
|
let model = self.config.model().to_string();
|
||||||
|
|
||||||
// Create agent loop with model configuration
|
// Create agent loop with model configuration
|
||||||
let tools = self.create_tool_registry();
|
let subagent_enabled = chat_mode.as_ref().and_then(|m| m.subagent_enabled).unwrap_or(false);
|
||||||
|
let tools = self.create_tool_registry(subagent_enabled);
|
||||||
let mut loop_runner = AgentLoop::new(
|
let mut loop_runner = AgentLoop::new(
|
||||||
*agent_id,
|
*agent_id,
|
||||||
self.driver.clone(),
|
self.driver.clone(),
|
||||||
@@ -92,7 +94,10 @@ impl Kernel {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Build system prompt with skill information injected
|
// Build system prompt with skill information injected
|
||||||
let system_prompt = self.build_system_prompt_with_skills(agent_config.system_prompt.as_ref()).await;
|
let system_prompt = self.build_system_prompt_with_skills(
|
||||||
|
agent_config.system_prompt.as_ref(),
|
||||||
|
subagent_enabled,
|
||||||
|
).await;
|
||||||
let loop_runner = loop_runner.with_system_prompt(&system_prompt);
|
let loop_runner = loop_runner.with_system_prompt(&system_prompt);
|
||||||
|
|
||||||
// Run the loop
|
// Run the loop
|
||||||
@@ -147,7 +152,8 @@ impl Kernel {
|
|||||||
let model = self.config.model().to_string();
|
let model = self.config.model().to_string();
|
||||||
|
|
||||||
// Create agent loop with model configuration
|
// Create agent loop with model configuration
|
||||||
let tools = self.create_tool_registry();
|
let subagent_enabled = chat_mode.as_ref().and_then(|m| m.subagent_enabled).unwrap_or(false);
|
||||||
|
let tools = self.create_tool_registry(subagent_enabled);
|
||||||
let mut loop_runner = AgentLoop::new(
|
let mut loop_runner = AgentLoop::new(
|
||||||
*agent_id,
|
*agent_id,
|
||||||
self.driver.clone(),
|
self.driver.clone(),
|
||||||
@@ -197,7 +203,10 @@ impl Kernel {
|
|||||||
// Use external prompt if provided, otherwise build default
|
// Use external prompt if provided, otherwise build default
|
||||||
let system_prompt = match system_prompt_override {
|
let system_prompt = match system_prompt_override {
|
||||||
Some(prompt) => prompt,
|
Some(prompt) => prompt,
|
||||||
None => self.build_system_prompt_with_skills(agent_config.system_prompt.as_ref()).await,
|
None => self.build_system_prompt_with_skills(
|
||||||
|
agent_config.system_prompt.as_ref(),
|
||||||
|
subagent_enabled,
|
||||||
|
).await,
|
||||||
};
|
};
|
||||||
let loop_runner = loop_runner.with_system_prompt(&system_prompt);
|
let loop_runner = loop_runner.with_system_prompt(&system_prompt);
|
||||||
|
|
||||||
@@ -206,8 +215,13 @@ impl Kernel {
|
|||||||
loop_runner.run_streaming(session_id, message).await
|
loop_runner.run_streaming(session_id, message).await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Build a system prompt with skill information injected
|
/// Build a system prompt with skill information injected.
|
||||||
pub(super) async fn build_system_prompt_with_skills(&self, base_prompt: Option<&String>) -> String {
|
/// When `subagent_enabled` is true, adds sub-agent delegation instructions.
|
||||||
|
pub(super) async fn build_system_prompt_with_skills(
|
||||||
|
&self,
|
||||||
|
base_prompt: Option<&String>,
|
||||||
|
subagent_enabled: bool,
|
||||||
|
) -> String {
|
||||||
// Get skill list asynchronously
|
// Get skill list asynchronously
|
||||||
let skills = self.skills.list().await;
|
let skills = self.skills.list().await;
|
||||||
|
|
||||||
@@ -215,7 +229,8 @@ impl Kernel {
|
|||||||
.map(|p| p.clone())
|
.map(|p| p.clone())
|
||||||
.unwrap_or_else(|| "You are a helpful AI assistant.".to_string());
|
.unwrap_or_else(|| "You are a helpful AI assistant.".to_string());
|
||||||
|
|
||||||
// Inject skill information with categories
|
// Inject skill metadata only (progressive loading pattern from DeerFlow).
|
||||||
|
// Full skill content is loaded on-demand via `load_skill_content` tool.
|
||||||
if !skills.is_empty() {
|
if !skills.is_empty() {
|
||||||
prompt.push_str("\n\n## Available Skills\n\n");
|
prompt.push_str("\n\n## Available Skills\n\n");
|
||||||
prompt.push_str("You have access to specialized skills. Analyze user intent and autonomously call `execute_skill` with the appropriate skill_id.\n\n");
|
prompt.push_str("You have access to specialized skills. Analyze user intent and autonomously call `execute_skill` with the appropriate skill_id.\n\n");
|
||||||
@@ -245,6 +260,21 @@ impl Kernel {
|
|||||||
prompt.push_str("User: \"分析腾讯财报\" → Intent: Financial analysis → Call: execute_skill(\"finance-tracker\", {...})\n");
|
prompt.push_str("User: \"分析腾讯财报\" → Intent: Financial analysis → Call: execute_skill(\"finance-tracker\", {...})\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Sub-agent delegation instructions (Ultra mode only)
|
||||||
|
if subagent_enabled {
|
||||||
|
prompt.push_str("\n\n## Sub-Agent Delegation\n\n");
|
||||||
|
prompt.push_str("You can delegate complex sub-tasks to sub-agents using the `task` tool. This enables parallel execution of independent work.\n\n");
|
||||||
|
prompt.push_str("### When to use sub-agents:\n");
|
||||||
|
prompt.push_str("- Complex tasks that can be decomposed into independent parallel sub-tasks\n");
|
||||||
|
prompt.push_str("- Research tasks requiring multiple independent searches\n");
|
||||||
|
prompt.push_str("- Tasks requiring different expertise areas simultaneously\n\n");
|
||||||
|
prompt.push_str("### Guidelines:\n");
|
||||||
|
prompt.push_str("- Break complex work into clear, self-contained sub-tasks\n");
|
||||||
|
prompt.push_str("- Each sub-task should have a clear objective and expected output\n");
|
||||||
|
prompt.push_str("- Synthesize sub-agent results into a coherent final response\n");
|
||||||
|
prompt.push_str("- Maximum 3 concurrent sub-agents — batch if more are needed\n");
|
||||||
|
}
|
||||||
|
|
||||||
prompt
|
prompt
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -162,18 +162,22 @@ impl Kernel {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Create a tool registry with built-in tools
|
/// Create a tool registry with built-in tools.
|
||||||
pub(crate) fn create_tool_registry(&self) -> ToolRegistry {
|
/// When `subagent_enabled` is false, TaskTool is excluded to prevent
|
||||||
|
/// the LLM from attempting sub-agent delegation in non-Ultra modes.
|
||||||
|
pub(crate) fn create_tool_registry(&self, subagent_enabled: bool) -> ToolRegistry {
|
||||||
let mut tools = ToolRegistry::new();
|
let mut tools = ToolRegistry::new();
|
||||||
zclaw_runtime::tool::builtin::register_builtin_tools(&mut tools);
|
zclaw_runtime::tool::builtin::register_builtin_tools(&mut tools);
|
||||||
|
|
||||||
// Register TaskTool with driver and memory for sub-agent delegation
|
// Register TaskTool only when sub-agent mode is enabled (Ultra mode)
|
||||||
let task_tool = zclaw_runtime::tool::builtin::TaskTool::new(
|
if subagent_enabled {
|
||||||
self.driver.clone(),
|
let task_tool = zclaw_runtime::tool::builtin::TaskTool::new(
|
||||||
self.memory.clone(),
|
self.driver.clone(),
|
||||||
self.config.model(),
|
self.memory.clone(),
|
||||||
);
|
self.config.model(),
|
||||||
tools.register(Box::new(task_tool));
|
);
|
||||||
|
tools.register(Box::new(task_tool));
|
||||||
|
}
|
||||||
|
|
||||||
tools
|
tools
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -60,6 +60,9 @@ pub struct StreamChatRequest {
|
|||||||
/// Enable plan mode
|
/// Enable plan mode
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub plan_mode: Option<bool>,
|
pub plan_mode: Option<bool>,
|
||||||
|
/// Enable sub-agent delegation (Ultra mode only)
|
||||||
|
#[serde(default)]
|
||||||
|
pub subagent_enabled: Option<bool>,
|
||||||
}
|
}
|
||||||
|
|
||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
@@ -216,6 +219,7 @@ pub async fn agent_chat_stream(
|
|||||||
thinking_enabled: request.thinking_enabled,
|
thinking_enabled: request.thinking_enabled,
|
||||||
reasoning_effort: request.reasoning_effort.clone(),
|
reasoning_effort: request.reasoning_effort.clone(),
|
||||||
plan_mode: request.plan_mode,
|
plan_mode: request.plan_mode,
|
||||||
|
subagent_enabled: request.subagent_enabled,
|
||||||
};
|
};
|
||||||
|
|
||||||
let rx = kernel.send_message_stream_with_prompt(
|
let rx = kernel.send_message_stream_with_prompt(
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
import { useState, useEffect, useCallback, useRef } from 'react';
|
import { useState, useEffect, useCallback, useRef } from 'react';
|
||||||
import { motion, AnimatePresence } from 'framer-motion';
|
|
||||||
import './index.css';
|
import './index.css';
|
||||||
import { Sidebar, MainViewType } from './components/Sidebar';
|
import { Sidebar } from './components/Sidebar';
|
||||||
import { ChatArea } from './components/ChatArea';
|
import { ChatArea } from './components/ChatArea';
|
||||||
import { RightPanel } from './components/RightPanel';
|
import { RightPanel } from './components/RightPanel';
|
||||||
import { SettingsLayout } from './components/Settings/SettingsLayout';
|
import { SettingsLayout } from './components/Settings/SettingsLayout';
|
||||||
import { AutomationPanel } from './components/Automation';
|
|
||||||
import { SkillMarket } from './components/SkillMarket';
|
|
||||||
import { AgentOnboardingWizard } from './components/AgentOnboardingWizard';
|
import { AgentOnboardingWizard } from './components/AgentOnboardingWizard';
|
||||||
import { HandApprovalModal } from './components/HandApprovalModal';
|
import { HandApprovalModal } from './components/HandApprovalModal';
|
||||||
import { TopBar } from './components/TopBar';
|
import { TopBar } from './components/TopBar';
|
||||||
@@ -17,7 +14,7 @@ import { useHandStore, type HandRun } from './store/handStore';
|
|||||||
import { useChatStore } from './store/chatStore';
|
import { useChatStore } from './store/chatStore';
|
||||||
import { initializeStores } from './store';
|
import { initializeStores } from './store';
|
||||||
import { getStoredGatewayToken } from './lib/gateway-client';
|
import { getStoredGatewayToken } from './lib/gateway-client';
|
||||||
import { pageVariants, defaultTransition, fadeInVariants } from './lib/animations';
|
|
||||||
import { Loader2 } from 'lucide-react';
|
import { Loader2 } from 'lucide-react';
|
||||||
import { isTauriRuntime, getLocalGatewayStatus, startLocalGateway } from './lib/tauri-gateway';
|
import { isTauriRuntime, getLocalGatewayStatus, startLocalGateway } from './lib/tauri-gateway';
|
||||||
import { LoginPage } from './components/LoginPage';
|
import { LoginPage } from './components/LoginPage';
|
||||||
@@ -49,7 +46,6 @@ function BootstrapScreen({ status }: { status: string }) {
|
|||||||
|
|
||||||
function App() {
|
function App() {
|
||||||
const [view, setView] = useState<View>('main');
|
const [view, setView] = useState<View>('main');
|
||||||
const [mainContentView, setMainContentView] = useState<MainViewType>('chat');
|
|
||||||
const [bootstrapping, setBootstrapping] = useState(true);
|
const [bootstrapping, setBootstrapping] = useState(true);
|
||||||
const [bootstrapStatus, setBootstrapStatus] = useState('Initializing...');
|
const [bootstrapStatus, setBootstrapStatus] = useState('Initializing...');
|
||||||
const [showOnboarding, setShowOnboarding] = useState(false);
|
const [showOnboarding, setShowOnboarding] = useState(false);
|
||||||
@@ -379,11 +375,6 @@ function App() {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// 处理主视图切换
|
|
||||||
const handleMainViewChange = (view: MainViewType) => {
|
|
||||||
setMainContentView(view);
|
|
||||||
};
|
|
||||||
|
|
||||||
// 登录门禁 — 必须登录才能使用
|
// 登录门禁 — 必须登录才能使用
|
||||||
if (isRestoring) {
|
if (isRestoring) {
|
||||||
return <BootstrapScreen status="Restoring session..." />;
|
return <BootstrapScreen status="Restoring session..." />;
|
||||||
@@ -457,7 +448,6 @@ function App() {
|
|||||||
{/* 左侧边栏 */}
|
{/* 左侧边栏 */}
|
||||||
<Sidebar
|
<Sidebar
|
||||||
onOpenSettings={() => setView('settings')}
|
onOpenSettings={() => setView('settings')}
|
||||||
onMainViewChange={handleMainViewChange}
|
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* 主内容区 */}
|
{/* 主内容区 */}
|
||||||
@@ -468,62 +458,8 @@ function App() {
|
|||||||
onOpenDetail={() => setShowDetailDrawer(true)}
|
onOpenDetail={() => setShowDetailDrawer(true)}
|
||||||
/>
|
/>
|
||||||
|
|
||||||
{/* 内容区域 */}
|
{/* 聊天区域 */}
|
||||||
<AnimatePresence mode="wait">
|
<ChatArea />
|
||||||
<motion.main
|
|
||||||
key={mainContentView}
|
|
||||||
variants={pageVariants}
|
|
||||||
initial="initial"
|
|
||||||
animate="animate"
|
|
||||||
exit="exit"
|
|
||||||
transition={defaultTransition}
|
|
||||||
className="flex-1 overflow-hidden relative flex flex-col"
|
|
||||||
>
|
|
||||||
{mainContentView === 'automation' ? (
|
|
||||||
<motion.div
|
|
||||||
variants={fadeInVariants}
|
|
||||||
initial="initial"
|
|
||||||
animate="animate"
|
|
||||||
className="h-full overflow-y-auto"
|
|
||||||
>
|
|
||||||
<div className="sticky top-0 z-10 flex items-center gap-2 px-4 py-2 bg-white/80 dark:bg-gray-900/80 backdrop-blur-sm border-b border-gray-200 dark:border-gray-800">
|
|
||||||
<button
|
|
||||||
onClick={() => handleMainViewChange('chat')}
|
|
||||||
className="p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-md transition-colors text-gray-600 dark:text-gray-400"
|
|
||||||
title="返回聊天"
|
|
||||||
>
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" className="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="m15 18-6-6 6-6"/></svg>
|
|
||||||
</button>
|
|
||||||
<span className="text-sm font-medium text-gray-900 dark:text-gray-100">自动化</span>
|
|
||||||
</div>
|
|
||||||
<AutomationPanel />
|
|
||||||
</motion.div>
|
|
||||||
) : mainContentView === 'skills' ? (
|
|
||||||
<motion.div
|
|
||||||
variants={fadeInVariants}
|
|
||||||
initial="initial"
|
|
||||||
animate="animate"
|
|
||||||
className="h-full overflow-hidden"
|
|
||||||
>
|
|
||||||
<div className="flex items-center gap-2 px-4 py-2 border-b border-gray-200 dark:border-gray-800">
|
|
||||||
<button
|
|
||||||
onClick={() => handleMainViewChange('chat')}
|
|
||||||
className="p-1.5 hover:bg-black/5 dark:hover:bg-white/5 rounded-md transition-colors text-gray-600 dark:text-gray-400"
|
|
||||||
title="返回聊天"
|
|
||||||
>
|
|
||||||
<svg xmlns="http://www.w3.org/2000/svg" className="w-4 h-4" viewBox="0 0 24 24" fill="none" stroke="currentColor" strokeWidth="2" strokeLinecap="round" strokeLinejoin="round"><path d="m15 18-6-6 6-6"/></svg>
|
|
||||||
</button>
|
|
||||||
<span className="text-sm font-medium text-gray-900 dark:text-gray-100">技能市场</span>
|
|
||||||
</div>
|
|
||||||
<div className="h-[calc(100%-40px)] overflow-auto">
|
|
||||||
<SkillMarket />
|
|
||||||
</div>
|
|
||||||
</motion.div>
|
|
||||||
) : (
|
|
||||||
<ChatArea />
|
|
||||||
)}
|
|
||||||
</motion.main>
|
|
||||||
</AnimatePresence>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* 详情抽屉 - 按需显示 */}
|
{/* 详情抽屉 - 按需显示 */}
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
import { useState } from 'react';
|
import { useState } from 'react';
|
||||||
import { motion, AnimatePresence } from 'framer-motion';
|
import { motion, AnimatePresence } from 'framer-motion';
|
||||||
import {
|
import {
|
||||||
SquarePen, MessageSquare, Bot, Search, X, Settings, Zap, Sparkles
|
SquarePen, MessageSquare, Bot, Search, X, Settings
|
||||||
} from 'lucide-react';
|
} from 'lucide-react';
|
||||||
import { ConversationList } from './ConversationList';
|
import { ConversationList } from './ConversationList';
|
||||||
import { CloneManager } from './CloneManager';
|
import { CloneManager } from './CloneManager';
|
||||||
@@ -15,7 +15,7 @@ const sidebarTabVariants = {
|
|||||||
exit: { opacity: 0, transition: { duration: 0.1 } },
|
exit: { opacity: 0, transition: { duration: 0.1 } },
|
||||||
};
|
};
|
||||||
|
|
||||||
export type MainViewType = 'chat' | 'automation' | 'skills';
|
export type MainViewType = 'chat';
|
||||||
|
|
||||||
interface SidebarProps {
|
interface SidebarProps {
|
||||||
onOpenSettings?: () => void;
|
onOpenSettings?: () => void;
|
||||||
@@ -89,23 +89,6 @@ export function Sidebar({
|
|||||||
智能体
|
智能体
|
||||||
</button>
|
</button>
|
||||||
|
|
||||||
{/* Divider between primary nav and secondary tools */}
|
|
||||||
<div className="mx-1 my-1 border-t border-[#e8e6e1]/40 dark:border-gray-800" />
|
|
||||||
|
|
||||||
<button
|
|
||||||
onClick={() => onMainViewChange?.('automation')}
|
|
||||||
className="w-full flex items-center gap-3 px-3 py-2 rounded-lg text-sm text-gray-600 dark:text-gray-400 hover:bg-black/5 dark:hover:bg-white/5 transition-colors"
|
|
||||||
>
|
|
||||||
<Zap className="w-4 h-4" />
|
|
||||||
自动化
|
|
||||||
</button>
|
|
||||||
<button
|
|
||||||
onClick={() => onMainViewChange?.('skills')}
|
|
||||||
className="w-full flex items-center gap-3 px-3 py-2 rounded-lg text-sm text-gray-600 dark:text-gray-400 hover:bg-black/5 dark:hover:bg-white/5 transition-colors"
|
|
||||||
>
|
|
||||||
<Sparkles className="w-4 h-4" />
|
|
||||||
技能市场
|
|
||||||
</button>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
{/* Divider */}
|
{/* Divider */}
|
||||||
|
|||||||
@@ -476,6 +476,7 @@ export class GatewayClient {
|
|||||||
thinking_enabled?: boolean;
|
thinking_enabled?: boolean;
|
||||||
reasoning_effort?: string;
|
reasoning_effort?: string;
|
||||||
plan_mode?: boolean;
|
plan_mode?: boolean;
|
||||||
|
subagent_enabled?: boolean;
|
||||||
}
|
}
|
||||||
): Promise<{ runId: string }> {
|
): Promise<{ runId: string }> {
|
||||||
const agentId = opts?.agentId || this.defaultAgentId;
|
const agentId = opts?.agentId || this.defaultAgentId;
|
||||||
@@ -489,6 +490,7 @@ export class GatewayClient {
|
|||||||
thinking_enabled: opts?.thinking_enabled,
|
thinking_enabled: opts?.thinking_enabled,
|
||||||
reasoning_effort: opts?.reasoning_effort,
|
reasoning_effort: opts?.reasoning_effort,
|
||||||
plan_mode: opts?.plan_mode,
|
plan_mode: opts?.plan_mode,
|
||||||
|
subagent_enabled: opts?.subagent_enabled,
|
||||||
};
|
};
|
||||||
this.fetchDefaultAgentId().then(() => {
|
this.fetchDefaultAgentId().then(() => {
|
||||||
const resolvedAgentId = this.defaultAgentId;
|
const resolvedAgentId = this.defaultAgentId;
|
||||||
@@ -529,6 +531,7 @@ export class GatewayClient {
|
|||||||
thinking_enabled?: boolean;
|
thinking_enabled?: boolean;
|
||||||
reasoning_effort?: string;
|
reasoning_effort?: string;
|
||||||
plan_mode?: boolean;
|
plan_mode?: boolean;
|
||||||
|
subagent_enabled?: boolean;
|
||||||
}
|
}
|
||||||
): void {
|
): void {
|
||||||
// Close existing connection if any
|
// Close existing connection if any
|
||||||
@@ -570,6 +573,9 @@ export class GatewayClient {
|
|||||||
if (chatModeOpts?.plan_mode !== undefined) {
|
if (chatModeOpts?.plan_mode !== undefined) {
|
||||||
chatRequest.plan_mode = chatModeOpts.plan_mode;
|
chatRequest.plan_mode = chatModeOpts.plan_mode;
|
||||||
}
|
}
|
||||||
|
if (chatModeOpts?.subagent_enabled !== undefined) {
|
||||||
|
chatRequest.subagent_enabled = chatModeOpts.subagent_enabled;
|
||||||
|
}
|
||||||
this.zclawWs?.send(JSON.stringify(chatRequest));
|
this.zclawWs?.send(JSON.stringify(chatRequest));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -59,6 +59,7 @@ export function installChatMethods(ClientClass: { prototype: KernelClient }): vo
|
|||||||
thinking_enabled?: boolean;
|
thinking_enabled?: boolean;
|
||||||
reasoning_effort?: string;
|
reasoning_effort?: string;
|
||||||
plan_mode?: boolean;
|
plan_mode?: boolean;
|
||||||
|
subagent_enabled?: boolean;
|
||||||
}
|
}
|
||||||
): Promise<{ runId: string }> {
|
): Promise<{ runId: string }> {
|
||||||
const runId = crypto.randomUUID();
|
const runId = crypto.randomUUID();
|
||||||
@@ -185,6 +186,7 @@ export function installChatMethods(ClientClass: { prototype: KernelClient }): vo
|
|||||||
thinkingEnabled: opts?.thinking_enabled,
|
thinkingEnabled: opts?.thinking_enabled,
|
||||||
reasoningEffort: opts?.reasoning_effort,
|
reasoningEffort: opts?.reasoning_effort,
|
||||||
planMode: opts?.plan_mode,
|
planMode: opts?.plan_mode,
|
||||||
|
subagentEnabled: opts?.subagent_enabled,
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
} catch (err: unknown) {
|
} catch (err: unknown) {
|
||||||
|
|||||||
@@ -403,7 +403,7 @@ export interface KernelClient {
|
|||||||
|
|
||||||
// Chat (kernel-chat.ts)
|
// Chat (kernel-chat.ts)
|
||||||
chat(message: string, opts?: { sessionKey?: string; agentId?: string }): Promise<{ runId: string; sessionId?: string; response?: string }>;
|
chat(message: string, opts?: { sessionKey?: string; agentId?: string }): Promise<{ runId: string; sessionId?: string; response?: string }>;
|
||||||
chatStream(message: string, callbacks: import('./kernel-types').StreamCallbacks, opts?: { sessionKey?: string; agentId?: string; thinking_enabled?: boolean; reasoning_effort?: string; plan_mode?: boolean }): Promise<{ runId: string }>;
|
chatStream(message: string, callbacks: import('./kernel-types').StreamCallbacks, opts?: { sessionKey?: string; agentId?: string; thinking_enabled?: boolean; reasoning_effort?: string; plan_mode?: boolean; subagent_enabled?: boolean }): Promise<{ runId: string }>;
|
||||||
cancelStream(sessionId: string): Promise<void>;
|
cancelStream(sessionId: string): Promise<void>;
|
||||||
fetchDefaultAgentId(): Promise<string | null>;
|
fetchDefaultAgentId(): Promise<string | null>;
|
||||||
setDefaultAgentId(agentId: string): void;
|
setDefaultAgentId(agentId: string): void;
|
||||||
|
|||||||
@@ -108,6 +108,7 @@ export function createSaaSRelayGatewayClient(
|
|||||||
thinking_enabled?: boolean;
|
thinking_enabled?: boolean;
|
||||||
reasoning_effort?: string;
|
reasoning_effort?: string;
|
||||||
plan_mode?: boolean;
|
plan_mode?: boolean;
|
||||||
|
subagent_enabled?: boolean;
|
||||||
},
|
},
|
||||||
): Promise<{ runId: string }> {
|
): Promise<{ runId: string }> {
|
||||||
const runId = `run_${Date.now()}`;
|
const runId = `run_${Date.now()}`;
|
||||||
|
|||||||
@@ -425,6 +425,7 @@ export const useStreamStore = create<StreamState>()(
|
|||||||
thinking_enabled: get().getChatModeConfig().thinking_enabled,
|
thinking_enabled: get().getChatModeConfig().thinking_enabled,
|
||||||
reasoning_effort: get().getChatModeConfig().reasoning_effort,
|
reasoning_effort: get().getChatModeConfig().reasoning_effort,
|
||||||
plan_mode: get().getChatModeConfig().plan_mode,
|
plan_mode: get().getChatModeConfig().plan_mode,
|
||||||
|
subagent_enabled: get().getChatModeConfig().subagent_enabled,
|
||||||
}
|
}
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user