efe0a15b8c
Images found via SearXNG are fetched server-side, stored on disk, and served from /api/images/<id> — the user's browser never contacts the original image host. Original URLs are preserved for citation. New files: - alembic/versions/0016_add_image_cache.py — image_cache table - src/fabledassistant/models/image_cache.py — SQLAlchemy model - src/fabledassistant/services/images.py — fetch/store/serve logic - src/fabledassistant/routes/images.py — GET /api/images/<id> Modified: - config.py: IMAGE_CACHE_DIR (/data/images), IMAGE_MAX_BYTES (5 MB) - research.py: _search_searxng_images() — SearXNG categories=images - tools.py: _IMAGE_TOOLS def + search_images branch in execute_tool - intent.py: search_images routing rule (explicit visual language only) - app.py: register images_bp - docker-compose.yml: image_cache named volume mounted at /data/images - ToolCallCard.vue: "image_search" label Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
31 lines
905 B
Python
31 lines
905 B
Python
"""Add image_cache table for locally-stored images fetched from the web."""
|
|
|
|
from alembic import op
|
|
|
|
revision = "0016"
|
|
down_revision = "0015"
|
|
|
|
|
|
def upgrade() -> None:
|
|
op.execute("""
|
|
CREATE TABLE IF NOT EXISTS image_cache (
|
|
id SERIAL PRIMARY KEY,
|
|
url_hash TEXT UNIQUE NOT NULL,
|
|
original_url TEXT NOT NULL,
|
|
source_domain TEXT,
|
|
title TEXT,
|
|
content_type TEXT NOT NULL DEFAULT 'image/jpeg',
|
|
file_size INTEGER,
|
|
file_ext TEXT NOT NULL DEFAULT 'jpg',
|
|
fetched_at TIMESTAMP WITH TIME ZONE DEFAULT NOW()
|
|
)
|
|
""")
|
|
op.execute(
|
|
"CREATE INDEX IF NOT EXISTS ix_image_cache_url_hash ON image_cache(url_hash)"
|
|
)
|
|
|
|
|
|
def downgrade() -> None:
|
|
op.execute("DROP INDEX IF EXISTS ix_image_cache_url_hash")
|
|
op.execute("DROP TABLE IF EXISTS image_cache")
|