mirror of
https://github.com/Sea-Haven-Industries/open-swe.git
synced 2026-09-30 09:13:14 +00:00
refactor: keep image URLs in text and centralize image auth
This commit is contained in:
parent
bec99b106e
commit
446b659c54
3 changed files with 40 additions and 56 deletions
|
|
@ -27,6 +27,28 @@ class LinearNotifyState(AgentState):
|
|||
linear_messages_sent_count: int
|
||||
|
||||
|
||||
async def _build_blocks_from_payload(
|
||||
payload: dict[str, Any],
|
||||
) -> list[dict[str, Any]]:
|
||||
text = payload.get("text", "")
|
||||
image_urls = payload.get("image_urls", []) or []
|
||||
blocks: list[dict[str, Any]] = []
|
||||
if text:
|
||||
blocks.append({"type": "text", "text": text})
|
||||
|
||||
if not image_urls:
|
||||
return blocks
|
||||
linear_api_key = os.environ.get("LINEAR_API_KEY", "")
|
||||
async with httpx.AsyncClient() as client:
|
||||
for image_url in image_urls:
|
||||
image_block = await fetch_image_block(
|
||||
image_url, client, linear_api_key=linear_api_key
|
||||
)
|
||||
if image_block:
|
||||
blocks.append(image_block)
|
||||
return blocks
|
||||
|
||||
|
||||
@before_model(state_schema=LinearNotifyState)
|
||||
async def check_message_queue_before_model( # noqa: PLR0911
|
||||
state: LinearNotifyState, # noqa: ARG001
|
||||
|
|
@ -84,36 +106,6 @@ async def check_message_queue_before_model( # noqa: PLR0911
|
|||
thread_id,
|
||||
)
|
||||
|
||||
async def _build_blocks_from_payload(
|
||||
payload: dict[str, Any],
|
||||
) -> list[dict[str, Any]]:
|
||||
text = payload.get("text", "")
|
||||
image_urls = payload.get("image_urls", []) or []
|
||||
blocks: list[dict[str, Any]] = []
|
||||
if text:
|
||||
blocks.append({"type": "text", "text": text})
|
||||
|
||||
if not image_urls:
|
||||
return blocks
|
||||
linear_api_key = os.environ.get("LINEAR_API_KEY", "")
|
||||
async with httpx.AsyncClient() as client:
|
||||
for image_url in image_urls:
|
||||
headers = None
|
||||
if "uploads.linear.app" in image_url:
|
||||
if linear_api_key:
|
||||
headers = {"Authorization": linear_api_key}
|
||||
else:
|
||||
logger.warning(
|
||||
"LINEAR_API_KEY not set; cannot authenticate image fetch for %s",
|
||||
image_url,
|
||||
)
|
||||
image_block = await fetch_image_block(
|
||||
image_url, client, headers=headers
|
||||
)
|
||||
if image_block:
|
||||
blocks.append(image_block)
|
||||
return blocks
|
||||
|
||||
content_blocks: list[dict[str, Any]] = []
|
||||
for msg in queued_messages:
|
||||
content = msg.get("content")
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ from __future__ import annotations
|
|||
import base64
|
||||
import logging
|
||||
import mimetypes
|
||||
import os
|
||||
import re
|
||||
from typing import Any
|
||||
|
||||
|
|
@ -35,26 +36,27 @@ def extract_image_urls(text: str) -> list[str]:
|
|||
return deduped
|
||||
|
||||
|
||||
def strip_image_urls(text: str, image_urls: list[str]) -> str:
|
||||
"""Remove markdown image links and direct image URLs from text."""
|
||||
if not text or not image_urls:
|
||||
return text
|
||||
|
||||
logger.debug("Stripping %d image URL(s) from text", len(image_urls))
|
||||
text = IMAGE_MARKDOWN_RE.sub("", text)
|
||||
for url in image_urls:
|
||||
text = text.replace(url, "")
|
||||
return text
|
||||
|
||||
|
||||
async def fetch_image_block(
|
||||
image_url: str,
|
||||
client: httpx.AsyncClient,
|
||||
headers: dict[str, str] | None = None,
|
||||
*,
|
||||
linear_api_key: str | None = None,
|
||||
) -> dict[str, Any] | None:
|
||||
"""Fetch image bytes and build an image content block."""
|
||||
try:
|
||||
logger.debug("Fetching image from %s", image_url)
|
||||
headers = None
|
||||
if "uploads.linear.app" in image_url:
|
||||
if linear_api_key is None:
|
||||
linear_api_key = os.environ.get("LINEAR_API_KEY", "")
|
||||
if linear_api_key:
|
||||
headers = {"Authorization": linear_api_key}
|
||||
else:
|
||||
logger.warning(
|
||||
"LINEAR_API_KEY not set; cannot authenticate image fetch for %s",
|
||||
image_url,
|
||||
)
|
||||
response = await client.get(image_url, headers=headers)
|
||||
response.raise_for_status()
|
||||
content_type = response.headers.get("Content-Type", "").split(";")[0].strip()
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ from langgraph_sdk import get_client
|
|||
|
||||
# Local import for encryption
|
||||
from .encryption import encrypt_token
|
||||
from .utils.multimodal import extract_image_urls, fetch_image_block, strip_image_urls
|
||||
from .utils.multimodal import extract_image_urls, fetch_image_block
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
|
@ -581,7 +581,6 @@ async def process_linear_issue( # noqa: PLR0912, PLR0915
|
|||
description_image_urls = extract_image_urls(description)
|
||||
if description_image_urls:
|
||||
image_urls.extend(description_image_urls)
|
||||
description = strip_image_urls(description, description_image_urls)
|
||||
logger.debug(
|
||||
"Found %d image URL(s) in issue description",
|
||||
len(description_image_urls),
|
||||
|
|
@ -643,7 +642,6 @@ async def process_linear_issue( # noqa: PLR0912, PLR0915
|
|||
body_image_urls = extract_image_urls(body)
|
||||
if body_image_urls:
|
||||
image_urls.extend(body_image_urls)
|
||||
body = strip_image_urls(body, body_image_urls)
|
||||
logger.debug(
|
||||
"Found %d image URL(s) in comment by %s",
|
||||
len(body_image_urls),
|
||||
|
|
@ -661,7 +659,6 @@ async def process_linear_issue( # noqa: PLR0912, PLR0915
|
|||
trigger_image_urls = extract_image_urls(trigger_body)
|
||||
if trigger_image_urls:
|
||||
image_urls.extend(trigger_image_urls)
|
||||
trigger_body = strip_image_urls(trigger_body, trigger_image_urls)
|
||||
logger.debug(
|
||||
"Found %d image URL(s) in triggering comment by %s",
|
||||
len(trigger_image_urls),
|
||||
|
|
@ -696,16 +693,9 @@ async def process_linear_issue( # noqa: PLR0912, PLR0915
|
|||
|
||||
async with httpx.AsyncClient() as client:
|
||||
for image_url in image_urls:
|
||||
headers = None
|
||||
if "uploads.linear.app" in image_url:
|
||||
if LINEAR_API_KEY:
|
||||
headers = {"Authorization": LINEAR_API_KEY}
|
||||
else:
|
||||
logger.warning(
|
||||
"LINEAR_API_KEY not set; cannot authenticate image fetch for %s",
|
||||
image_url,
|
||||
)
|
||||
image_block = await fetch_image_block(image_url, client, headers=headers)
|
||||
image_block = await fetch_image_block(
|
||||
image_url, client, linear_api_key=LINEAR_API_KEY
|
||||
)
|
||||
if image_block:
|
||||
content_blocks.append(image_block)
|
||||
logger.info("Built %d content block(s) for prompt", len(content_blocks))
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue