chore: 规范标点

This commit is contained in:
pluv committed 2026-10-03 14:56:56 +08:00
1 parent 15e79887fa
commit 3dd2231c70
81 files changed
+1751 -1751

No files matched your search

+35 -35
View File
@@ -1,4 +1,4 @@
/* main.c - 入口:命令行解析、单次任务模式、交互式 REPL */
/* main.c - 入口: 命令行解析、单次任务模式、交互式 REPL */
#include "config.h"
#include "agent.h"
#include "tools.h"
@@ -41,7 +41,7 @@ static void install_signals(void)
memset(&sa, 0, sizeof sa);
sa.sa_handler = on_sigint;
sigemptyset(&sa.sa_mask);
sa.sa_flags = 0; /* 不设 SA_RESTART:让 read/fgets 被 EINTR 打断 */
sa.sa_flags = 0; /* 不设 SA_RESTART: 让 read/fgets 被 EINTR 打断 */
sigaction(SIGINT, &sa, NULL);
signal(SIGPIPE, SIG_IGN);
}
@@ -113,7 +113,7 @@ static void print_banner(const LigentConfig *c, const Agent *a)
/* 存档目录跟二进制走, 和配置同一个原则 */
static const char *g_bindir;
/* 当前对话的谱系:最近一次写出或载入的存档名 (不含 .json).
/* 当前对话的谱系: 最近一次写出或载入的存档名 (不含 .json).
* 下次存档就在它后面接一级分支, 于是文件名本身就记录了分支关系. */
static char *g_lineage;
@@ -153,7 +153,7 @@ static void auto_save(Agent *a, LigentConfig *c, const char *why,
char *path = NULL, *name = NULL;
char err[512];
/* meta 改过就另起一根:<原名>_m<3位>, parent 记空 */
/* meta 改过就另起一根: <原名>_m<3位>, parent 记空 */
int meta = meta_reroot_pending();
if (archive_export(a->messages, g_bindir ? g_bindir : ".", g_lineage,
prefix, meta, a->started_at, time(NULL),
@@ -190,12 +190,12 @@ static void apply_model(Agent *a, LigentConfig *c, const char *name)
printf("%s", tf("repl.model.switched", "model", c->model, NULL));
}
/* /model 不带参数:拉一次在线列表, 打印出来, 然后用**普通输入行**问要哪个.
/* /model 不带参数: 拉一次在线列表, 打印出来, 然后用**普通输入行**问要哪个.
*
* 刻意不用"光标选择"那种菜单:一是它会用 ANSI 反复重画、把 stdout 搅乱
* 刻意不用"光标选择"那种菜单: 一是它会用 ANSI 反复重画、把 stdout 搅乱
* (重定向、日志、粘贴都会跟着遭殃), 二是**没法输入列表里没有的东西** ——
* 而"列表里没有"恰恰很常见:内部模型、灰度模型、服务端没列出来的别名.
* 所以这里是 /import 那一套:列表打在上面, 输入行里既可以填序号, 也可以
* 而"列表里没有"恰恰很常见: 内部模型、灰度模型、服务端没列出来的别名.
* 所以这里是 /import 那一套: 列表打在上面, 输入行里既可以填序号, 也可以
* 直接写模型名, 回车取消.
*
* 拉不到列表就明说原因, 并提示还能直接用 /model <名字> —— 不能因为网络不行
@@ -267,7 +267,7 @@ static int include_can_image(void *ud)
Agent *a = ud;
agent_ensure_caps(a);
/* 只有**明确不支持**才拦. 未测 (探测被关掉或结论不确定)按支持放行,
* 和别处一个原则:宁可让服务端说不行, 也不错误地藏掉东西. */
* 和别处一个原则: 宁可让服务端说不行, 也不错误地藏掉东西. */
return a->caps.vision != CAP_NO;
}
@@ -344,7 +344,7 @@ static void cmd_export(Agent *a, LigentConfig *c)
free(name);
}
/* 按名字找一份存档:支持完整文件名、不含 .json 的名字、以及唯一前缀 */
/* 按名字找一份存档: 支持完整文件名、不含 .json 的名字、以及唯一前缀 */
static const ArchiveEntry *find_entry(const ArchiveEntry *list, size_t n,
const char *want)
{
@@ -361,9 +361,9 @@ static const ArchiveEntry *find_entry(const ArchiveEntry *list, size_t n,
return hit;
}
/* 载入存档:给了名字就直接载入, 否则交互式选一份.
/* 载入存档: 给了名字就直接载入, 否则交互式选一份.
* 只把历史装回去, 不重放历史内容. */
/* 问一个是非题, (Y/n) 语义:直接回车算"是".
/* 问一个是非题, (Y/n) 语义: 直接回车算"是".
* 非终端时没人能回答, 按默认值返回 1 —— 和 confirm_tool 一致. */
static int ask_yes_no(const char *question)
{
@@ -384,7 +384,7 @@ static int ask_yes_no(const char *question)
/* /import 载入后用户可能想看看这段历史到底聊了什么.
*
* 这里是**完整**转储:不截断正文、不省略工具参数、不砍总量. 既然用户
* 这里是**完整**转储: 不截断正文、不省略工具参数、不砍总量. 既然用户
* 明确回答了 Y, 就该看到全部 —— 截一半反而会让人以为历史里就这么点东西.
* 所以只做排版, 不做取舍.
*
@@ -530,10 +530,10 @@ static void cmd_import(Agent *a, const char *arg)
}
char *loaded = xstrdup(pick->name);
agent_replace_history(a, msgs); /* 取得所有权 */
/* 载入之后再数:换成和 /history 一样的口径 (不含 system),
/* 载入之后再数: 换成和 /history 一样的口径 (不含 system),
* 否则"已载入 N 条"和"历史消息 M 条"会差 1, 看着像出了错 */
size_t count = agent_conversation_len(a);
/* 输入历史不跟着清:它现在是一份持久的、跨会话的用户资源 (像 bash 的
/* 输入历史不跟着清: 它现在是一份持久的、跨会话的用户资源 (像 bash 的
* HISTFILE), 记的是"我在 ligent> 敲过什么", 和当前装的是哪段对话无关. */
set_lineage(loaded); /* 之后的分支都挂在它下面 */
printf("%s", tf("repl.import.done", "name", loaded,
@@ -551,7 +551,7 @@ static void repl_help(void)
fputs(t("repl.help"), stdout);
}
/* 带参数命令的匹配:/name 之后必须是空白或字符串结束.
/* 带参数命令的匹配: /name 之后必须是空白或字符串结束.
*
* 只用前缀匹配是不够的 —— 那样 "/modelxxx" 会被当成 "/model" 并把 xxx
* 当作模型名去切模型, "/thinkfoo" 也会落进 /think 分支. 命中返回参数起点
@@ -583,7 +583,7 @@ static int handle_command(Agent *a, LigentConfig *c, const char *line)
auto_save(a, c, t("repl.why.before_reset"), NULL);
agent_reset(a);
/* 刚存的是"上一段"对话, 和新开的这段没关系了, 所以把判重状态清掉.
* 不清的话会漏存:判重只看 (条数, started_at), 而 time() 只有秒级
* 不清的话会漏存: 判重只看 (条数, started_at), 而 time() 只有秒级
* 精度 —— 同一秒里重置、又聊出同样多条消息, 退出时就会被当成
* "内容没变"而跳过存档. */
g_saved_count = 0;
@@ -631,12 +631,12 @@ static int handle_command(Agent *a, LigentConfig *c, const char *line)
? c->reasoning_effort : t("cfg.val.server_default"));
}
} else if (strcmp(cmd, "/meta") == 0) {
/* 进 meta 前先留一份保底存档:里面全是不可逆的删改.
* 用 tmp_ 前缀, 免得它变成以后分支的祖先. */
/* 进 meta 前先留一份保底存档: 里面全是不可逆的删改.
* 用 tmp_ 前缀, 以免它变成以后分支的祖先. */
auto_save(a, c, t("repl.why.before_meta"), ARCHIVE_TMP_PREFIX);
int r = meta_session(a, c);
if (r == 1) {
/* 历史被改过:/back 的撤销栈基于旧历史, 作废;
/* 历史被改过: /back 的撤销栈基于旧历史, 作废;
* 存档判重也清掉, 保证退出时一定存下这个新版本. */
back_undo_clear();
g_saved_count = 0;
@@ -723,14 +723,14 @@ static int handle_command(Agent *a, LigentConfig *c, const char *line)
}
} else if ((arg = cmd_arg(cmd, "/shell")) != NULL) {
if (*arg) {
/* 带参数:直接执行它, 不进入交互式 shell */
/* 带参数: 直接执行它, 不进入交互式 shell */
JsonValue *args = json_new_object();
json_object_set_string(args, "command", arg);
int is_err = 0;
char *r = tool_execute(TOOL_RUN_COMMAND, args, &is_err);
json_free(args);
puts(r);
char *msg = xasprintf("我在 shell 里执行了:%s\n\n结果是:\n%s",
char *msg = xasprintf("我在 shell 里执行了: %s\n\n结果是: \n%s",
arg, r);
agent_add_user(a, msg);
free(msg);
@@ -746,7 +746,7 @@ static int handle_command(Agent *a, LigentConfig *c, const char *line)
} else {
if (rec[0]) {
char *msg = xasprintf(
"我在交互式 shell 里做了以下操作 (shell 退出码 %d):\n\n"
"我在交互式 shell 里做了以下操作 (shell 退出码 %d): \n\n"
"```console\n%s\n```\n", code, rec);
agent_add_user(a, msg);
printf("\n%s\n",
@@ -792,7 +792,7 @@ static int handle_command(Agent *a, LigentConfig *c, const char *line)
* 而下面列出来的是**含** system 的全部消息 —— 两个数不一样, 所以必须
* 说清楚, 否则用户会以为打印漏了或者多了一条.
*
* 为什么要连 system 一起列:那是"模型被要求怎么做"的原文, 想核对提示词
* 为什么要连 system 一起列: 那是"模型被要求怎么做"的原文, 想核对提示词
* 时只有这里能看到全文 (/config 里那行会把多行提示词挤成一团). */
printf("%s", tf("repl.history.count", "n",
i18n_num((long long)agent_conversation_len(a)), NULL));
@@ -813,12 +813,12 @@ static int handle_command(Agent *a, LigentConfig *c, const char *line)
/* 输入历史文件; NULL 表示禁用 (--no-history). */
static char *g_hist_path = NULL;
/* 提示符保持纯文本:绿色由行编辑器统一加在整个输入行 (提示符 + 你敲的字)上.
/* 提示符保持纯文本: 绿色由行编辑器统一加在整个输入行 (提示符 + 你敲的字)上.
* 在这里塞颜色的话, 提示符自带的 reset 会让后面的输入掉回默认色. */
#define PROMPT_MAIN "ligent> "
#define PROMPT_CONT " ... "
/* 读一条完整输入. 支持行尾反斜杠续行:每段都由行编辑器独立编辑,
/* 读一条完整输入. 支持行尾反斜杠续行: 每段都由行编辑器独立编辑,
* 因此方向键、Home/End、历史在续行的每一段里都可用. */
static char *read_prompt_line(const char *prompt, int *interrupted)
{
@@ -839,7 +839,7 @@ static char *read_prompt_line(const char *prompt, int *interrupted)
sb_free(&sb);
return NULL;
}
/* EOF:缓冲区里还有内容就把它交出去, 否则终止 */
/* EOF: 缓冲区里还有内容就把它交出去, 否则终止 */
if (sb.len > 0) {
if (sb.data[sb.len - 1] != '\n') sb_putc(&sb, '\n');
return sb_detach(&sb);
@@ -863,7 +863,7 @@ static char *read_prompt_line(const char *prompt, int *interrupted)
free(seg);
if (!cont) {
sb_putc(&sb, '\n');
/* 历史记的是"这一整条输入":多行续行算一条, 上下键能整条召回.
/* 历史记的是"这一整条输入": 多行续行算一条, 上下键能整条召回.
* 续行的中间段不单独记. 这里借尾部那个换行临时当结束符. */
if (sb.len > 1) {
sb.data[sb.len - 1] = '\0';
@@ -930,7 +930,7 @@ int main(int argc, char **argv)
const char *explicit_config = NULL;
char err[512];
/* 界面语言:--lang > LIGENT_LANG > LC_ALL/LC_MESSAGES/LANG > 英文.
/* 界面语言: --lang > LIGENT_LANG > LC_ALL/LC_MESSAGES/LANG > 英文.
* 先粗扫一遍 argv, 好让 --help 和 --lang 的先后顺序不影响结果 ——
* 解析循环一遇到 --help 就直接返回, 那之后再写 --lang 就来不及了. */
{
@@ -1054,7 +1054,7 @@ int main(int argc, char **argv)
} else if (strcmp(arg, "--stream") == 0) {
cli.stream_set = 1; cli.stream_val = 1;
} else if (strcmp(arg, "doctor") == 0 && !cli.doctor && cli.prompt.len == 0) {
cli.doctor = 1; /* 子命令:ligent doctor */
cli.doctor = 1; /* 子命令: ligent doctor */
} else if (strcmp(arg, "--offline") == 0) {
cli.offline = 1;
} else if (strcmp(arg, "--no-confirm") == 0) {
@@ -1088,7 +1088,7 @@ int main(int argc, char **argv)
fprintf(stderr, "%s", tf("cli.err.bad_lang", "value", val, NULL));
return 2;
}
i18n_init(l); /* "auto" 也是 -1:交给环境探测 */
i18n_init(l); /* "auto" 也是 -1: 交给环境探测 */
} else if (strcmp(arg, "--print-config") == 0) {
cli.print_config = 1;
} else if (strcmp(arg, "--") == 0) {
@@ -1107,7 +1107,7 @@ int main(int argc, char **argv)
#undef NEED_VAL
}
/* 配置:默认值 → 文件 → 环境变量 → 命令行 */
/* 配置: 默认值 → 文件 → 环境变量 → 命令行 */
/* doctor 要能在"配置本身坏了"的时候跑起来 —— 那正是最需要它的时刻 */
char cfg_error[512];
cfg_error[0] = '\0';
@@ -1198,7 +1198,7 @@ int main(int argc, char **argv)
g_bindir = cfg.config_dir;
image_set_bindir(cfg.config_dir); /* 理由见 run_repl 里那段注释 */
/* 输入历史文件:命令行 > 环境变量 > <二进制目录>/ligent.history.
/* 输入历史文件: 命令行 > 环境变量 > <二进制目录>/ligent.history.
* 和配置一样, 默认只放二进制旁边, 不碰用户级/系统级目录. */
{
const char *env = getenv("LIGENT_HISTORY");
@@ -1211,7 +1211,7 @@ int main(int argc, char **argv)
} else {
g_hist_path = xasprintf("%s/ligent.history", cfg.config_dir);
}
/* 读不回来不是错误:第一次跑本来就没有这个文件, 只读的目录也不该
/* 读不回来不是错误: 第一次跑本来就没有这个文件, 只读的目录也不该
* 拦住 REPL. 加载失败静默降级成"这次没有历史". */
if (g_hist_path) line_history_load(g_hist_path, LIGENT_HISTORY_KEEP);
}
@@ -1223,7 +1223,7 @@ int main(int argc, char **argv)
exit_code = rc == 0 ? 0 : 1;
auto_save(&agent, &cfg, t("repl.why.exit"), NULL);
} else if (!isatty(fileno(stdin))) {
/* 管道输入:把 stdin 当任务 */
/* 管道输入: 把 stdin 当任务 */
char *text = read_stdin_all();
char *trimmed = str_trim(text);
if (*trimmed) {