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
92 lines
2.7 KiB
TypeScript
92 lines
2.7 KiB
TypeScript
import { useCallback, useMemo } from "react";
|
|
import {
|
|
editRetryPresentationRecordsEqual,
|
|
dispatchEditRetry,
|
|
dispatchEditRetryRecovery,
|
|
selectEditRetryPresentation,
|
|
type AgentActivityEditRetryRecoveryAction
|
|
} from "@tutti-os/agent-activity-core";
|
|
import { useAgentGUIRuntime } from "../../../agentActivityRuntime";
|
|
import { useEngineSelector } from "../../../shared/engine/useEngineSelector";
|
|
import { projectAgentGUIEditRetryPresentation } from "../model/agentGUIEditRetryModel";
|
|
|
|
export function useAgentGUIEditRetryController(input: {
|
|
agentSessionId: string | null;
|
|
workspaceId: string;
|
|
}) {
|
|
const runtime = useAgentGUIRuntime();
|
|
const sessionEngine = runtime.getSessionEngine(input.workspaceId);
|
|
const record = useEngineSelector(
|
|
sessionEngine,
|
|
(state) => selectEditRetryPresentation(state, input.agentSessionId),
|
|
editRetryPresentationRecordsEqual
|
|
);
|
|
|
|
const submit = useCallback(
|
|
async (request: { editedText: string; turnId: string }) => {
|
|
const agentSessionId = input.agentSessionId?.trim() ?? "";
|
|
if (
|
|
!agentSessionId ||
|
|
record.availability?.eligible !== true ||
|
|
record.availability.turnId !== request.turnId
|
|
) {
|
|
return false;
|
|
}
|
|
try {
|
|
await dispatchEditRetry(sessionEngine, {
|
|
agentSessionId,
|
|
editedText: request.editedText,
|
|
turnId: request.turnId,
|
|
workspaceId: input.workspaceId
|
|
});
|
|
return true;
|
|
} catch {
|
|
// The engine retains the typed failure/recovery state. Returning false
|
|
// keeps the editor draft available without leaking a rejected UI event.
|
|
return false;
|
|
}
|
|
},
|
|
[
|
|
input.agentSessionId,
|
|
input.workspaceId,
|
|
record.availability,
|
|
sessionEngine
|
|
]
|
|
);
|
|
|
|
const recover = useCallback(
|
|
async (action: AgentActivityEditRetryRecoveryAction) => {
|
|
const agentSessionId = input.agentSessionId?.trim() ?? "";
|
|
if (
|
|
!agentSessionId ||
|
|
!record.availability?.operationId ||
|
|
!record.availability.availableActions.includes(action)
|
|
) {
|
|
throw new Error("agent_edit_retry_recovery_unavailable");
|
|
}
|
|
await dispatchEditRetryRecovery(sessionEngine, {
|
|
action,
|
|
agentSessionId,
|
|
workspaceId: input.workspaceId
|
|
});
|
|
},
|
|
[
|
|
input.agentSessionId,
|
|
input.workspaceId,
|
|
record.availability,
|
|
sessionEngine
|
|
]
|
|
);
|
|
|
|
const presentation = useMemo(
|
|
() =>
|
|
projectAgentGUIEditRetryPresentation({
|
|
availability: record.availability,
|
|
commandStatus: record.operation.status
|
|
}),
|
|
[record.availability, record.operation.status]
|
|
);
|
|
|
|
return { presentation, recover, submit };
|
|
}
|