mirror of
https://github.com/getpaseo/paseo.git
synced 2026-07-29 12:01:31 +00:00
fix(sync): replay live deltas after refresh failures
This commit is contained in:
@@ -593,7 +593,10 @@ function SessionProviderInternal({ children, serverId, client }: SessionProvider
|
||||
isCurrent: () => workspaceHydrationRef.current?.id === transaction.id,
|
||||
});
|
||||
} catch (error) {
|
||||
if (workspaceHydrationRef.current === transaction) workspaceHydrationRef.current = null;
|
||||
if (workspaceHydrationRef.current === transaction) {
|
||||
workspaceHydrationRef.current = null;
|
||||
for (const delta of transaction.deltas) applyWorkspaceUpdatePayload(delta);
|
||||
}
|
||||
throw error;
|
||||
}
|
||||
if (!snapshot || options?.isCancelled?.()) {
|
||||
|
||||
@@ -2289,6 +2289,14 @@ export class HostRuntimeStore {
|
||||
});
|
||||
} catch (error) {
|
||||
if (!(error instanceof AgentDirectoryRefreshSupersededError)) {
|
||||
if (
|
||||
this.agentDirectoryTransactions.get(input.serverId)?.id === transaction.id &&
|
||||
hasMatchingSession()
|
||||
) {
|
||||
for (const delta of transaction.deltas) {
|
||||
this.applyAgentDirectoryDelta(input.serverId, delta);
|
||||
}
|
||||
}
|
||||
controller.markAgentDirectorySyncError(toErrorMessage(error));
|
||||
}
|
||||
throw error;
|
||||
|
||||
@@ -6,6 +6,7 @@ import pino from "pino";
|
||||
import { afterEach, describe, expect, test, vi } from "vitest";
|
||||
|
||||
import { PARENT_AGENT_ID_LABEL } from "@getpaseo/protocol/agent-labels";
|
||||
import { CLIENT_CAPS } from "@getpaseo/protocol/client-capabilities";
|
||||
import type { WorkspaceDescriptorPayload } from "@getpaseo/protocol/messages";
|
||||
import {
|
||||
decodeFileTransferFrame,
|
||||
@@ -4247,6 +4248,8 @@ test("unions viewed timelines across socket sources and removes detached sources
|
||||
|
||||
const legacySocket = {};
|
||||
session.updateClientCapabilities(null, legacySocket);
|
||||
expect(session.supportsForSource(CLIENT_CAPS.selectiveAgentTimeline, legacySocket)).toBe(false);
|
||||
expect(session.supportsForSource(CLIENT_CAPS.selectiveAgentTimeline, firstSocket)).toBe(true);
|
||||
messages.length = 0;
|
||||
forward({
|
||||
type: "agent_stream",
|
||||
|
||||
@@ -976,6 +976,13 @@ export class Session {
|
||||
return this.clientCapabilities.has(capability);
|
||||
}
|
||||
|
||||
supportsForSource(capability: ClientCapability, source: object): boolean {
|
||||
if (capability === CLIENT_CAPS.selectiveAgentTimeline) {
|
||||
return this.selectiveTimelineCapabilityBySource.get(source) ?? this.supports(capability);
|
||||
}
|
||||
return this.supports(capability);
|
||||
}
|
||||
|
||||
async syncWorkspaceGitObserverForWorkspace(workspace: PersistedWorkspaceRecord): Promise<void> {
|
||||
await this.workspaceGitObserver.syncObserverForWorkspace(workspace);
|
||||
}
|
||||
|
||||
@@ -2010,7 +2010,7 @@ export class VoiceAssistantWebSocketServer {
|
||||
notification,
|
||||
};
|
||||
const message = wrapSessionMessage(
|
||||
connection?.session.supports(CLIENT_CAPS.selectiveAgentTimeline)
|
||||
connection?.session.supportsForSource(CLIENT_CAPS.selectiveAgentTimeline, ws)
|
||||
? {
|
||||
type: "agent_attention_required",
|
||||
payload: attentionPayload,
|
||||
|
||||
Reference in New Issue
Block a user