feat: format Claude stream-json events in K8s streaming path for consistency with claude_local (FAR-32)
All output sent to Paperclip via onLog now passes through formatClaudeStreamLine, converting raw stream-json blobs into human-readable text consistent with how the CLI and claude_local adapter format events. Changes: - format-event.ts: add formatClaudeStreamLine(raw) -> string | null Plain-text equivalent of printClaudeStreamEvent — no ANSI colours, returns null for lines to suppress (assistant with no content, unknown events). Handles: system/init, assistant (text/thinking/tool_use), user (tool_result), result (summary + tokens), rate_limit_event. Non-JSON lines pass through. - execute.ts: wire formatClaudeStreamLine into streamPodLogsOnce write handler. raw chunks still stored in 'chunks[]' for parseClaudeStreamJson; only the onLog path receives formatted text. - 12 new tests for formatClaudeStreamLine covering all event types. - 352/352 tests pass. Co-Authored-By: Paperclip <noreply@paperclip.ing>
This commit is contained in:
+10
-1
@@ -19,6 +19,7 @@ import {
|
||||
import { getSelfPodInfo, getBatchApi, getCoreApi, getLogApi } from "./k8s-client.js";
|
||||
import { buildJobManifest, sanitizeLabelValue } from "./job-manifest.js";
|
||||
import { LogLineDedupFilter } from "./log-dedup.js";
|
||||
import { formatClaudeStreamLine } from "../cli/format-event.js";
|
||||
import type * as k8s from "@kubernetes/client-node";
|
||||
import { Writable } from "node:stream";
|
||||
|
||||
@@ -353,13 +354,21 @@ export async function streamPodLogsOnce(
|
||||
const writable = new Writable({
|
||||
write(chunk: Buffer, _encoding, callback) {
|
||||
const text = chunk.toString("utf-8");
|
||||
// Always store raw text — parseClaudeStreamJson needs the original
|
||||
// stream-json lines to extract session IDs, usage, and result events.
|
||||
chunks.push(text);
|
||||
const emitted = dedup ? dedup.filter(text) : text;
|
||||
if (!emitted) {
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
void onLog("stdout", emitted).then(() => callback(), callback);
|
||||
// Format each stream-json event into human-readable text before the
|
||||
// Paperclip server sees it, matching claude_local output style.
|
||||
// Non-JSON lines (adapter status messages, plain errors) pass through.
|
||||
const formatted = emitted.split("\n")
|
||||
.map((line) => formatClaudeStreamLine(line) ?? "")
|
||||
.join("\n");
|
||||
void onLog("stdout", formatted).then(() => callback(), callback);
|
||||
},
|
||||
});
|
||||
|
||||
|
||||
Reference in New Issue
Block a user