mirror of
https://github.com/cline/cline.git
synced 2026-10-24 12:03:46 +08:00
fix(hub): forward discarded pending prompts to hub clients
The pending_prompts snapshot that empties a queue on teardown carries
the removed entries in a `discarded` field so a subscribed client can
offer the text back, but both ends of the hub boundary rebuilt the
payload as { sessionId, prompts }: the session event projector when
publishing session.pending_prompts, and HubRuntimeHost when turning it
back into a core event. No hub client and nothing behind HubRuntimeHost
ever saw the field. Both now pass it through when present.
This commit is contained in:
@@ -187,6 +187,81 @@ describe("HubRuntimeHost", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("carries discarded pending prompts across the hub boundary", async () => {
|
||||
let onEvent: ((event: HubEventEnvelope) => void) | undefined;
|
||||
subscribeMock.mockImplementation((listener) => {
|
||||
onEvent = listener;
|
||||
return () => {};
|
||||
});
|
||||
commandMock.mockResolvedValue({
|
||||
payload: {
|
||||
session: {
|
||||
sessionId: "sess-1",
|
||||
status: "running",
|
||||
createdAt: Date.now(),
|
||||
updatedAt: Date.now(),
|
||||
workspaceRoot: "/tmp/project",
|
||||
cwd: "/tmp/project",
|
||||
},
|
||||
},
|
||||
});
|
||||
const events: unknown[] = [];
|
||||
const { HubRuntimeHost } = await import("./hub-runtime-host");
|
||||
const host = new HubRuntimeHost({ url: "ws://127.0.0.1:25463/hub" });
|
||||
host.subscribe((event) => events.push(event));
|
||||
await host.startSession({
|
||||
config: createConfig(),
|
||||
source: SessionSource.CLI,
|
||||
prompt: "Hey",
|
||||
});
|
||||
const ctx = {
|
||||
sessionHost: {
|
||||
getAccumulatedUsage: vi.fn().mockResolvedValue(undefined),
|
||||
},
|
||||
buildEvent: vi.fn<HubTransportContext["buildEvent"]>(
|
||||
(event, payload, sessionId) => ({
|
||||
version: "v1",
|
||||
event,
|
||||
payload,
|
||||
sessionId,
|
||||
}),
|
||||
),
|
||||
publish: (event: HubEventEnvelope) => {
|
||||
onEvent?.(JSON.parse(JSON.stringify(event)));
|
||||
},
|
||||
} as unknown as HubTransportContext;
|
||||
const discarded = [
|
||||
{
|
||||
id: "pending-1",
|
||||
prompt: "typed before the task was closed",
|
||||
delivery: "queue" as const,
|
||||
attachmentCount: 0,
|
||||
},
|
||||
];
|
||||
// The snapshot that empties the queue on teardown must still tell a
|
||||
// hub client what was removed, or it cannot offer the text back.
|
||||
await projectSessionEvent(ctx, {
|
||||
type: "pending_prompts",
|
||||
payload: { sessionId: "sess-1", prompts: [], discarded },
|
||||
});
|
||||
await projectSessionEvent(ctx, {
|
||||
type: "pending_prompts",
|
||||
payload: { sessionId: "sess-1", prompts: [] },
|
||||
});
|
||||
expect(events).toEqual(
|
||||
expect.arrayContaining([
|
||||
{
|
||||
type: "pending_prompts",
|
||||
payload: { sessionId: "sess-1", prompts: [], discarded },
|
||||
},
|
||||
{
|
||||
type: "pending_prompts",
|
||||
payload: { sessionId: "sess-1", prompts: [] },
|
||||
},
|
||||
]),
|
||||
);
|
||||
});
|
||||
|
||||
it("reconstructs tool content updates from hub events", async () => {
|
||||
let onEvent: ((event: HubEventEnvelope) => void) | undefined;
|
||||
subscribeMock.mockImplementation((listener) => {
|
||||
|
||||
@@ -2008,6 +2008,9 @@ export class HubRuntimeHost implements RuntimeHost {
|
||||
return;
|
||||
}
|
||||
case "session.pending_prompts": {
|
||||
const discarded = Array.isArray(event.payload?.discarded)
|
||||
? (event.payload.discarded as SessionPendingPrompt[])
|
||||
: [];
|
||||
this.events.emit({
|
||||
type: "pending_prompts",
|
||||
payload: {
|
||||
@@ -2015,6 +2018,7 @@ export class HubRuntimeHost implements RuntimeHost {
|
||||
prompts: Array.isArray(event.payload?.prompts)
|
||||
? (event.payload.prompts as SessionPendingPrompt[])
|
||||
: [],
|
||||
...(discarded.length ? { discarded } : {}),
|
||||
},
|
||||
});
|
||||
return;
|
||||
|
||||
@@ -71,6 +71,9 @@ export async function projectSessionEvent(
|
||||
{
|
||||
sessionId: event.payload.sessionId,
|
||||
prompts: event.payload.prompts,
|
||||
...(event.payload.discarded?.length
|
||||
? { discarded: event.payload.discarded }
|
||||
: {}),
|
||||
},
|
||||
event.payload.sessionId,
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user