Files
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

143 lines
4.1 KiB
TypeScript

import {
selectTuttiModeActivationPresentation,
tuttiModeActivationPresentationsEqual,
type AgentSessionEngine,
type TuttiModeActivationPresentation
} from "@tutti-os/agent-activity-core";
import { useCallback, useMemo, useRef } from "react";
import { useEngineSelector } from "../../../shared/engine/useEngineSelector";
interface UseAgentGUITuttiModeActivationInput {
activeConversationId: string | null;
draftKey: string;
engine: AgentSessionEngine;
workspaceId: string;
}
export function resolveAgentGUITuttiModeDraftKey(
nodeId: string | null | undefined
): string {
return `agent-gui:${nodeId?.trim() || "default"}:tutti-mode:home`;
}
export function useAgentGUITuttiModeActivation({
activeConversationId,
draftKey,
engine,
workspaceId
}: UseAgentGUITuttiModeActivationInput) {
const commandSequenceRef = useRef(0);
const presentation = useEngineSelector(
engine,
useCallback(
(state) =>
selectTuttiModeActivationPresentation(
state,
activeConversationId,
draftKey
),
[activeConversationId, draftKey]
),
tuttiModeActivationPresentationsEqual
);
const updatePending = isTuttiModeActivationPending(presentation);
const setActive = useCallback(
(active: boolean): void => {
if (updatePending || presentation.active === active) return;
const agentSessionId = activeConversationId?.trim() ?? "";
if (!agentSessionId) {
engine.dispatch({
active,
draftKey,
occurredAtUnixMs: Date.now(),
type: "tuttiMode/draftSet"
});
return;
}
commandSequenceRef.current += 1;
const requestedAtUnixMs = Date.now();
engine.dispatch({
agentSessionId,
commandId: `tutti-mode:${workspaceId}:${agentSessionId}:${requestedAtUnixMs}:${commandSequenceRef.current}`,
requestedAtUnixMs,
source: active ? "slash_command" : "badge_remove",
status: active ? "active" : "inactive",
type: "tuttiMode/updateRequested",
workspaceId
});
},
[
activeConversationId,
draftKey,
engine,
presentation.active,
updatePending,
workspaceId
]
);
const retry = useCallback((): void => {
if (presentation.updateStatus !== "failed") return;
setActive(!presentation.active);
}, [presentation.active, presentation.updateStatus, setActive]);
const setPreference = useCallback(
(preference: "effect" | "speed", value: number): void => {
const agentSessionId = activeConversationId?.trim() ?? "";
if (!agentSessionId) {
engine.dispatch({
active: true,
draftKey,
occurredAtUnixMs: Date.now(),
[preference]: value,
type: "tuttiMode/draftSet"
});
return;
}
commandSequenceRef.current += 1;
const requestedAtUnixMs = Date.now();
engine.dispatch({
agentSessionId,
commandId: `tutti-mode:${workspaceId}:${agentSessionId}:${requestedAtUnixMs}:${commandSequenceRef.current}`,
[preference]: value,
requestedAtUnixMs,
source: "slash_command",
status: "active",
type: "tuttiMode/updateRequested",
workspaceId
});
},
[activeConversationId, draftKey, engine, workspaceId]
);
const setEffect = useCallback(
(value: number): void => setPreference("effect", value),
[setPreference]
);
const setSpeed = useCallback(
(value: number): void => setPreference("speed", value),
[setPreference]
);
return useMemo(
() => ({
...presentation,
effect: presentation.effect ?? presentation.orchestrationIntensity,
speed: presentation.speed ?? 50,
retry,
setActive,
setEffect,
setSpeed,
updatePending
}),
[presentation, retry, setActive, setEffect, setSpeed, updatePending]
);
}
function isTuttiModeActivationPending(
presentation: TuttiModeActivationPresentation
): boolean {
return (
presentation.updateStatus === "pending_create" ||
presentation.updateStatus === "updating" ||
presentation.updateStatus === "uncertain"
);
}