feat: store large paste inputs as artifacts

This commit is contained in:
2026-09-01 17:26:58 +09:00
parent 5cc78d63c6
commit 04e296a4ef
21 changed files with 1164 additions and 23 deletions
+3 -1
View File
@@ -133,7 +133,9 @@ message: string,
*/
timestamp_ms: number, };
export type Segment = { "kind": "text", content: string, } | { "kind": "paste", id: number, chars: number, lines: number, content: string, } | { "kind": "file_ref", path: string, } | { "kind": "flow", selector: string, } | { "kind": "unknown" };
export type PasteArtifactRef = { artifact_id: string, byte_len: number, char_count: number, line_count: number, sha256: string, source_entry_id: string, };
export type Segment = { "kind": "text", content: string, } | { "kind": "paste", id: number, chars: number, lines: number, content: string, } | { "kind": "paste_artifact", artifact: PasteArtifactRef, } | { "kind": "file_ref", path: string, } | { "kind": "flow", selector: string, } | { "kind": "unknown" };
export type WorkerEvent = { "kind": "turn_ended", worker_name: string, } | { "kind": "errored", worker_name: string, message: string, } | { "kind": "shut_down", worker_name: string, } | { "kind": "scope_sub_delegated",
/**
@@ -137,6 +137,24 @@ function snapshotEvent(cwd: string, entries: unknown[] = []): Event {
};
}
Deno.test("large paste segments project compact artifact metadata", () => {
const body = "secret pasted body";
const text = segmentsToText([{
kind: "paste_artifact",
artifact: {
artifact_id: "019ca7c8-57b6-7f05-8edf-524147aba7b2",
byte_len: 65536,
char_count: 65530,
line_count: 200,
sha256: "a".repeat(64),
source_entry_id: "entry-1",
},
}]);
assert(text.includes("019ca7c8-57b6-7f05-8edf-524147aba7b2"), "artifact id is visible");
assert(text.includes("65536 bytes"), "bounded size metadata is visible");
assert(!text.includes(body), "artifact body is not projected");
});
Deno.test("console routing projects live errors but not completion replies", () => {
const errorEvent = {
event: "error",
@@ -1069,6 +1069,8 @@ export function segmentsToText(segments: Segment[]): string {
case "paste":
return segment.content ||
`[paste ${segment.id}: ${segment.chars} chars / ${segment.lines} lines]`;
case "paste_artifact":
return `[Large paste artifact ${segment.artifact.artifact_id}: ${segment.artifact.byte_len} bytes, sha256 ${segment.artifact.sha256}]`;
case "file_ref":
return `@file ${segment.path}`;
case "unknown":