feat(snapcompact): ignored empty text and thinking blocks
- Prevented the serialization of empty or whitespace-only content blocks to avoid extraneous headers. - Updated the prompt template to improve clarity for message roles and formatting.
This commit is contained in:
@@ -1,6 +1,11 @@
|
||||
Prior conversation history has been archived verbatim onto {{frameCount}} snapcompact frame{{#if multipleFrames}}s{{/if}} — the bitmap image{{#if multipleFrames}}s{{/if}} attached below{{#if multipleFrames}}, ordered oldest to newest{{/if}}.
|
||||
|
||||
Reading a frame: monospace {{fontCell}} pixel font on a white background, {{#if docColumns}}typeset as two word-wrapped newspaper columns of {{cols}} characters by {{rows}} lines each — read the left column top to bottom, then the right column{{else}}{{cols}} characters per row, {{rows}} text rows per frame; read left to right, top to bottom. Text flows continuously with no word wrap, so words may break across row ends{{/if}}. Horizontal whitespace runs were collapsed to single spaces; line breaks print as a solid black cell (one character wide) — treat each as a newline. {{#if sentenceInk}}Ink color cycles through six colors, advancing at sentence boundaries — a color change marks a new sentence.{{else}}Glyphs are plain black ink.{{/if}}{{#if stopwordDimmed}} Common function words (the, of, and, …) are printed in dim gray; content words carry the full ink.{{/if}}{{#if dimmedToolResults}} Tool output is printed in dim gray ink — gray text is archived tool output, not conversation.{{/if}}{{#if lineRepeated}} Every text line is printed twice in a row — first on the white background, then repeated on a pale yellow band. The copies are identical: read each line once and use the duplicate only to double-check hard glyphs.{{/if}} Roles are tagged inline as [User]:, [Assistant]:, [Think]:, [Tool Call]:, and [Tool Result]:.
|
||||
Reading a frame: a grid {{cols}} cells wide and up to {{rows}} tall{{#if docColumns}}, set as two word-wrapped columns — read the left column top to bottom, then the right{{else}} — read left to right, top to bottom, with no word wrap, so words may break across rows{{/if}}. A solid black cell is a newline; runs of spaces collapse to one. Turns are headed # User ¶, # Assistant ¶, or # Tool call ¶; assistant reasoning is _italic_ and tool output sits in <out>…</out>.
|
||||
{{#if sentenceInk}}- Ink cycles six colors, one per sentence.
|
||||
{{/if}}{{#if stopwordDimmed}}- Function words are dim gray; content words keep full ink.
|
||||
{{/if}}{{#if dimmedToolResults}}- Text inside <out> is dim gray; that gray is archived tool output, not conversation.
|
||||
{{/if}}{{#if lineRepeated}}- Each line is printed twice (white, then a pale-yellow band); the copies are identical.
|
||||
{{/if}}
|
||||
{{#if mixedShapes}}
|
||||
|
||||
Older frames may use a different font, grid, or ink coloring than described above; the reading order is always the same (left to right, top to bottom, oldest frame first).
|
||||
|
||||
@@ -740,9 +740,11 @@ export function serializeConversation(messages: Message[], options?: SerializeOp
|
||||
|
||||
for (const block of msg.content) {
|
||||
if (block.type === "text") {
|
||||
pendingText.push(stripDimMarkers(block.text));
|
||||
const text = stripDimMarkers(block.text);
|
||||
if (text.trim()) pendingText.push(text);
|
||||
} else if (block.type === "thinking") {
|
||||
pendingThinking.push(stripDimMarkers(block.thinking));
|
||||
const thinking = stripDimMarkers(block.thinking);
|
||||
if (thinking.trim()) pendingThinking.push(thinking);
|
||||
} else if (block.type === "toolCall") {
|
||||
if (uselessCallIds.has(block.id)) continue;
|
||||
flushAssistant();
|
||||
|
||||
@@ -609,6 +609,22 @@ describe("serializeConversation", () => {
|
||||
expect(out).toBe("# Assistant ¶\nbefore\nafter");
|
||||
});
|
||||
|
||||
it("drops blank text/thinking blocks instead of emitting an empty assistant heading", () => {
|
||||
const out = snapcompact.serializeConversation(
|
||||
[
|
||||
createAssistantMessage([
|
||||
{ type: "thinking", thinking: " " },
|
||||
{ type: "text", text: "" },
|
||||
{ type: "toolCall", id: "c1", name: "read", arguments: { path: "a.ts" } },
|
||||
]),
|
||||
{ ...createToolResultMessage("body"), toolCallId: "c1" } as Message,
|
||||
],
|
||||
{ dimToolResults: false },
|
||||
);
|
||||
expect(out).toBe('# Tool call ¶\nread(path="a.ts")\n<out>\nbody\n</out>');
|
||||
expect(out).not.toContain("# Assistant ¶");
|
||||
});
|
||||
|
||||
it("wraps tool-result bodies in dim toggles by default and strips stray toggles from content", () => {
|
||||
const out = snapcompact.serializeConversation([
|
||||
createUserMessage(`hello ${snapcompact.DIM_ON}world`),
|
||||
|
||||
Reference in New Issue
Block a user