Files
codecraft/server/Cargo.toml
T
Richard ZinkandClaude Opus 5.5 e8e455b779 Store chat images separately; JPEG for large PNGs; gzip/brotli responses
Images of messages (pasted images, screenshots, generated images) were base64
inside the message JSON, so opening a chat downloaded all of them at once
(66 MB for a chat with 120 screenshots). They now live in a `blobs` table,
addressed by SHA-256; messages keep a reference (blob, size). The UI loads
them from /api/blobs/<hash> lazily with an immutable cache header, the runner
fills the bytes in before model requests, JSON exports stay self-contained.

- Store::add_message moves inline images out; large opaque PNGs become JPEG
  (q85) when smaller. Older chats are converted once at start-up in the
  background, unused images are removed (also after deleting a chat) and the
  database is vacuumed when that frees 32 MB or more.
- Responses are compressed with gzip/brotli (not images, SSE streams or
  binary downloads).

Example (copy of production): chat load 66 MB -> 1.5 MB (370 KB brotli),
database 90 MB -> 27 MB.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-09 20:21:24 +01:00

51 lines
1.5 KiB
TOML

[package]
name = "codecraft"
version = "0.1.0"
edition = "2024"
description = "Web-based coding harness for AI models"
license = "MIT"
repository = "https://git.familie-zink.org/zink/codecraft"
[dependencies]
codecraft-core = { path = "../core" }
anyhow = "1"
argon2 = "0.6"
sha2 = "0.11"
rand = "0.10"
async-trait = "0.1"
axum = { version = "0.8", features = ["ws", "macros"] }
bytes = "1"
chrono = { version = "0.4", features = ["serde"] }
eventsource-stream = "0.2"
futures = "0.3"
globset = "0.4"
html2text = "0.15"
image = { version = "0.25", default-features = false, features = ["png", "jpeg", "webp"] }
base64 = "0.22"
calamine = "0.38"
zip = { version = "9", default-features = false, features = ["deflate"] }
shell-words = "1"
libc = "0.2"
ignore = "0.4"
regex = "1"
reqwest = { version = "0.13", default-features = false, features = ["json", "stream", "rustls", "form", "multipart"] }
rusqlite = { version = "0.41", features = ["bundled"] }
serde = { version = "1", features = ["derive"] }
serde_json = "1"
similar = "2"
tokio = { version = "1", features = ["full"] }
tokio-tungstenite = "0.29"
tokio-util = "0.7"
toml = "1"
toml_edit = "0.25"
tower-http = { version = "0.7", features = ["fs", "cors", "trace", "compression-gzip", "compression-br"] }
tracing = "0.1"
tracing-subscriber = { version = "0.3", features = ["env-filter", "json"] }
uuid = { version = "1", features = ["v4", "v7"] }
p256 = { version = "0.14", features = ["ecdh", "ecdsa"] }
hkdf = "0.13"
aes-gcm = "0.11"
pty-process = { version = "0.5.4", features = ["async"] }
croner = "4.0.3"
hmac = "0.13"