mirror of
https://github.com/paperclipai/paperclip.git
synced 2026-11-04 02:32:07 +01:00
Project Runner PRP events into task chat
This commit is contained in:
1 parent
00b9012a28
commit
d2c709ed19
6 files changed
+83
-5
No files matched your search
@@ -0,0 +1,23 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { paperclipRunnerUIAdapter } from "./index";
|
||||
|
||||
describe("paperclip runner transcript projection", () => {
|
||||
it("renders committed PRP semantic tool items with the existing chat parts", () => {
|
||||
const started = paperclipRunnerUIAdapter.parseStdoutLine(JSON.stringify({
|
||||
type: "paperclip.prp.event",
|
||||
event: {
|
||||
eventType: "item.started",
|
||||
payload: { item: { type: "tool_use", id: "call-1", name: "get_task_context", input: {} } },
|
||||
},
|
||||
}), "2026-08-21T12:00:00.000Z");
|
||||
const completed = paperclipRunnerUIAdapter.parseStdoutLine(JSON.stringify({
|
||||
type: "paperclip.prp.event",
|
||||
event: {
|
||||
eventType: "item.completed",
|
||||
payload: { item: { type: "tool_result", id: "call-1", tool_use_id: "call-1", result: { ok: true } } },
|
||||
},
|
||||
}), "2026-08-21T12:00:01.000Z");
|
||||
expect(started).toEqual([expect.objectContaining({ kind: "tool_call", name: "get_task_context", toolUseId: "call-1" })]);
|
||||
expect(completed).toEqual([expect.objectContaining({ kind: "tool_result", toolUseId: "call-1", isError: false })]);
|
||||
});
|
||||
});
|
||||
@@ -2,10 +2,40 @@ import type { UIAdapterModule } from "../types";
|
||||
import { parseCodexStdoutLine, buildPaperclipRunnerConfig } from "@paperclipai/adapter-codex-local/ui";
|
||||
import { CodexLocalConfigFields } from "../codex-local/config-fields";
|
||||
|
||||
function parsePaperclipRunnerStdoutLine(line: string, ts: string) {
|
||||
let parsed: unknown;
|
||||
try {
|
||||
parsed = JSON.parse(line);
|
||||
} catch {
|
||||
return parseCodexStdoutLine(line, ts);
|
||||
}
|
||||
if (typeof parsed !== "object" || parsed === null || (parsed as { type?: unknown }).type !== "paperclip.prp.event") {
|
||||
return parseCodexStdoutLine(line, ts);
|
||||
}
|
||||
const event = (parsed as { event?: unknown }).event;
|
||||
if (typeof event !== "object" || event === null) return [];
|
||||
const candidate = event as { eventType?: unknown; payload?: unknown };
|
||||
const eventType = typeof candidate.eventType === "string" ? candidate.eventType : "";
|
||||
const payload = typeof candidate.payload === "object" && candidate.payload !== null
|
||||
? candidate.payload as Record<string, unknown>
|
||||
: {};
|
||||
if ((eventType === "item.started" || eventType === "item.completed") && payload.item) {
|
||||
return parseCodexStdoutLine(JSON.stringify({ type: eventType, item: payload.item }), ts);
|
||||
}
|
||||
if (eventType === "turn.started") return parseCodexStdoutLine(JSON.stringify({ type: "turn.started" }), ts);
|
||||
if (eventType === "turn.completed") {
|
||||
return parseCodexStdoutLine(JSON.stringify({ type: "turn.completed", result: payload.result ?? "" }), ts);
|
||||
}
|
||||
if (eventType === "harness.diagnostic") {
|
||||
return [{ kind: "system" as const, ts, text: String(payload.message ?? payload.code ?? "Runner diagnostic") }];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
|
||||
export const paperclipRunnerUIAdapter: UIAdapterModule = {
|
||||
type: "paperclip_runner",
|
||||
label: "Paperclip Runner",
|
||||
parseStdoutLine: parseCodexStdoutLine,
|
||||
parseStdoutLine: parsePaperclipRunnerStdoutLine,
|
||||
ConfigFields: CodexLocalConfigFields,
|
||||
buildAdapterConfig: buildPaperclipRunnerConfig,
|
||||
};
|
||||
Reference in new issue
Block a user