源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
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
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
This commit is contained in:
+142
@@ -0,0 +1,142 @@
|
||||
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"
|
||||
);
|
||||
}
|
||||
Reference in New Issue
Block a user