feat(remote-control): 优化 Web 展示、状态同步与桥接控制流程 (#288)

Co-authored-by: chengzifeng <chengzifeng@meituan.com>
This commit is contained in:
Cheng Zi Feng
2026-04-17 16:21:27 +08:00
committed by GitHub
parent b5c299f5d2
commit 72a2093cd6
64 changed files with 4138 additions and 312 deletions

View File

@@ -207,6 +207,7 @@ const getCoordinatorUserContext: (
/* eslint-enable custom-rules/no-process-env-top-level, @typescript-eslint/no-require-imports */
import useCanUseTool from '../hooks/useCanUseTool.js';
import type { ToolPermissionContext, Tool } from '../Tool.js';
import { notifyAutomationStateChanged } from '../utils/sessionState.js';
import {
applyPermissionUpdate,
applyPermissionUpdates,
@@ -341,6 +342,7 @@ import { useInboxPoller } from '../hooks/useInboxPoller.js';
const proactiveModule = feature('PROACTIVE') || feature('KAIROS') ? require('../proactive/index.js') : null;
const PROACTIVE_NO_OP_SUBSCRIBE = (_cb: () => void) => () => {};
const PROACTIVE_FALSE = () => false;
const PROACTIVE_NULL = (): number | null => null;
const SUGGEST_BG_PR_NOOP = (_p: string, _n: string): boolean => false;
const useProactive =
feature('PROACTIVE') || feature('KAIROS') ? require('../proactive/useProactive.js').useProactive : null;
@@ -928,6 +930,10 @@ export function REPL({
proactiveModule?.subscribeToProactiveChanges ?? PROACTIVE_NO_OP_SUBSCRIBE,
proactiveModule?.isProactiveActive ?? PROACTIVE_FALSE,
);
const proactiveNextTickAt = React.useSyncExternalStore<number | null>(
proactiveModule?.subscribeToProactiveChanges ?? PROACTIVE_NO_OP_SUBSCRIBE,
proactiveModule?.getNextTickAt ?? PROACTIVE_NULL,
);
// BriefTool.isEnabled() reads getUserMsgOptIn() from bootstrap state, which
// /brief flips mid-session alongside isBriefOnly. The memo below needs a
@@ -4944,6 +4950,48 @@ export function REPL({
onQueueTick: (command: QueuedCommand) => enqueue(command),
});
useEffect(() => {
if (!proactiveActive) {
notifyAutomationStateChanged(null);
return;
}
if (isLoading) {
return;
}
if (
proactiveNextTickAt !== null &&
queuedCommands.length === 0 &&
!isShowingLocalJSXCommand &&
toolPermissionContext.mode !== 'plan' &&
initialMessage === null
) {
notifyAutomationStateChanged({
enabled: true,
phase: 'standby',
next_tick_at: proactiveNextTickAt,
sleep_until: null,
});
return;
}
notifyAutomationStateChanged({
enabled: true,
phase: null,
next_tick_at: null,
sleep_until: null,
});
}, [
initialMessage,
isLoading,
isShowingLocalJSXCommand,
proactiveActive,
proactiveNextTickAt,
queuedCommands.length,
toolPermissionContext.mode,
]);
// Abort the current operation when a 'now' priority message arrives
// (e.g. from a chat UI client via UDS).
useEffect(() => {