feat(delegation): 添加直连模式下的委托公告回调机制
- 引入 DirectAnnouncementCallback 类型用于处理直连模式下的公告 - 在 DelegationManager 中添加 _direct_announcement_callback 属性和设置方法 - 实现 _notify_direct_announcement 方法用于在非总线模式下将公告回写到本地会话 - 在委托取消、完成和分组完成时添加对直连公告的通知逻辑 feat(web): 增加 WebSocket 广播器支持实时会话更新通知 - 创建 WebSocketBroadcaster 类用于跟踪认证的 WebSocket 连接并广播 JSON 事件 - 在应用启动时初始化 websocket_broadcaster 实例 - 实现连接注册、注销和消息广播功能 - 添加过期连接清理机制 feat(agent): 新增系统公告处理方法支持本地处理 - 在 AgentLoop 中添加 process_system_announcement 方法用于在无常驻 run() 场景下处理系统公告 - 创建 InboundMessage 并通过 _process_message 进行处理 feat(cron): 改进定时任务的会话路由解析和实时更新 - 添加 _resolve_cron_session_key 和 _infer_cron_route_from_session_key 辅助函数 - 在 cron 任务执行完成后通过 WebSocket 广播会话更新事件 - 在添加定时任务时自动推断目标会话的渠道和聊天 ID refactor: 项目名称从 Boardware Genius 统一改为 Boardware Agent Sandbox - 更新前端页面标题和描述文本中的产品名称 - 添加新的品牌 Logo 图片资源 - 在前端布局中使用新的 Logo 显示 - 更新授权门户中的品牌信息和 Logo 显示 feat(frontend): 添加会话更新事件监听实现消息自动刷新 - 定义 SessionUpdatedEvent 类型接口 - 在 ChatPage 中添加会话更新事件的处理逻辑 - 当收到会话更新事件时自动重新加载会话列表和当前会话消息 feat(api): 扩展定时任务 API 支持会话键参数 - 在 addCronJob API 参数中添加 session_key 字段 - 更新前端 Cron 页面的表单处理以传递当前会话键
This commit is contained in:
@ -39,13 +39,16 @@ import {
|
||||
SelectTrigger,
|
||||
SelectValue,
|
||||
} from '@/components/ui/select';
|
||||
import { useChatStore } from '@/lib/store';
|
||||
import type { CronJob } from '@/types';
|
||||
|
||||
export default function CronPage() {
|
||||
const sessionId = useChatStore((s) => s.sessionId);
|
||||
const [jobs, setJobs] = useState<CronJob[]>([]);
|
||||
const [loading, setLoading] = useState(true);
|
||||
const [error, setError] = useState<string | null>(null);
|
||||
const [showAdd, setShowAdd] = useState(false);
|
||||
const targetSessionKey = sessionId.startsWith('web:') ? sessionId : 'web:default';
|
||||
|
||||
const loadJobs = async () => {
|
||||
setLoading(true);
|
||||
@ -98,7 +101,10 @@ export default function CronPage() {
|
||||
cron_expr?: string;
|
||||
}) => {
|
||||
try {
|
||||
await addCronJob(params);
|
||||
await addCronJob({
|
||||
...params,
|
||||
session_key: targetSessionKey,
|
||||
});
|
||||
setShowAdd(false);
|
||||
loadJobs();
|
||||
} catch (err: any) {
|
||||
@ -157,6 +163,7 @@ export default function CronPage() {
|
||||
{/* Add Job Form */}
|
||||
{showAdd && (
|
||||
<AddJobForm
|
||||
targetSessionKey={targetSessionKey}
|
||||
onAdd={handleAdd}
|
||||
onCancel={() => setShowAdd(false)}
|
||||
/>
|
||||
@ -271,9 +278,11 @@ export default function CronPage() {
|
||||
}
|
||||
|
||||
function AddJobForm({
|
||||
targetSessionKey,
|
||||
onAdd,
|
||||
onCancel,
|
||||
}: {
|
||||
targetSessionKey: string;
|
||||
onAdd: (params: {
|
||||
name: string;
|
||||
message: string;
|
||||
@ -382,6 +391,9 @@ function AddJobForm({
|
||||
onChange={(e) => setMessage(e.target.value)}
|
||||
placeholder="例如:检查我的邮件并生成摘要"
|
||||
/>
|
||||
<p className="text-xs text-muted-foreground">
|
||||
任务结果会自动回写到当前 Web 会话:<code className="bg-muted px-1 py-0.5 rounded">{targetSessionKey}</code>
|
||||
</p>
|
||||
</div>
|
||||
|
||||
<div className="flex justify-end gap-2">
|
||||
|
||||
@ -61,7 +61,7 @@ export default function HelpPage() {
|
||||
<div className="max-w-2xl mx-auto px-4 py-8 space-y-4">
|
||||
<div className="mb-6">
|
||||
<h1 className="text-2xl font-bold mb-1">使用帮助</h1>
|
||||
<p className="text-muted-foreground text-sm">了解如何使用 Boardware Genius 的各项功能</p>
|
||||
<p className="text-muted-foreground text-sm">了解如何使用 Boardware Agent Sandbox 的各项功能</p>
|
||||
</div>
|
||||
|
||||
<Section icon={<MessageSquare className="w-5 h-5" />} title="如何开始对话" defaultOpen>
|
||||
@ -69,7 +69,7 @@ export default function HelpPage() {
|
||||
<ol className="list-decimal list-inside space-y-1.5 ml-1">
|
||||
<li>在底部输入框中输入你的问题或指令</li>
|
||||
<li>按 <Tag>Enter</Tag> 发送,按 <Tag>Shift + Enter</Tag> 换行</li>
|
||||
<li>等待 Boardware Genius 回复(右上角会显示"思考中...")</li>
|
||||
<li>等待 Boardware Agent Sandbox 回复(右上角会显示"思考中...")</li>
|
||||
</ol>
|
||||
<p className="mt-1">
|
||||
点击左上角的 <Tag>新对话</Tag> 按钮可以开启一个全新的对话,历史对话会保存在左侧列表中。
|
||||
@ -111,7 +111,7 @@ export default function HelpPage() {
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="w-2 h-2 rounded-full bg-green-500 flex-shrink-0" />
|
||||
<Tag color="green">已连接</Tag>
|
||||
<span>— Boardware Genius 服务正常运行,可以正常对话</span>
|
||||
<span>— Boardware Agent Sandbox 服务正常运行,可以正常对话</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="w-2 h-2 rounded-full bg-yellow-500 flex-shrink-0" />
|
||||
@ -121,7 +121,7 @@ export default function HelpPage() {
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="w-2 h-2 rounded-full bg-red-500 flex-shrink-0" />
|
||||
<Tag color="red">服务离线</Tag>
|
||||
<span>— 已连到后端接口,但 Boardware Genius 服务当前不可用</span>
|
||||
<span>— 已连到后端接口,但 Boardware Agent Sandbox 服务当前不可用</span>
|
||||
</div>
|
||||
<div className="flex items-center gap-2">
|
||||
<span className="w-2 h-2 rounded-full bg-red-500 flex-shrink-0" />
|
||||
@ -150,7 +150,7 @@ export default function HelpPage() {
|
||||
<p>请检查右上角连接状态是否为"已连接"。若显示"服务离线"或"未连接",说明后端服务未运行,消息无法被处理。</p>
|
||||
</div>
|
||||
<div>
|
||||
<p className="font-medium text-foreground mb-1">Q:如何查看 Boardware Genius 的运行状态?</p>
|
||||
<p className="font-medium text-foreground mb-1">Q:如何查看 Boardware Agent Sandbox 的运行状态?</p>
|
||||
<p>点击顶部导航栏的<strong className="text-foreground">状态</strong>页面,可以查看服务配置、AI 模型、各通道和定时任务的运行状况。</p>
|
||||
</div>
|
||||
<div>
|
||||
@ -159,7 +159,7 @@ export default function HelpPage() {
|
||||
</div>
|
||||
<div>
|
||||
<p className="font-medium text-foreground mb-1">Q:什么是技能和插件?</p>
|
||||
<p><strong className="text-foreground">技能</strong>是可上传的自定义提示词包,扩展 Boardware Genius 的能力范围。<strong className="text-foreground">插件</strong>是更完整的功能扩展,可以提供新的斜杠命令、专用 Agent 等。</p>
|
||||
<p><strong className="text-foreground">技能</strong>是可上传的自定义提示词包,扩展 Boardware Agent Sandbox 的能力范围。<strong className="text-foreground">插件</strong>是更完整的功能扩展,可以提供新的斜杠命令、专用 Agent 等。</p>
|
||||
</div>
|
||||
</div>
|
||||
</Section>
|
||||
|
||||
@ -20,7 +20,7 @@ import {
|
||||
wsManager,
|
||||
} from '@/lib/api';
|
||||
import { useChatStore } from '@/lib/store';
|
||||
import type { ChatMessage, FileAttachment, ProcessWsEvent, SlashCommand, WsEvent } from '@/types';
|
||||
import type { ChatMessage, FileAttachment, ProcessWsEvent, SessionUpdatedEvent, SlashCommand, WsEvent } from '@/types';
|
||||
|
||||
function scheduleWhenIdle(task: () => void, timeout = 1200): () => void {
|
||||
if (typeof window === 'undefined') {
|
||||
@ -78,6 +78,10 @@ function isProcessEvent(data: WsEvent | Record<string, unknown>): data is Proces
|
||||
return type.startsWith('process_') || type === 'process_cancel_ack';
|
||||
}
|
||||
|
||||
function isSessionUpdatedEvent(data: WsEvent | Record<string, unknown>): data is SessionUpdatedEvent {
|
||||
return data.type === 'session_updated' && typeof data.session_id === 'string';
|
||||
}
|
||||
|
||||
export default function ChatPage() {
|
||||
const {
|
||||
sessionId,
|
||||
@ -235,6 +239,14 @@ export default function ChatPage() {
|
||||
});
|
||||
|
||||
const unsubMessage = wsManager.onMessage((data) => {
|
||||
if (isSessionUpdatedEvent(data)) {
|
||||
void loadSessions();
|
||||
if (data.session_id === useChatStore.getState().sessionId) {
|
||||
void loadSessionMessages(data.session_id);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
if (isProcessEvent(data)) {
|
||||
ingestProcessEvent(data);
|
||||
return;
|
||||
|
||||
@ -92,7 +92,7 @@ export default function PluginsPage() {
|
||||
<p className="font-medium">还没有安装任何插件</p>
|
||||
<p className="text-sm mt-2 max-w-sm mx-auto">
|
||||
把插件目录放到 <code className="text-xs bg-muted px-1 py-0.5 rounded">~/.nanobot/plugins/</code>,
|
||||
然后重启 Boardware Genius。
|
||||
然后重启 Boardware Agent Sandbox。
|
||||
</p>
|
||||
</CardContent>
|
||||
</Card>
|
||||
|
||||
@ -57,7 +57,7 @@ export default function StatusPage() {
|
||||
<div className="flex items-center gap-3 text-destructive">
|
||||
<AlertCircle className="w-5 h-5" />
|
||||
<div>
|
||||
<p className="font-medium">无法连接到 Boardware Genius 后端</p>
|
||||
<p className="font-medium">无法连接到 Boardware Agent Sandbox 后端</p>
|
||||
<p className="text-sm text-muted-foreground mt-1">{error}</p>
|
||||
<p className="text-sm text-muted-foreground mt-1">
|
||||
请确认后端已启动:<code className="bg-muted px-1 rounded">nanobot web</code>
|
||||
|
||||
@ -2,8 +2,11 @@ import './globals.css';
|
||||
import type { Metadata } from 'next';
|
||||
|
||||
export const metadata: Metadata = {
|
||||
title: 'Boardware Genius',
|
||||
title: 'Boardware Agent Sandbox',
|
||||
description: '个人 AI 助手',
|
||||
icons: {
|
||||
icon: '/boardware-logo.svg',
|
||||
},
|
||||
};
|
||||
|
||||
export default function RootLayout({
|
||||
|
||||
Reference in New Issue
Block a user