From b3d28329df214e815f2b1ac20eedee457c61ea16 Mon Sep 17 00:00:00 2001 From: sixvolts Date: Sun, 6 Sep 2026 16:21:00 +0000 Subject: [PATCH 1/2] fix(chat): stop horizontal overflow, and stop research firing on plain questions MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Two unrelated bugs from the same screenshot. 1. Chat scrolled sideways past the panel separator. .chat-messages and .chat-msg are flex columns with no min-width:0. A flex item defaults to min-width:auto, so content sets the floor and any wide child — the monospace reasoning trace, a code block, a long URL — stretches the column past the panel and takes the whole conversation sideways. .chat-right already had min-width:0, but that does not propagate; every flex container in the chain needs its own. Now: both containers get min-width:0, the scroller gets overflow-x:hidden, the message body wraps unbroken tokens (overflow-wrap:anywhere), and pre/table get max-width:100% + overflow-x:auto so they scroll INSIDE their own box instead of widening the parent. Code blocks keep their formatting; they just no longer drag the panel with them. 2. "Give me a 1-page overview of the history of the amiga" started a research run, burned the search budget, hit the tool wall, and produced no answer. The skill description said: ALWAYS use this skill when the user asks to research, investigate, dig into, or get an overview of a topic. The model's own trace quotes it — "the instruction is explicit that 'get an overview of a topic' → use the skill" — and the existing caveat ("Not for simple lookups") was buried after the ALWAYS and lost the argument. Rewritten so the opt-out is as prominent as the opt-in: the skill is for EXPLICIT research requests; overview/summarize/explain/tell-me-about are ordinary knowledge requests to answer directly; a length hint like "1-page" is a FORMAT, not a request to research; and a trivial/knowledge classifier tier is a strong signal to answer directly rather than start a run. Applied to both the live copy under ~/.familiar/skills and the repo builtin so they cannot drift. --- .../skillpkg/builtin/research/SKILL.md | 16 +++++++++---- familiar-workspace/static/app.css | 23 +++++++++++++++++++ 2 files changed, 35 insertions(+), 4 deletions(-) diff --git a/familiar-gateway/internal/skillpkg/builtin/research/SKILL.md b/familiar-gateway/internal/skillpkg/builtin/research/SKILL.md index e7df2e3..58b2606 100644 --- a/familiar-gateway/internal/skillpkg/builtin/research/SKILL.md +++ b/familiar-gateway/internal/skillpkg/builtin/research/SKILL.md @@ -1,10 +1,18 @@ --- name: research description: >- - Web research expert. ALWAYS use this skill when the user asks to research, - investigate, dig into, or get an overview of a topic. Effort tiers: quick, - standard (default), deep — keyword anywhere in the request. Not for simple - lookups answerable with a single search. + Web research expert for EXPLICIT research requests: the user asks to + research, investigate, dig into, look into, or compile sources on a topic. + Effort tiers: quick, standard (default), deep — keyword anywhere in the + request. + DO NOT use this skill when the user just wants an answer written from what + you already know. "Give me an overview of X", "summarize X", "explain X", + "tell me about X" are ordinary knowledge requests — answer them directly. + A length hint ("1-page", "short") is a FORMAT, not a request to research. + If the classifier tier for the turn is trivial or knowledge, that is a strong + signal the user wants a direct answer; do not start a research run to satisfy + it. Never research a topic that is answerable from training knowledge unless + the user asked for sources, citations, or current/recent information. license: MIT metadata: version: "1.0" diff --git a/familiar-workspace/static/app.css b/familiar-workspace/static/app.css index 965bf98..395f9ad 100644 --- a/familiar-workspace/static/app.css +++ b/familiar-workspace/static/app.css @@ -4021,6 +4021,13 @@ code { .chat-messages { flex: 1 1 auto; overflow-y: auto; + /* Never scroll the conversation sideways: a wide child should scroll + inside itself (see .chat-msg-body pre) rather than widen the column. + min-width:0 is required because a flex item defaults to min-width:auto, + which lets content set the floor — .chat-right having it does not + propagate, each flex container needs its own. */ + overflow-x: hidden; + min-width: 0; padding: 24px 32px; display: flex; flex-direction: column; @@ -4056,6 +4063,7 @@ code { display: flex; flex-direction: column; gap: 6px; + min-width: 0; /* Cap width at the readable 760px on wide panels, but keep a 10% gap against the opposite edge on narrower ones so the back-and-forth reads at a glance. */ @@ -4088,6 +4096,21 @@ code { font-size: var(--text-md); line-height: 1.65; color: var(--fg-2); + min-width: 0; + /* Long URLs and unbroken tokens wrap instead of widening the panel. */ + overflow-wrap: anywhere; +} +/* Code blocks keep their formatting, so they cannot wrap — let them scroll + inside their own box rather than stretching the message column and taking + the whole conversation sideways with it. */ +.chat-msg-body pre { + max-width: 100%; + overflow-x: auto; +} +.chat-msg-body table { + display: block; + max-width: 100%; + overflow-x: auto; } .chat-msg-body > :first-child { margin-top: 0; } .chat-msg-body > :last-child { margin-bottom: 0; } From ceab32a5480baef88547c507fd7422563d7e8961 Mon Sep 17 00:00:00 2001 From: sixvolts Date: Sun, 6 Sep 2026 16:27:46 +0000 Subject: [PATCH 2/2] style(chat): render markdown tables legibly MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The model emits ordinary pipe tables and they arrived completely unstyled: no header rule, no cell padding, no column gap — adjacent cells ran together, with "Rest of Europe / other" abutting "remainder" in the reported case. Adopts the .memory-table / .users-table idiom already used elsewhere in the app so a table looks the same wherever it appears: uppercase mono header with a rule under it, per-row hairlines, 16px right gutter between columns, no trailing gutter on the last column and no hairline under the last row. width:max-content keeps a narrow table narrow instead of stretching it across the panel, while display:block + overflow-x:auto (from the overflow fix in this branch) still lets a wide one scroll inside its own box rather than dragging the message column sideways. --- familiar-workspace/static/app.css | 37 +++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) diff --git a/familiar-workspace/static/app.css b/familiar-workspace/static/app.css index 395f9ad..dbe0f1e 100644 --- a/familiar-workspace/static/app.css +++ b/familiar-workspace/static/app.css @@ -4107,11 +4107,48 @@ code { max-width: 100%; overflow-x: auto; } +/* Markdown tables in chat. The model emits plain | pipe | tables and they + arrived completely unstyled: no header rule, no cell padding, no column + gap — adjacent cells ran together ("Rest of Europe / other" abutting + "remainder"). Matches the .memory-table / .users-table idiom used elsewhere + in the app so tables look the same wherever they appear. + + display:block + overflow-x:auto keeps a wide table scrolling inside its own + box instead of widening the message column (see the overflow fix above). + width:max-content lets narrow tables stay narrow rather than being stretched + to the panel, while still allowing wide ones to scroll. */ .chat-msg-body table { display: block; + width: max-content; max-width: 100%; overflow-x: auto; + border-collapse: collapse; + font-size: var(--text-sm); + margin: 12px 0; +} +.chat-msg-body thead th { + text-align: left; + color: var(--fg-3); + font-family: var(--font-mono); + font-size: var(--text-2xs); + font-weight: 500; + letter-spacing: 0.12em; + text-transform: uppercase; + padding: 8px 16px 8px 0; + border-bottom: 1px solid var(--border-default); + white-space: nowrap; +} +.chat-msg-body tbody td { + padding: 8px 16px 8px 0; + border-bottom: 1px solid var(--border-subtle); + color: var(--fg-2); + vertical-align: top; } +/* Last column carries no trailing gutter, and the final row no hairline, so + the table ends cleanly instead of looking clipped. */ +.chat-msg-body thead th:last-child, +.chat-msg-body tbody td:last-child { padding-right: 0; } +.chat-msg-body tbody tr:last-child td { border-bottom: 0; } .chat-msg-body > :first-child { margin-top: 0; } .chat-msg-body > :last-child { margin-bottom: 0; } .chat-msg-body p { margin: 0 0 12px; }