Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions server/blocks.sql
Original file line number Diff line number Diff line change
Expand Up @@ -44,11 +44,11 @@ WITH line AS (
SELECT * EXCLUDE (b, content_keys, id_keys, part_keys, message_types), coalesce(b ->> 'type', 'text') AS block_type,
CASE WHEN list_contains(call_types, block_type) THEN 'call' WHEN list_contains(result_types, block_type) THEN 'result' END AS tool_part,
-- a tool result's content (Claude) or output (Codex) can be a list of {type, text} parts, joined by
-- newlines. string_agg, not tera_render: a result can hold a NUL byte, and tera aborts the whole
-- server on one (CString unwrap, src/lib.rs:135; 19 boots in a row on 2026-10-21).
-- newlines (Tera reads "\n" as one: on dev, 1554 multi-part results equal their newline join).
-- A NUL byte is dropped first: tera hands its output to C as a C string (2026-10-21).
[b -> k FOR k IN part_keys IF json_type(b -> k) = 'ARRAY'][1] AS part_array,
[p ->> 'text' FOR p IN CAST(part_array AS JSON[]) IF p ->> 'text' IS NOT NULL] AS text_parts,
coalesce(list_aggregate(text_parts, 'string_agg', E'\n'),
[translate(p ->> 'text', chr(0), '') FOR p IN CAST(part_array AS JSON[]) IF p ->> 'text' IS NOT NULL] AS text_parts,
coalesce(CASE WHEN len(text_parts) > 0 THEN tera_render('{{ parts | join(sep="\n") }}', {'parts': text_parts}::JSON, autoescape := false) END,
CASE WHEN json_type(b) = 'VARCHAR' THEN b ->> '$' END, [b ->> k FOR k IN content_keys IF b ->> k IS NOT NULL][1]) AS message_content,
b ->> 'name' AS tool_name,
-- call_id first: a Codex call and its output share call_id, and each also has its own item id
Expand Down
Loading