mirror of
https://github.com/outbackdingo/optimclaw.git
synced 2026-08-25 14:53:34 +00:00
* feat: full image support across all channels End-to-end image handling: upload, generation, analysis, editing, and rendering across web gateway, HTTP webhook, WASM (Telegram/Slack), and REPL channels. Builds on the attachment infrastructure from #596 and draws inspiration from PR #641's image pipeline approach — credit to that PR's author for the sentinel JSON pattern and base64-in-JSON upload design. Key changes: - Image upload in web UI (file picker, paste, preview strip) - Image generation tool (FLUX/DALL-E via /v1/images/generations) - Image edit tool (multipart /v1/images/edits with fallback) - Image analysis tool (vision model for workspace images) - Model detection utilities (image_models.rs, vision_models.rs) - Sentinel JSON detection in dispatcher for generated image rendering - StatusUpdate::ImageGenerated → SSE/WS/REPL/WASM broadcast - HTTP webhook attachment support (base64, 5MB/file, 10MB total) - WASM channel image download (Telegram via file API, Slack via host HTTP) - Tool registration wiring in app.rs [skip-regression-check] Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: address PR #725 review comments (16 issues) - SecretString for API keys in all image tools (image_gen, image_edit, image_analyze) - Binary image read via tokio::fs::read instead of DB-backed workspace.read() - Replace Arc<Workspace> with Option<PathBuf> base_dir (workspace has no filesystem API) - ApprovalRequirement::UnlessAutoApproved for cost-sensitive image tools - Scope sentinel detection to image_generate/image_edit tool names only - Skip ToolResult preview broadcast for image sentinels (avoids multi-MB base64 in SSE) - Extract shared media_type_from_path() to builtin/mod.rs - Rename fallback_chat_edit → fallback_generate with tracing::warn - Increase gateway body limit from 1MB to 10MB for image uploads - Increase webhook body limit to 15MB (base64 overhead) - Log warning on invalid base64 in images_to_attachments - Client-side image size limits (5MB/file, 5 images max) in app.js - aria-label on attach button for accessibility - Update body_too_large test for new 10MB limit [skip-regression-check] Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: add Slack file size check before download (PR review item #15) Skip downloading files larger than 20 MB in the Slack WASM channel to avoid excessive memory use and slow downloads in the WASM runtime. Logs a warning when a file is skipped. Also bumps channel versions for Slack and Telegram (prior branch changes). [skip-regression-check] Co-Authored-By: Claude Opus 4.6 <[email protected]> * style: cargo fmt Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix(security): add path validation and approval requirement to image tools Add sandbox path validation via validate_path() to both ImageAnalyzeTool and ImageEditTool to prevent path traversal attacks that could exfiltrate arbitrary files through external vision/edit APIs. Also fix ImageAnalyzeTool::requires_approval to return UnlessAutoApproved, consistent with ImageEditTool and ImageGenerateTool. Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: post-download size guards and empty data_url sentinel check - Slack: add post-download size check on actual bytes when metadata size_bytes is absent, preventing bypass of the 20MB limit - Telegram: add 20MB download size limit (matching Slack) enforced in download_telegram_file() after receiving response bytes - Dispatcher: skip broadcasting ImageGenerated SSE event when data_url is empty from unwrap_or_default(), log warning instead Closes correctness issues #3, #4, #5 from PR #725 review. Co-Authored-By: Claude Opus 4.6 <[email protected]> * fix: use mime_guess for media type detection, add alt attrs and media_type validation - Replace hardcoded media type mapping with mime_guess crate (already in deps) - Add alt attributes to img elements in web UI for accessibility - Validate media_type starts with "image/" in images_to_attachments() - Update bmp test assertion to match mime_guess behavior Co-Authored-By: Claude Opus 4.6 <[email protected]> --------- Co-authored-by: Claude Opus 4.6 <[email protected]> Co-authored-by: Zaki <[email protected]>
402 lines
9.8 KiB
TOML
402 lines
9.8 KiB
TOML
# This file is automatically @generated by Cargo.
|
|
# It is not intended for manual editing.
|
|
version = 4
|
|
|
|
[[package]]
|
|
name = "ahash"
|
|
version = "0.8.12"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "5a15f179cd60c4584b8a8c596927aadc462e27f2ca70c04e0071964a73ba7a75"
|
|
dependencies = [
|
|
"cfg-if",
|
|
"once_cell",
|
|
"version_check",
|
|
"zerocopy",
|
|
]
|
|
|
|
[[package]]
|
|
name = "anyhow"
|
|
version = "1.0.100"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "a23eb6b1614318a8071c9b2521f36b424b2c83db5eb3a0fead4a6c0809af6e61"
|
|
|
|
[[package]]
|
|
name = "bitflags"
|
|
version = "2.10.0"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "812e12b5285cc515a9c72a5c1d3b6d46a19dac5acfef5265968c166106e31dd3"
|
|
|
|
[[package]]
|
|
name = "cfg-if"
|
|
version = "1.0.4"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "9330f8b2ff13f34540b44e946ef35111825727b38d33286ef986142615121801"
|
|
|
|
[[package]]
|
|
name = "equivalent"
|
|
version = "1.0.2"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
|
|
|
|
[[package]]
|
|
name = "hashbrown"
|
|
version = "0.14.5"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1"
|
|
dependencies = [
|
|
"ahash",
|
|
]
|
|
|
|
[[package]]
|
|
name = "hashbrown"
|
|
version = "0.16.1"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "841d1cc9bed7f9236f321df977030373f4a4163ae1a7dbfe1a51a2c1a51d9100"
|
|
|
|
[[package]]
|
|
name = "heck"
|
|
version = "0.5.0"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea"
|
|
|
|
[[package]]
|
|
name = "id-arena"
|
|
version = "2.3.0"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "3d3067d79b975e8844ca9eb072e16b31c3c1c36928edf9c6789548c524d0d954"
|
|
|
|
[[package]]
|
|
name = "indexmap"
|
|
version = "2.13.0"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017"
|
|
dependencies = [
|
|
"equivalent",
|
|
"hashbrown 0.16.1",
|
|
"serde",
|
|
"serde_core",
|
|
]
|
|
|
|
[[package]]
|
|
name = "itoa"
|
|
version = "1.0.17"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2"
|
|
|
|
[[package]]
|
|
name = "leb128"
|
|
version = "0.2.5"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "884e2677b40cc8c339eaefcb701c32ef1fd2493d71118dc0ca4b6a736c93bd67"
|
|
|
|
[[package]]
|
|
name = "log"
|
|
version = "0.4.29"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "5e5032e24019045c762d3c0f28f5b6b8bbf38563a65908389bf7978758920897"
|
|
|
|
[[package]]
|
|
name = "memchr"
|
|
version = "2.7.6"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "f52b00d39961fc5b2736ea853c9cc86238e165017a493d1d5c8eac6bdc4cc273"
|
|
|
|
[[package]]
|
|
name = "once_cell"
|
|
version = "1.21.3"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "42f5e15c9953c5e4ccceeb2e7382a716482c34515315f7b03532b8b4e8393d2d"
|
|
|
|
[[package]]
|
|
name = "prettyplease"
|
|
version = "0.2.37"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "479ca8adacdd7ce8f1fb39ce9ecccbfe93a3f1344b3d0d97f20bc0196208f62b"
|
|
dependencies = [
|
|
"proc-macro2",
|
|
"syn",
|
|
]
|
|
|
|
[[package]]
|
|
name = "proc-macro2"
|
|
version = "1.0.106"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "8fd00f0bb2e90d81d1044c2b32617f68fcb9fa3bb7640c23e9c748e53fb30934"
|
|
dependencies = [
|
|
"unicode-ident",
|
|
]
|
|
|
|
[[package]]
|
|
name = "quote"
|
|
version = "1.0.44"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "21b2ebcf727b7760c461f091f9f0f539b77b8e87f2fd88131e7f1b433b3cece4"
|
|
dependencies = [
|
|
"proc-macro2",
|
|
]
|
|
|
|
[[package]]
|
|
name = "semver"
|
|
version = "1.0.27"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2"
|
|
|
|
[[package]]
|
|
name = "serde"
|
|
version = "1.0.228"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "9a8e94ea7f378bd32cbbd37198a4a91436180c5bb472411e48b5ec2e2124ae9e"
|
|
dependencies = [
|
|
"serde_core",
|
|
"serde_derive",
|
|
]
|
|
|
|
[[package]]
|
|
name = "serde_core"
|
|
version = "1.0.228"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "41d385c7d4ca58e59fc732af25c3983b67ac852c1a25000afe1175de458b67ad"
|
|
dependencies = [
|
|
"serde_derive",
|
|
]
|
|
|
|
[[package]]
|
|
name = "serde_derive"
|
|
version = "1.0.228"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "d540f220d3187173da220f885ab66608367b6574e925011a9353e4badda91d79"
|
|
dependencies = [
|
|
"proc-macro2",
|
|
"quote",
|
|
"syn",
|
|
]
|
|
|
|
[[package]]
|
|
name = "serde_json"
|
|
version = "1.0.149"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "83fc039473c5595ace860d8c4fafa220ff474b3fc6bfdb4293327f1a37e94d86"
|
|
dependencies = [
|
|
"itoa",
|
|
"memchr",
|
|
"serde",
|
|
"serde_core",
|
|
"zmij",
|
|
]
|
|
|
|
[[package]]
|
|
name = "smallvec"
|
|
version = "1.15.1"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
|
|
|
|
[[package]]
|
|
name = "spdx"
|
|
version = "0.10.9"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "c3e17e880bafaeb362a7b751ec46bdc5b61445a188f80e0606e68167cd540fa3"
|
|
dependencies = [
|
|
"smallvec",
|
|
]
|
|
|
|
[[package]]
|
|
name = "syn"
|
|
version = "2.0.114"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "d4d107df263a3013ef9b1879b0df87d706ff80f65a86ea879bd9c31f9b307c2a"
|
|
dependencies = [
|
|
"proc-macro2",
|
|
"quote",
|
|
"unicode-ident",
|
|
]
|
|
|
|
[[package]]
|
|
name = "telegram-channel"
|
|
version = "0.2.1"
|
|
dependencies = [
|
|
"serde",
|
|
"serde_json",
|
|
"wit-bindgen",
|
|
]
|
|
|
|
[[package]]
|
|
name = "unicode-ident"
|
|
version = "1.0.22"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "9312f7c4f6ff9069b165498234ce8be658059c6728633667c526e27dc2cf1df5"
|
|
|
|
[[package]]
|
|
name = "unicode-xid"
|
|
version = "0.2.6"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "ebc1c04c71510c7f702b52b7c350734c9ff1295c464a03335b00bb84fc54f853"
|
|
|
|
[[package]]
|
|
name = "version_check"
|
|
version = "0.9.5"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "0b928f33d975fc6ad9f86c8f283853ad26bdd5b10b7f1542aa2fa15e2289105a"
|
|
|
|
[[package]]
|
|
name = "wasm-encoder"
|
|
version = "0.220.1"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "e913f9242315ca39eff82aee0e19ee7a372155717ff0eb082c741e435ce25ed1"
|
|
dependencies = [
|
|
"leb128",
|
|
"wasmparser",
|
|
]
|
|
|
|
[[package]]
|
|
name = "wasm-metadata"
|
|
version = "0.220.1"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "185dfcd27fa5db2e6a23906b54c28199935f71d9a27a1a27b3a88d6fee2afae7"
|
|
dependencies = [
|
|
"anyhow",
|
|
"indexmap",
|
|
"serde",
|
|
"serde_derive",
|
|
"serde_json",
|
|
"spdx",
|
|
"wasm-encoder",
|
|
"wasmparser",
|
|
]
|
|
|
|
[[package]]
|
|
name = "wasmparser"
|
|
version = "0.220.1"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "8d07b6a3b550fefa1a914b6d54fc175dd11c3392da11eee604e6ffc759805d25"
|
|
dependencies = [
|
|
"ahash",
|
|
"bitflags",
|
|
"hashbrown 0.14.5",
|
|
"indexmap",
|
|
"semver",
|
|
]
|
|
|
|
[[package]]
|
|
name = "wit-bindgen"
|
|
version = "0.36.0"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "6a2b3e15cd6068f233926e7d8c7c588b2ec4fb7cc7bf3824115e7c7e2a8485a3"
|
|
dependencies = [
|
|
"wit-bindgen-rt",
|
|
"wit-bindgen-rust-macro",
|
|
]
|
|
|
|
[[package]]
|
|
name = "wit-bindgen-core"
|
|
version = "0.36.0"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "b632a5a0fa2409489bd49c9e6d99fcc61bb3d4ce9d1907d44662e75a28c71172"
|
|
dependencies = [
|
|
"anyhow",
|
|
"heck",
|
|
"wit-parser",
|
|
]
|
|
|
|
[[package]]
|
|
name = "wit-bindgen-rt"
|
|
version = "0.36.0"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "7947d0131c7c9da3f01dfde0ab8bd4c4cf3c5bd49b6dba0ae640f1fa752572ea"
|
|
dependencies = [
|
|
"bitflags",
|
|
]
|
|
|
|
[[package]]
|
|
name = "wit-bindgen-rust"
|
|
version = "0.36.0"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "4329de4186ee30e2ef30a0533f9b3c123c019a237a7c82d692807bf1b3ee2697"
|
|
dependencies = [
|
|
"anyhow",
|
|
"heck",
|
|
"indexmap",
|
|
"prettyplease",
|
|
"syn",
|
|
"wasm-metadata",
|
|
"wit-bindgen-core",
|
|
"wit-component",
|
|
]
|
|
|
|
[[package]]
|
|
name = "wit-bindgen-rust-macro"
|
|
version = "0.36.0"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "177fb7ee1484d113b4792cc480b1ba57664bbc951b42a4beebe573502135b1fc"
|
|
dependencies = [
|
|
"anyhow",
|
|
"prettyplease",
|
|
"proc-macro2",
|
|
"quote",
|
|
"syn",
|
|
"wit-bindgen-core",
|
|
"wit-bindgen-rust",
|
|
]
|
|
|
|
[[package]]
|
|
name = "wit-component"
|
|
version = "0.220.1"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "b505603761ed400c90ed30261f44a768317348e49f1864e82ecdc3b2744e5627"
|
|
dependencies = [
|
|
"anyhow",
|
|
"bitflags",
|
|
"indexmap",
|
|
"log",
|
|
"serde",
|
|
"serde_derive",
|
|
"serde_json",
|
|
"wasm-encoder",
|
|
"wasm-metadata",
|
|
"wasmparser",
|
|
"wit-parser",
|
|
]
|
|
|
|
[[package]]
|
|
name = "wit-parser"
|
|
version = "0.220.1"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "ae2a7999ed18efe59be8de2db9cb2b7f84d88b27818c79353dfc53131840fe1a"
|
|
dependencies = [
|
|
"anyhow",
|
|
"id-arena",
|
|
"indexmap",
|
|
"log",
|
|
"semver",
|
|
"serde",
|
|
"serde_derive",
|
|
"serde_json",
|
|
"unicode-xid",
|
|
"wasmparser",
|
|
]
|
|
|
|
[[package]]
|
|
name = "zerocopy"
|
|
version = "0.8.38"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "57cf3aa6855b23711ee9852dfc97dfaa51c45feaba5b645d0c777414d494a961"
|
|
dependencies = [
|
|
"zerocopy-derive",
|
|
]
|
|
|
|
[[package]]
|
|
name = "zerocopy-derive"
|
|
version = "0.8.38"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "8a616990af1a287837c4fe6596ad77ef57948f787e46ce28e166facc0cc1cb75"
|
|
dependencies = [
|
|
"proc-macro2",
|
|
"quote",
|
|
"syn",
|
|
]
|
|
|
|
[[package]]
|
|
name = "zmij"
|
|
version = "1.0.19"
|
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
checksum = "3ff05f8caa9038894637571ae6b9e29466c1f4f829d26c9b28f869a29cbe3445"
|