mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-10-25 09:41:04 +01:00
fix(runner): preserve reasoning through native event translation
Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
1 parent
ab17109a21
commit
768d4e7755
2 files changed
+46
-2
No files matched your search
@@ -2120,6 +2120,33 @@ it("routes canonical session goals back through the Codex notification facade",
|
||||
);
|
||||
});
|
||||
|
||||
it("keeps canonical ACPX reasoning out of assistant deltas", () => {
|
||||
expect(runnerdCanonicalNotificationMethod("item.delta", {
|
||||
kind: "reasoning", channel: "summary", text: "Private reasoning",
|
||||
})).toBe("item/reasoning/summaryTextDelta");
|
||||
expect(runnerdCanonicalNotificationMethod("item.delta", {
|
||||
kind: "reasoning", channel: "detail", text: "Private reasoning",
|
||||
})).toBe("item/reasoning/textDelta");
|
||||
expect(runnerdCanonicalNotificationMethod("item.delta", {
|
||||
kind: "agentMessage", text: "Visible answer",
|
||||
})).toBe("item/agentMessage/delta");
|
||||
});
|
||||
|
||||
it("preserves reasoning kinds and order inside coalesced canonical deltas", () => {
|
||||
const events = [
|
||||
{ kind: "reasoning", channel: "summary", text: "Private reasoning", itemId: "thought-1" },
|
||||
{ kind: "agentMessage", text: "Visible answer", itemId: "answer-1" },
|
||||
{ kind: "reasoning", channel: "detail", text: "Private detail", itemId: "thought-2" },
|
||||
];
|
||||
expect(expandRunnerdCanonicalNotifications("item/agentMessage/delta", {
|
||||
coalescedCount: events.length, events,
|
||||
}, "item.delta")).toEqual([
|
||||
{ method: "item/reasoning/summaryTextDelta", params: events[0] },
|
||||
{ method: "item/agentMessage/delta", params: events[1] },
|
||||
{ method: "item/reasoning/textDelta", params: events[2] },
|
||||
]);
|
||||
});
|
||||
|
||||
it("continues consuming after the durable committed-event window rolls", () => {
|
||||
const rollingWindow = Array.from({ length: 64 }, (_, index) => ({
|
||||
sourceSeq: index + 65,
|
||||
|
||||
@@ -1322,10 +1322,19 @@ export function unseenRunnerdCommittedEvents<
|
||||
export function expandRunnerdCanonicalNotifications(
|
||||
method: string,
|
||||
input: unknown,
|
||||
eventType?: string,
|
||||
): Array<{ method: string; params: Record<string, unknown> }> {
|
||||
const payload = record(input);
|
||||
if (!Array.isArray(payload.events)) return [{ method, params: payload }];
|
||||
return payload.events.map((event) => ({ method, params: record(event) }));
|
||||
return payload.events.map((event) => {
|
||||
const params = record(event);
|
||||
return {
|
||||
method: eventType
|
||||
? runnerdCanonicalNotificationMethod(eventType, params) ?? method
|
||||
: method,
|
||||
params,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
export function runnerdCanonicalNotificationMethod(
|
||||
@@ -1338,6 +1347,14 @@ export function runnerdCanonicalNotificationMethod(
|
||||
if (eventType === "session.goal.snapshot" && payload.goal === null) {
|
||||
return undefined;
|
||||
}
|
||||
// ACPX thoughts retain their reasoning kind through the notification facade.
|
||||
// Treating them as assistant deltas exposes them in the task transcript and
|
||||
// bypasses the existing reasoning redaction and progress handling.
|
||||
if (eventType === "item.delta" && payload.kind === "reasoning") {
|
||||
return payload.channel === "detail"
|
||||
? "item/reasoning/textDelta"
|
||||
: "item/reasoning/summaryTextDelta";
|
||||
}
|
||||
return (
|
||||
{
|
||||
"turn.started": "turn/started",
|
||||
@@ -5961,7 +5978,7 @@ class DurablePrpCodexTransport implements CodexAppServerTransport {
|
||||
: event.eventType === "provider.event"
|
||||
? unwrapRunnerdProviderNotifications(eventPayload)
|
||||
: canonicalMethod
|
||||
? expandRunnerdCanonicalNotifications(canonicalMethod, eventPayload)
|
||||
? expandRunnerdCanonicalNotifications(canonicalMethod, eventPayload, event.eventType)
|
||||
: [];
|
||||
for (const payload of notifications) {
|
||||
const method = payload.method;
|
||||
|
||||
Reference in new issue
Block a user