Files
Hermit/include/cst_attach.h
T
WHC 895b47274c
ci / linux (clang) (push) Successful in 4m41s
ci / linux (gcc) (push) Successful in 5m35s
ci / musl (push) Failing after 30s
ci / windows-cross (push) Successful in 9m59s
v0.7.0: image input, model registry, prefix-cache savings
Images
- vision gate: text-only models get a note instead of image parts and no
  view_image tool; unknown models retry once without images on HTTP 400
- paste: Ctrl+V and /attach paste read the clipboard (wl-paste, xclip,
  pngpaste/osascript, Win32 PNG or CF_DIB converted to PNG); pasting image
  file paths attaches them
- MCP image content is stored in the session and sent with the tool result
- attach: rel path validation, base64 decode, /retry keeps images

Model registry
- built-in src/models_builtin.json embedded at build time, merged with
  <config>/models.json and cached GET /models metadata (context, vision,
  pricing); most specific rule wins per field
- /model labels, /status source, --list-models [provider]

Cache and cost
- stable request prefix (frozen tools, notes as messages), DeepSeek prefix
  completion, OpenAI/Anthropic cache hints, /cost and hit rate in the status
2026-10-08 20:34:09 +08:00

82 lines
3.8 KiB
C

#ifndef CST_ATTACH_H
#define CST_ATTACH_H
#include "cst_agent.h"
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/* --- image attachments ---------------------------------------------------
* An attachment is a validated copy of an image file, stored beside the
* session so the bytes a model is shown stay the bytes that were picked.
* Only the metadata travels in the JSONL; the bytes are encoded into the
* request when it is built. */
/* Supported: PNG, JPEG, GIF, WebP, BMP (static images). */
#define CST_ATTACH_MAX_BYTES (16 * 1024 * 1024) /* one stored image */
#define CST_ATTACH_MAX_TOTAL (32 * 1024 * 1024) /* per request */
#define CST_ATTACH_MAX_COUNT 8 /* per message */
/* Magic-byte test: 0 and a canonical mime when data holds a supported
* image, -1 otherwise (an extension alone never decides). */
int cst_attach_sniff(const void *data, size_t n, char *mime, size_t mime_sz);
/* Pixel size from the header when it is readable; 0 for unknown. */
int cst_attach_dimensions(const void *data, size_t n, int *w, int *h);
/* A stored file name as store() makes it ("<id>.<ext>"); rejects anything
* that could leave the attachment directory. */
int cst_attach_rel_ok(const char *rel);
/* Directory holding this session's stored images (created on demand). */
int cst_attach_dir(const char *session_path, char *out, size_t out_sz);
/* Absolute path of a stored image (0 / -1). */
int cst_attach_full_path(const char *session_path, const cst_attachment_t *a,
char *out, size_t out_sz);
/* Read src_path, verify it is a supported image within limits, and copy it
* into the session's attachment directory. Returns a malloc'd entry the
* caller owns (cst_attach_free), or NULL with err filled. */
cst_attachment_t *cst_attach_import_file(const char *session_path,
const char *src_path, char *err,
size_t err_sz);
/* Store already-read bytes (clipboard, downloads); name is display-only. */
cst_attachment_t *cst_attach_import_bytes(const char *session_path,
const char *name, const char *data,
size_t n, char *err, size_t err_sz);
/* Validate and read back a stored image, or NULL when it is gone. */
char *cst_attach_read(const char *session_path, const cst_attachment_t *a,
size_t *out_len, char *err, size_t err_sz);
/* "data:image/png;base64,...." for the wire; NULL when the file is gone. */
char *cst_attach_data_url(const char *session_path, const cst_attachment_t *a);
/* "1920x1080 PNG 412 KB" style one-liner for prompts and the UI. */
void cst_attach_describe(const cst_attachment_t *a, char *out, size_t out_sz);
void cst_attach_free(cst_attachment_t *a);
/* Free a list of n entries allocated as separate blocks. */
void cst_attachments_free(cst_attachment_t *list, int n);
/* Deep copy (NULL on OOM or when n <= 0). */
cst_attachment_t *cst_attachments_dup(const cst_attachment_t *list, int n);
/* Append src to *list (grows with realloc). 0 / -1. */
int cst_attachments_push(cst_attachment_t **list, int *n, int *cap,
const cst_attachment_t *src);
/* JSON array of n attachments for the session JSONL (malloc'd), or NULL. */
char *cst_attachments_to_json(const cst_attachment_t *list, int n);
/* Parse a JSON array; caller frees with cst_attachments_free. */
cst_attachment_t *cst_attachments_from_json(const void *array_json, int *n_out);
/* Base64 of n bytes (malloc'd, no line breaks). */
char *cst_base64_encode(const void *data, size_t n);
/* Standard or URL-safe base64 (whitespace ignored) to bytes; malloc'd,
* NULL on a bad character. */
char *cst_base64_decode(const char *s, size_t n, size_t *out_len);
#ifdef __cplusplus
}
#endif
#endif