mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-29 04:25:52 +01:00
fix(dot): preserve completion and admission receipts
Normalize accepted completion reports across the control plane and Rust bridge, serialize Dot assignments, replay work admission receipts, and continue subscription polling. Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
ad1ff9b329
commit
78f4c4f5e6
8 files changed
+227
-30
No files matched your search
@@ -75,3 +75,18 @@ it("keeps a revoked binding cleared when the follow-up connection read fails", a
|
||||
expect(client.getQueryData(["dot-binding", "company", "agent"])).toMatchObject({ binding: null });
|
||||
expect(Array.from(container.querySelectorAll("button")).some(button => button.textContent === "Revoke connection")).toBe(false);
|
||||
});
|
||||
|
||||
it("shows event testing when a connected Dot subscribes without a manual refresh", async () => {
|
||||
api.get.mockResolvedValue({ enabled: true, resourceUrl: "https://paperclip.example/mcp/runner", binding: { ...binding, subscriptionVerified: false } });
|
||||
vi.useFakeTimers();
|
||||
try {
|
||||
await act(async () => root.render(<QueryClientProvider client={client}><Form /></QueryClientProvider>));
|
||||
await act(async () => { await vi.advanceTimersByTimeAsync(20); });
|
||||
expect(container.textContent).toContain("Event subscription: required");
|
||||
expect(container.textContent).not.toContain("Test event delivery");
|
||||
api.get.mockResolvedValue({ enabled: true, resourceUrl: "https://paperclip.example/mcp/runner", binding });
|
||||
await act(async () => { await vi.advanceTimersByTimeAsync(5020); });
|
||||
expect(container.textContent).toContain("Test event delivery");
|
||||
expect(container.textContent).toContain("Event subscription: verified");
|
||||
} finally { vi.useRealTimers(); }
|
||||
});
|
||||
@@ -20,7 +20,9 @@ export function DotRunnerConnection({ companyId, agentId, bindingId, onBinding }
|
||||
const key = ["dot-binding", companyId, agentId];
|
||||
const state = useQuery({ queryKey: key, enabled: !!companyId && !!agentId,
|
||||
queryFn: () => api.get<Connection>(path),
|
||||
refetchInterval: query => query.state.data?.binding?.status === "pairing" || query.state.data?.binding?.hasPendingChallenge || query.state.data?.binding?.assignment ? 5000 : false });
|
||||
refetchInterval: query => query.state.data?.binding?.status === "pairing" ||
|
||||
(query.state.data?.binding?.connected && !query.state.data.binding.subscriptionVerified) ||
|
||||
query.state.data?.binding?.hasPendingChallenge || query.state.data?.binding?.assignment ? 5000 : false });
|
||||
const pair = useMutation({ mutationFn: () => api.post<{ bindingId: string; pairingCode: string; expiresAt: string }>(path, {}),
|
||||
onSuccess: result => { setPairing(result); onBinding(result.bindingId); void client.invalidateQueries({ queryKey: key }); } });
|
||||
const test = useMutation({ mutationFn: () => api.post(path + "/event-test", {}),
|
||||
|
||||
Reference in new issue
Block a user