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
199 lines
6.1 KiB
TypeScript
199 lines
6.1 KiB
TypeScript
import {
|
|
useCallback,
|
|
type Dispatch,
|
|
type RefObject,
|
|
type SetStateAction
|
|
} from "react";
|
|
import {
|
|
selectEngineQueuedPrompt,
|
|
type AgentSessionEngine
|
|
} from "@tutti-os/agent-activity-core";
|
|
import type { AgentGUIRuntime } from "../../../agentActivityRuntime";
|
|
import type { AgentComposerDraft } from "../model/agentGuiNodeTypes";
|
|
import {
|
|
agentComposerDraftImages,
|
|
agentPromptContentToComposerDraft,
|
|
updateAgentComposerDraft
|
|
} from "../model/agentComposerDraft";
|
|
import { resolveAgentComposerDraftScopeKey } from "../model/agentComposerDraftScope";
|
|
import { QueuedPromptImageLoadOwner } from "../queuedPromptImageLoadOwner";
|
|
import { createAgentGUIConversationId } from "./agentGuiController.promptHelpers";
|
|
|
|
export interface UseAgentGUIQueueActionsInput {
|
|
activeConversationIdRef: RefObject<string | null>;
|
|
agentActivityRuntime: AgentGUIRuntime;
|
|
sessionEngine: AgentSessionEngine;
|
|
setDraftByScopeKey: Dispatch<
|
|
SetStateAction<Record<string, AgentComposerDraft>>
|
|
>;
|
|
workspaceId: string;
|
|
}
|
|
|
|
/** Owns queued-prompt mutations without coupling them to session activation. */
|
|
export function useAgentGUIQueueActions({
|
|
activeConversationIdRef,
|
|
agentActivityRuntime,
|
|
sessionEngine,
|
|
setDraftByScopeKey,
|
|
workspaceId
|
|
}: UseAgentGUIQueueActionsInput) {
|
|
const removeQueuedPrompt = useCallback(
|
|
(queuedPromptId: string) => {
|
|
const agentSessionId = activeConversationIdRef.current;
|
|
const normalizedQueuedPromptId = queuedPromptId.trim();
|
|
if (!agentSessionId || !normalizedQueuedPromptId) {
|
|
return;
|
|
}
|
|
const queuedPrompt = selectEngineQueuedPrompt(
|
|
sessionEngine.getSnapshot(),
|
|
agentSessionId,
|
|
normalizedQueuedPromptId
|
|
);
|
|
sessionEngine.dispatch(
|
|
queuedPrompt?.clientSubmitId
|
|
? {
|
|
agentSessionId,
|
|
clientSubmitId: queuedPrompt.clientSubmitId,
|
|
type: "submit/canceled"
|
|
}
|
|
: {
|
|
agentSessionId,
|
|
promptId: normalizedQueuedPromptId,
|
|
type: "queue/removed"
|
|
}
|
|
);
|
|
},
|
|
[activeConversationIdRef, sessionEngine]
|
|
);
|
|
|
|
const editQueuedPrompt = useCallback(
|
|
(queuedPromptId: string) => {
|
|
const agentSessionId = activeConversationIdRef.current;
|
|
const normalizedQueuedPromptId = queuedPromptId.trim();
|
|
if (!agentSessionId || !normalizedQueuedPromptId) {
|
|
return;
|
|
}
|
|
const queuedPrompt = selectEngineQueuedPrompt(
|
|
sessionEngine.getSnapshot(),
|
|
agentSessionId,
|
|
normalizedQueuedPromptId
|
|
);
|
|
if (!queuedPrompt) {
|
|
return;
|
|
}
|
|
const draftScopeKey = resolveAgentComposerDraftScopeKey({
|
|
agentSessionId
|
|
});
|
|
const restoredDraft = agentPromptContentToComposerDraft(
|
|
queuedPrompt.content,
|
|
`restore-${queuedPrompt.id}`
|
|
);
|
|
sessionEngine.dispatch(
|
|
queuedPrompt.clientSubmitId
|
|
? {
|
|
agentSessionId,
|
|
clientSubmitId: queuedPrompt.clientSubmitId,
|
|
type: "submit/canceled"
|
|
}
|
|
: {
|
|
agentSessionId,
|
|
promptId: normalizedQueuedPromptId,
|
|
type: "queue/removed"
|
|
}
|
|
);
|
|
setDraftByScopeKey((current) => ({
|
|
...current,
|
|
[draftScopeKey]: restoredDraft
|
|
}));
|
|
for (const restoredImage of agentComposerDraftImages(restoredDraft)) {
|
|
const attachmentId = restoredImage.attachmentId?.trim() ?? "";
|
|
const path = restoredImage.path?.trim() ?? "";
|
|
if (restoredImage.previewUrl || (!attachmentId && !path)) {
|
|
continue;
|
|
}
|
|
const owner = new QueuedPromptImageLoadOwner(
|
|
{
|
|
agentSessionId,
|
|
attachmentId,
|
|
imageKey: restoredImage.id,
|
|
mimeType: restoredImage.mimeType,
|
|
name: restoredImage.name,
|
|
path,
|
|
remoteUrl: restoredImage.url?.trim() ?? "",
|
|
runtime: agentActivityRuntime,
|
|
workspaceId
|
|
},
|
|
(source) => {
|
|
if (!source) {
|
|
return;
|
|
}
|
|
setDraftByScopeKey((current) => {
|
|
const currentDraft = current[draftScopeKey];
|
|
if (!currentDraft) {
|
|
return current;
|
|
}
|
|
let updated = false;
|
|
const images = agentComposerDraftImages(currentDraft).map(
|
|
(currentImage) => {
|
|
if (
|
|
currentImage.id !== restoredImage.id ||
|
|
currentImage.previewUrl ||
|
|
currentImage.attachmentId !== restoredImage.attachmentId ||
|
|
currentImage.path !== restoredImage.path ||
|
|
currentImage.url !== restoredImage.url
|
|
) {
|
|
return currentImage;
|
|
}
|
|
updated = true;
|
|
return { ...currentImage, previewUrl: source };
|
|
}
|
|
);
|
|
return updated
|
|
? {
|
|
...current,
|
|
[draftScopeKey]: updateAgentComposerDraft(currentDraft, {
|
|
images
|
|
})
|
|
}
|
|
: current;
|
|
});
|
|
}
|
|
);
|
|
owner.start();
|
|
}
|
|
},
|
|
[
|
|
activeConversationIdRef,
|
|
agentActivityRuntime,
|
|
sessionEngine,
|
|
setDraftByScopeKey,
|
|
workspaceId
|
|
]
|
|
);
|
|
|
|
const sendQueuedPromptNext = useCallback(
|
|
(queuedPromptId: string) => {
|
|
const agentSessionId = activeConversationIdRef.current;
|
|
const normalizedQueuedPromptId = queuedPromptId.trim();
|
|
if (!agentSessionId || !normalizedQueuedPromptId) {
|
|
return;
|
|
}
|
|
sessionEngine.dispatch({
|
|
agentSessionId,
|
|
awaitingTurnExpiresAtUnixMs: Date.now() + 30_000,
|
|
cancelCommandId: createAgentGUIConversationId(),
|
|
promptId: normalizedQueuedPromptId,
|
|
timeoutMs: 30_000,
|
|
type: "queue/sendNowRequested"
|
|
});
|
|
},
|
|
[activeConversationIdRef, sessionEngine]
|
|
);
|
|
|
|
return {
|
|
editQueuedPrompt,
|
|
removeQueuedPrompt,
|
|
sendQueuedPromptNext
|
|
};
|
|
}
|