8205590f8d
The Discuss button on news cards was producing one-shot replies because the model got the whole trafilatura blob dropped into history with a canned "summarize and discuss this article" prompt — no length guard, no prep, no invitation to converse. Large articles got silently truncated by Ollama; small articles got a tepid reply. This reworks discuss_article around a three-layer cache: context_prepared → content_full → fresh trafilatura fetch First click on a small article fetches once, writes through to both caches, and passes the body straight into the synthetic read_article tool-result. First click on a large article additionally runs a parallel map step (services/article_context.py) that chunks the body on paragraph boundaries, summarizes each ~8k chunk to ~300 words of dense factual prose via the background model, and concatenates the summaries under section headers — all pinned to num_ctx=16384 so the map step doesn't itself fall victim to silent truncation. Repeat clicks on either path skip straight to the chat turn. The canned summary prompt is replaced with a conversational seed that invites the user into an actual discussion rather than a one-shot synopsis, matching the goal of "have a conversation about an article, not just read it." discuss_topic is intentionally left untouched — it's the multi-article aggregation path and needs a separate rework. Follow-up task will decide whether to retire it or rework it on the cached-context approach. Closes task #106. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
35 lines
819 B
Python
35 lines
819 B
Python
"""Add content_full and context_prepared caches to rss_items.
|
|
|
|
Revision ID: 0038
|
|
Revises: 0037
|
|
Create Date: 2026-04-13
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import sqlalchemy as sa
|
|
from alembic import op
|
|
|
|
revision = "0038"
|
|
down_revision = "0037"
|
|
branch_labels = None
|
|
depends_on = None
|
|
|
|
|
|
def upgrade() -> None:
|
|
op.add_column("rss_items", sa.Column("content_full", sa.Text(), nullable=True))
|
|
op.add_column(
|
|
"rss_items",
|
|
sa.Column("context_prepared", sa.Text(), nullable=True),
|
|
)
|
|
op.add_column(
|
|
"rss_items",
|
|
sa.Column("content_fetched_at", sa.DateTime(timezone=True), nullable=True),
|
|
)
|
|
|
|
|
|
def downgrade() -> None:
|
|
op.drop_column("rss_items", "content_fetched_at")
|
|
op.drop_column("rss_items", "context_prepared")
|
|
op.drop_column("rss_items", "content_full")
|