v0.8.6: general mode, clipboard text, PDF text extraction
Working mode: --mode coding|general (CST_MODE, settings.json, /mode, WebUI run settings). general swaps the default framing for a general assistant one -- workflow, safety notes, tool wording (run_shell, the subagents) -- and /status shows it; minimal (the paper profile) stays byte-frozen. The prompt state carries the mode so a switch leaves a system note in history. Clipboard: clipboard_read / clipboard_write tools (16 MiB cap read, default 64 KiB window; writing is a WRITE permission with a preview) on pbcopy / wl-copy / xclip / pbpaste / wl-paste / xclip and the Win32 clipboard. In the TUI, /attach paste falls back to clipboard text when there is no image on it. PDF: a dependency-free text extractor (src/pdf_text.c): inflate, Flate/ASCIIHex/ASCII85, PNG/TIFF predictors, layout-independent object scan, object streams, page tree walk with inherited resources, content lexer (Tj/TJ/'/" and the Td/TD/T*/Tm spacing heuristics), per-font ToUnicode CMaps and inline images skipped. Encrypted files and pages with no text layer are refused with the reason. Attachments: /attach (a path or files dropped on the terminal) now take images, PDFs and text. A PDF is stored as its text layer with the mime still saying application/pdf and its page count; anything else has to be UTF-8 text. Documents travel inline as text parts, so CST_NO_IMAGES and text-only models no longer drop them, while images keep their old path. Tests: test_pdf_text (plain, bare and zlib-framed Flate, inline image, CID + ToUnicode, object stream, error paths), documents in test_attach, inlined documents in test_llm_body, mode in test_config.
This commit is contained in:
+16
@@ -263,6 +263,7 @@ static cJSON *wui_state_new(wui_t *w) {
|
||||
cJSON_AddStringToObject(o, "provider", cfg->provider);
|
||||
cJSON_AddStringToObject(o, "model", cfg->model);
|
||||
cJSON_AddStringToObject(o, "effort", cfg->effort);
|
||||
cJSON_AddStringToObject(o, "mode", cst_mode_name(cfg->mode));
|
||||
cJSON_AddStringToObject(o, "approval", cst_approval_name(cfg->approval));
|
||||
cJSON_AddStringToObject(o, "protocol_tools", cst_protocol_name(cfg->protocol));
|
||||
cJSON_AddBoolToObject(o, "plan_mode", cfg->plan_mode);
|
||||
@@ -1670,6 +1671,12 @@ static int h_settings_get(cst_http_conn_t *c, void *ud) {
|
||||
cJSON *pr = cJSON_AddArrayToObject(o, "profiles");
|
||||
for (int p = CST_TOOLS_DEFAULT; pr && p <= CST_TOOLS_MINIMAL; p++)
|
||||
cJSON_AddItemToArray(pr, cJSON_CreateString(cst_tool_profile_name(p)));
|
||||
cJSON_AddStringToObject(o, "mode", cst_mode_name(cfg->mode));
|
||||
cJSON *md = cJSON_AddArrayToObject(o, "modes");
|
||||
if (md) {
|
||||
cJSON_AddItemToArray(md, cJSON_CreateString("coding"));
|
||||
cJSON_AddItemToArray(md, cJSON_CreateString("general"));
|
||||
}
|
||||
cJSON *cf = cJSON_AddObjectToObject(o, "confirm");
|
||||
if (cf) {
|
||||
cJSON_AddBoolToObject(cf, "shell", cfg->confirm_shell);
|
||||
@@ -1728,6 +1735,7 @@ static int h_settings_x(cst_http_conn_t *c, void *ud) {
|
||||
const cJSON *proto = cJSON_GetObjectItem(j, "protocol");
|
||||
const cJSON *steps = cJSON_GetObjectItem(j, "max_steps");
|
||||
const cJSON *prof = cJSON_GetObjectItem(j, "tool_profile");
|
||||
const cJSON *mode = cJSON_GetObjectItem(j, "mode");
|
||||
const cJSON *tools = cJSON_GetObjectItem(j, "tools");
|
||||
const cJSON *conf = cJSON_GetObjectItem(j, "confirm");
|
||||
cst_protocol_t p = cfg->protocol;
|
||||
@@ -1742,6 +1750,9 @@ static int h_settings_x(cst_http_conn_t *c, void *ud) {
|
||||
else if (prof && (!cJSON_IsString(prof) ||
|
||||
cst_tool_profile_parse(prof->valuestring, &profile) != 0))
|
||||
snprintf(bad, sizeof(bad), "未知的工具集(default 或 minimal)");
|
||||
else if (mode && (!cJSON_IsString(mode) ||
|
||||
!cst_mode_valid(mode->valuestring)))
|
||||
snprintf(bad, sizeof(bad), "工作模式只能是 coding / general");
|
||||
else if (tools && !cJSON_IsObject(tools))
|
||||
snprintf(bad, sizeof(bad), "tools 要是 {\"名字\": true/false}");
|
||||
else if (conf && !cJSON_IsObject(conf))
|
||||
@@ -1760,6 +1771,11 @@ static int h_settings_x(cst_http_conn_t *c, void *ud) {
|
||||
}
|
||||
cfg->protocol = p;
|
||||
cfg->tool_profile = profile;
|
||||
if (mode) {
|
||||
snprintf(cfg->mode, sizeof(cfg->mode), "%s",
|
||||
cst_mode_name(mode->valuestring));
|
||||
cst_settings_remember_mode(cfg->mode);
|
||||
}
|
||||
if (steps)
|
||||
cfg->max_steps = (int)steps->valuedouble;
|
||||
for (const cJSON *t = tools ? tools->child : NULL; t; t = t->next)
|
||||
|
||||
Reference in New Issue
Block a user