mirror of
https://github.com/turnstonelabs/turnstone.git
synced 2026-08-12 23:12:23 -06:00
db0baefeb2
* feat: render rich media embeds for MCP tool results Detect structured media JSON (stream_url, results, sessions) in MCP tool output and render interactive cards instead of plain text. Web UI: media cards with thumbnail, title, metadata, and click-to-play video/audio. HLS via lazy-loaded hls.js with direct-stream preference. Collapsed raw JSON (API keys redacted) for inspection. Discord: rich embeds with proxied thumbnail images (fetched by the bot since Discord CDN cannot reach private media servers). Search results as numbered lists, session state as "Now Playing" cards. Stream URLs never exposed in embeds — web_url used for safe clickable links. CI: vendor hls.js 1.6.15 with renovate tracking and update script. * fix: address PR #292 review — SSRF guards, streaming fetch, tests - URL validation: reject non-http(s) schemes and userinfo in thumbnail URLs. Private IPs intentionally allowed (media servers are on LAN). - Streaming fetch: use http.stream() with aiter_bytes() and a running byte count to enforce the 2MB cap without buffering the full response. Validate content-type is image/* before downloading. - Resilience: wrap try_build_media_embed in try/except in bot.py so a media embed failure falls through to the code-block path. - LICENSE: download hls.js LICENSE from npm on update instead of only copying from old dir. - Tests: add 19 new tests — try_parse_media (8 cases), _is_safe_image_url (7 cases), embed builders (4 cases including stream_url exclusion and string season/episode safety). * chore: add LICENSE file for vendored hls.js * fix: remove ANSI escape codes from tool preview fields Preview text (tool args, URLs, queries) was wrapped in DIM/RESET ANSI codes at the source in session.py, which leaked into SSE events and rendered as raw escape sequences in Discord and the web UI. Move ANSI styling to the CLI consumer (cli.py) where it belongs. Also escape markdown in Discord tool name titles to prevent __ from being interpreted as underline formatting. * fix: drop [MCP: server] prefix from tool descriptions The prefix made MCP tools look second-class compared to builtins, causing models to hesitate using them. The server name is already encoded in the tool name (mcp__server__tool). * feat: pretty-print JSON tool output, player error state, broader key redaction - JSON tool results are detected and pretty-printed with 2-space indent instead of rendering as a wall of text - API key redaction extended to cover api_key, apiKey, api-key, and token query params across all tool output (not just media embeds) - Video/audio player shows styled error message when stream fails to load instead of leaving a broken player element - Both appendToolOutput and replayHistory use shared renderToolOutput() * fix: designer review — player error retry, contrast, tool-cmd cap - Player error: role="alert" for screen readers, retry button that reuses existing play handler, includes media title in error message - Light theme: darken --red from #dc2626 to #b91c1c (5.7:1 contrast on --code-bg, was 4.3:1 failing WCAG AA at 12px) - Pretty-print collapsed raw JSON in media embeds (was missed earlier) - Cap .tool-cmd at 120px to prevent tools with many args from making approval blocks disproportionately tall in history replay - Dedicated .media-player-error class instead of reusing .tool-output * fix: Discord tool info name matching regression, suppress deprecation warning The escape_markdown call on tool names was stored for matching against ToolResultEvent.name, but event.name is raw/unescaped. The escaped name never matched, so the "Running → Done" transition silently failed and previews disappeared from the status embed. Fix: store raw name for matching, use escaped name only for display. Also suppress discord.py's re.sub count deprecation warning (Python 3.13+ issue, fixed upstream). * fix: update MCP tool description tests to match prefix removal * fix: address PR #292 review round 2 - Retry button: handle missing span children in click handler so retry buttons from player error state don't throw - Footer count: use len(lines) instead of min(len(results), 10) to reflect actual rendered count after char budget truncation - Null display: use "null" instead of "None" in JS tool arg preview - Broader redaction: also redact JSON "api_key": "..." patterns - SSRF hardening: block loopback and link-local IPs plus cloud metadata hostnames in thumbnail fetch (private LAN IPs still allowed)
143 lines
4.3 KiB
JSON
143 lines
4.3 KiB
JSON
{
|
|
"$schema": "https://docs.renovatebot.com/renovate-schema.json",
|
|
"extends": [
|
|
"config:recommended",
|
|
"helpers:pinGitHubActionDigests",
|
|
":separateMajorReleases"
|
|
],
|
|
"gitIgnoredAuthors": [
|
|
"41898282+github-actions[bot]@users.noreply.github.com"
|
|
],
|
|
"labels": ["dependencies"],
|
|
"prConcurrentLimit": 5,
|
|
"prHourlyLimit": 2,
|
|
"schedule": ["before 9am on Monday"],
|
|
"timezone": "America/New_York",
|
|
"lockFileMaintenance": {
|
|
"enabled": true,
|
|
"schedule": ["before 9am on Monday"]
|
|
},
|
|
"customManagers": [
|
|
{
|
|
"customType": "regex",
|
|
"description": "Track vendored KaTeX version",
|
|
"managerFilePatterns": ["/pyproject\\.toml$/"],
|
|
"matchStrings": ["katex-(?<currentValue>[\\d.]+)/"],
|
|
"depNameTemplate": "katex",
|
|
"datasourceTemplate": "npm"
|
|
},
|
|
{
|
|
"customType": "regex",
|
|
"description": "Track vendored Highlight.js version",
|
|
"managerFilePatterns": ["/pyproject\\.toml$/"],
|
|
"matchStrings": ["hljs-(?<currentValue>[\\d.]+)/"],
|
|
"depNameTemplate": "highlight.js",
|
|
"datasourceTemplate": "npm"
|
|
},
|
|
{
|
|
"customType": "regex",
|
|
"description": "Track vendored Mermaid version",
|
|
"managerFilePatterns": ["/pyproject\\.toml$/"],
|
|
"matchStrings": ["mermaid-(?<currentValue>[\\d.]+)/"],
|
|
"depNameTemplate": "mermaid",
|
|
"datasourceTemplate": "npm"
|
|
},
|
|
{
|
|
"customType": "regex",
|
|
"description": "Track vendored hls.js version",
|
|
"managerFilePatterns": ["/pyproject\\.toml$/"],
|
|
"matchStrings": ["hls-(?<currentValue>[\\d.]+)/"],
|
|
"depNameTemplate": "hls.js",
|
|
"datasourceTemplate": "npm"
|
|
}
|
|
],
|
|
"packageRules": [
|
|
{
|
|
"description": "LLM SDKs — always review manually",
|
|
"groupName": "LLM SDKs",
|
|
"matchPackageNames": ["openai", "anthropic", "mcp"],
|
|
"schedule": ["before 9am on Monday"],
|
|
"automerge": false
|
|
},
|
|
{
|
|
"description": "Web framework stack",
|
|
"groupName": "Web Framework",
|
|
"matchPackageNames": [
|
|
"starlette",
|
|
"uvicorn",
|
|
"sse-starlette",
|
|
"httpx",
|
|
"httpx-sse",
|
|
"pydantic"
|
|
],
|
|
"schedule": ["before 9am on Wednesday"],
|
|
"automerge": true,
|
|
"matchUpdateTypes": ["patch"]
|
|
},
|
|
{
|
|
"description": "Database layer",
|
|
"groupName": "Database",
|
|
"matchPackageNames": ["sqlalchemy", "alembic", "psycopg"],
|
|
"schedule": ["before 9am on Wednesday"],
|
|
"automerge": true,
|
|
"matchUpdateTypes": ["patch"]
|
|
},
|
|
{
|
|
"description": "Security-critical — always review manually",
|
|
"groupName": "Security",
|
|
"matchPackageNames": ["PyJWT", "pyjwt", "bcrypt"],
|
|
"automerge": false
|
|
},
|
|
{
|
|
"description": "Infrastructure dependencies",
|
|
"groupName": "Infrastructure",
|
|
"matchPackageNames": ["structlog", "croniter", "discord.py"],
|
|
"schedule": ["before 9am on the first day of the month"],
|
|
"automerge": true,
|
|
"matchUpdateTypes": ["patch"]
|
|
},
|
|
{
|
|
"description": "Vendored JS — CI workflow downloads files automatically",
|
|
"groupName": "Vendored JS",
|
|
"matchPackageNames": ["katex", "highlight.js", "mermaid", "hls.js"],
|
|
"schedule": ["before 9am on the first day of the month"],
|
|
"automerge": false
|
|
},
|
|
{
|
|
"description": "Dev/test tooling",
|
|
"groupName": "Tooling",
|
|
"matchPackageNames": [
|
|
"ruff",
|
|
"mypy",
|
|
"pytest",
|
|
"pytest-cov",
|
|
"pre-commit"
|
|
],
|
|
"schedule": ["before 9am on the first day of the month"],
|
|
"automerge": true,
|
|
"matchUpdateTypes": ["patch"]
|
|
},
|
|
{
|
|
"description": "Docker base images",
|
|
"groupName": "Docker Images",
|
|
"matchManagers": ["dockerfile", "docker-compose"],
|
|
"schedule": ["before 9am on the first day of the month"],
|
|
"automerge": false
|
|
},
|
|
{
|
|
"description": "TypeScript SDK dev dependencies",
|
|
"groupName": "TypeScript SDK",
|
|
"matchFileNames": ["sdk/typescript/**"],
|
|
"schedule": ["before 9am on the first day of the month"],
|
|
"automerge": true,
|
|
"matchUpdateTypes": ["patch"]
|
|
},
|
|
{
|
|
"description": "GitHub Actions — group all action updates",
|
|
"groupName": "GitHub Actions",
|
|
"matchManagers": ["github-actions"],
|
|
"automerge": false
|
|
}
|
|
]
|
|
}
|