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
This commit is contained in:
@@ -14,6 +14,7 @@
|
||||
|
||||
#include <regex.h>
|
||||
|
||||
#include "cst_attach.h"
|
||||
#include "cst_tools.h"
|
||||
#include "cst_util.h"
|
||||
#include "os_compat.h"
|
||||
@@ -241,6 +242,47 @@ int cst_tool_read_file2(const cst_tool_ctx_t *ctx, const ctl_tool_call_t *c,
|
||||
return tool_take_buf(r, &b, 0);
|
||||
}
|
||||
|
||||
/* --- view_image ---------------------------------------------------------- */
|
||||
|
||||
/* Show an image to the model: the bytes are copied into the session's
|
||||
* attachment store and travel as a multimodal content part of the result. */
|
||||
int cst_tool_view_image(const cst_tool_ctx_t *ctx, const ctl_tool_call_t *c,
|
||||
cst_tool_result_t *r) {
|
||||
const char *path = tool_arg(c, "path");
|
||||
if (!path || !path[0])
|
||||
return tool_set_result(r, "error: missing path", 1);
|
||||
const char *session = ctx->agent ? cst_agent_session_path(ctx->agent) : NULL;
|
||||
if (!session || !session[0])
|
||||
return tool_set_result(r, "error: no session to store the image in", 1);
|
||||
char full[OS_PATH_MAX];
|
||||
if (resolve(ctx, path, full, sizeof(full)) != 0)
|
||||
return tool_set_resultf(r, 1,
|
||||
"error: path outside workspace or missing parent: "
|
||||
"%.200s",
|
||||
path);
|
||||
if (is_dir(full))
|
||||
return tool_set_resultf(r, 1, "error: %.200s is a directory", path);
|
||||
|
||||
char err[256];
|
||||
cst_attachment_t *a = cst_attach_import_file(session, full, err, sizeof(err));
|
||||
if (!a)
|
||||
return tool_set_resultf(r, 1, "error: cannot show %.200s: %s", path, err);
|
||||
snprintf(a->origin, sizeof(a->origin), "view_image");
|
||||
const char *d = tool_arg(c, "detail");
|
||||
if (d && (strcmp(d, "low") == 0 || strcmp(d, "high") == 0))
|
||||
snprintf(a->detail, sizeof(a->detail), "%s", d);
|
||||
|
||||
char desc[128];
|
||||
cst_attach_describe(a, desc, sizeof(desc));
|
||||
cst_buf_t out = {0};
|
||||
cst_buf_printf(&out, "view_image %.200s: %s\n(shown to you as an image)\n",
|
||||
path, desc);
|
||||
int rc = tool_take_buf(r, &out, 0);
|
||||
r->attach = a; /* one entry; freed as a block by cst_tool_result_free */
|
||||
r->nattach = 1;
|
||||
return rc;
|
||||
}
|
||||
|
||||
/* --- edit_file ----------------------------------------------------------- */
|
||||
|
||||
static size_t count_occ(const char *hay, size_t hn, const char *needle,
|
||||
|
||||
Reference in New Issue
Block a user