mirror of
https://github.com/getpaseo/paseo.git
synced 2026-10-14 21:32:40 +00:00
Compare commits
1
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
4d08ddba94 |
@@ -88,6 +88,43 @@ describe("useDraftAgentCreateFlow", () => {
|
||||
expect(onCreateSuccess).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("starts one create request when submit is invoked twice before React rerenders", async () => {
|
||||
let resolveCreate: ((value: { agentId: string; result: { id: string } }) => void) | undefined;
|
||||
const createRequest = vi.fn(
|
||||
() =>
|
||||
new Promise<{ agentId: string; result: { id: string } }>((resolve) => {
|
||||
resolveCreate = resolve;
|
||||
}),
|
||||
);
|
||||
const onCreateSuccess = vi.fn();
|
||||
const { result } = renderHook(() =>
|
||||
useDraftAgentCreateFlow({
|
||||
draftId: "draft-1",
|
||||
getPendingServerId: () => "server-1",
|
||||
buildDraftAgent: (attempt) => ({ attempt }),
|
||||
createRequest,
|
||||
onCreateSuccess,
|
||||
}),
|
||||
);
|
||||
const submission = { text: "build this", attachments: [], cwd: "/repo" };
|
||||
|
||||
let first: Promise<void>;
|
||||
let duplicate: Promise<void>;
|
||||
act(() => {
|
||||
first = result.current.handleCreateFromInput(submission);
|
||||
duplicate = result.current.handleCreateFromInput(submission);
|
||||
});
|
||||
|
||||
await expect(duplicate!).rejects.toThrow();
|
||||
expect(createRequest).toHaveBeenCalledTimes(1);
|
||||
|
||||
await act(async () => {
|
||||
resolveCreate?.({ agentId: "agent-1", result: { id: "agent-1" } });
|
||||
await first!;
|
||||
});
|
||||
expect(onCreateSuccess).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
|
||||
it("allows retrying an empty prompt when the draft still has context attachments", async () => {
|
||||
const attachment = {
|
||||
kind: "chat_history",
|
||||
|
||||
@@ -84,6 +84,17 @@ interface CreateRequestContext {
|
||||
cwd: string;
|
||||
}
|
||||
|
||||
function assertCreateAvailable(input: {
|
||||
draftId: string;
|
||||
isSubmitting: boolean;
|
||||
alreadyLoadingMessage: string;
|
||||
}): void {
|
||||
const pending = useCreateFlowStore.getState().pendingByDraftId[input.draftId];
|
||||
if (input.isSubmitting || pending?.lifecycle === "active") {
|
||||
throw new Error(input.alreadyLoadingMessage);
|
||||
}
|
||||
}
|
||||
|
||||
interface UseDraftAgentCreateFlowOptions<TDraftAgent, TCreateResult> {
|
||||
draftId: string;
|
||||
getPendingServerId: () => string | null;
|
||||
@@ -239,9 +250,11 @@ export function useDraftAgentCreateFlow<TDraftAgent, TCreateResult>({
|
||||
|
||||
const handleCreateFromInput = useCallback(
|
||||
async ({ text, attachments, cwd }: SubmitContext) => {
|
||||
if (isSubmitting) {
|
||||
throw new Error(t("composer.errors.alreadyLoading"));
|
||||
}
|
||||
assertCreateAvailable({
|
||||
draftId,
|
||||
isSubmitting,
|
||||
alreadyLoadingMessage: t("composer.errors.alreadyLoading"),
|
||||
});
|
||||
|
||||
dispatch({ type: "DRAFT_SET_ERROR", message: "" });
|
||||
const trimmedPrompt = text.trim();
|
||||
|
||||
Reference in New Issue
Block a user