@epoch-agent/infra 0.2.0 → 0.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +128 -12
- package/dist/index.js +52 -6
- package/dist/locales/en.yaml +156 -22
- package/dist/locales/zh.yaml +157 -23
- package/package.json +4 -4
package/dist/locales/zh.yaml
CHANGED
|
@@ -249,6 +249,10 @@ web:
|
|
|
249
249
|
mkdir_parent_not_absolute: 要在哪儿建必须给一条绝对路径:{parent}
|
|
250
250
|
mkdir_bad_name: 目录名只能是一段名字,不能带路径分隔符,也不能是 . 或 ..:{name}
|
|
251
251
|
mkdir_failed: 建不出这个目录:{path}
|
|
252
|
+
pick_prompt: 选一个工作区目录
|
|
253
|
+
pick_unavailable: 这台机器上弹不出系统目录框:它只在服务端和浏览器同机时才开(回环绑定、不是 ssh 起的、平台是 macOS 或 Windows)—— 用逐层浏览那一屏挑
|
|
254
|
+
pick_busy: 已经有一个目录选择框开着了 —— 去把它答掉(它可能被这扇窗口盖住了)
|
|
255
|
+
pick_failed: 系统目录框弹不出来:{detail}
|
|
252
256
|
plan_mode_unavailable: 这个进程没有 plan 模式(权限层没起来)
|
|
253
257
|
plan_mode_bad_action: action 必须是 {actions} 之一
|
|
254
258
|
permission_unavailable: 这个进程没有权限层,档位改不了(它此刻显示的是配置里那一档)
|
|
@@ -260,7 +264,7 @@ web:
|
|
|
260
264
|
rewind_bad_overwrite: overwrite 必须是一组文件路径(用户逐个确认过的那几个);没有要覆盖的就整个别给这个字段
|
|
261
265
|
rewind_no_checkpoint: 没有第 {turn} 轮的检查点
|
|
262
266
|
settings_write_bad_request: 请求体要有 key(设置项的点分路径)、layer({layers} 之一)和 value(字符串 / 数字 / 布尔)
|
|
263
|
-
settings_write_unknown_key:
|
|
267
|
+
settings_write_unknown_key: 这个键这样改不了:要么它压根不在可写名单里(比如降级链 —— 它是一条有序的链,不是一个标量),要么这个键只写得进用户级、而请求写的是项目本地。项目级那两层只认 permissions / model / maxTurns,别的键写进去会被启动诊断报成「未知配置项」
|
|
264
268
|
settings_write_bad_value: 这个值不合这一项的值域(比如 maxTurns 要正整数),没有写进去
|
|
265
269
|
settings_write_unwritable: '{path} 这份文件这一层认不出它的写法(或者它已经坏了),没有覆盖它 —— 请自己编辑那个文件'
|
|
266
270
|
settings_write_io: 写 {path} 失败:可能是没有写权限,或者那个目录建不出来
|
|
@@ -268,6 +272,8 @@ web:
|
|
|
268
272
|
mcp_unknown_server: 这个进程里没有名为「{name}」的 MCP server —— 连接是启动时按 mcp.json 建的,你手上这份清单可能已经旧了,刷新一下再看
|
|
269
273
|
skill_unknown: 没有名为「{name}」的技能 —— 能力页那份列表可能已经旧了,刷新一下再看
|
|
270
274
|
provider_unknown: 不支持名为「{name}」的 provider —— 可选的那几家是一份固定清单,你手上这份可能已经旧了,刷新一下再看
|
|
275
|
+
provider_key_not_applicable: '{name} 不用 API key —— 配一把进去也不会有人读它,这家现在就是通的'
|
|
276
|
+
provider_key_empty: 没收到 key —— 把它粘进那个框再保存。(想撤掉已经配好的那把,这一版还没有入口,去 ~/.epoch 或者钥匙串里删)
|
|
271
277
|
mcp_add_lan_exposed: 这一档下加不了 MCP server —— 服务是用 --host 绑到回环之外的,而我们没法确认发出这一下的浏览器就在这台机器上。加一台等于往 mcp.json 里写一条「启动哪个可执行文件」,而那台当场就会被起起来,往后这台机器上每一次跑 epoch(含 CLI 和 TUI)也都会照着它起。出路两条:到跑着服务的那台机器上直接改那个文件;或者去掉 --host 重启一次。
|
|
272
278
|
mcp_add_bad_transport: 传输类型只能是 stdio / sse / http
|
|
273
279
|
mcp_add_bad_name: server 名「{name}」不能用 —— 它会原样变成工具名的一部分,所以只收字母数字开头、由字母数字和 _ - 组成的名字(最长 48)。手写 mcp.json 不受这条管,这条只管从界面加的
|
|
@@ -301,6 +307,17 @@ web:
|
|
|
301
307
|
reference_store_unavailable: 这台机器上没有会话库(SQLite 没起来),引用不了历史会话
|
|
302
308
|
file_candidates_no_workspace: 这个会话还没有绑工作区,列不了文件 —— 先在输入框底栏挑一个目录
|
|
303
309
|
file_list_unavailable: 工作区文件清单列不出来(没有 .git 也不是可读目录),补全用不了 —— 路径手打照样能附上
|
|
310
|
+
file_view_no_workspace: 这个会话还没有绑工作区,看不了文件 —— 先在输入框底栏挑一个目录
|
|
311
|
+
file_view_missing_path: 没说要看哪个文件(缺 path)
|
|
312
|
+
file_view_denied: 这个文件不在工作区里,或者被权限规则拦住了 —— 模型读不到的文件,这儿也看不到
|
|
313
|
+
file_view_missing: 这个文件现在不在那儿了
|
|
314
|
+
file_view_not_a_file: 这是一个目录,不是文件
|
|
315
|
+
file_view_unreadable: 这个文件读不出来(权限位、正在被写、或者盘出了问题)
|
|
316
|
+
file_view_too_large: 这个文件太大,站内看不了(上限 {max} 字节)—— 用默认应用打开,或者下载下来看
|
|
317
|
+
file_view_not_text: 这不是文本文件,取不到正文 —— 图片 / PDF / 媒体走字节那条路
|
|
318
|
+
file_open_extension_not_allowed: 这种文件不交给系统应用打开 —— 代码和文本站内就能看,而压缩包「打开」等于解压
|
|
319
|
+
file_open_not_same_machine: 这个浏览器不在服务那台机器上,打开了窗口也弹在别人屏幕上
|
|
320
|
+
file_open_launch_failed: 系统应用没起来
|
|
304
321
|
ui:
|
|
305
322
|
conn:
|
|
306
323
|
connecting: 连接中
|
|
@@ -325,24 +342,39 @@ web:
|
|
|
325
342
|
rej_context: 上下文已用 {used},超过 {model} 的窗口({window})。先开一段新会话,或者换个窗口更大的模型
|
|
326
343
|
cav_context_tight: 换过去了,但上下文已用 {used},接近 {model} 的窗口({window}),可能撑不过几轮
|
|
327
344
|
cav_no_tools: 换过去了,但 {model} 不支持工具调用 —— 它只能聊天,读不了也写不了文件
|
|
328
|
-
pick_provider:
|
|
345
|
+
pick_provider: 提供商
|
|
329
346
|
pick_provider_none: 挑一家…
|
|
347
|
+
pick_model: 模型名称
|
|
348
|
+
suggest_open: 看看探到了哪些模型
|
|
330
349
|
provider_no_key: '{label}(没配 key)'
|
|
331
350
|
probe_probing: 正在问 {provider} 有哪些模型…不用等,上面直接敲一个也行
|
|
332
351
|
probe_no_key: '{provider} 还没配 key,问不了它的模型清单。设一个 {env},或者跑 epoch model 配一把'
|
|
333
352
|
probe_no_key_bare: '{provider} 还没配 key,问不了它的模型清单。跑 epoch model 配一把'
|
|
353
|
+
probe_no_key_here: '{provider} 还没配 key,问不了它的模型清单 —— 上面那个 API Key 框填一把就行'
|
|
354
|
+
key_goto: 去设置页配
|
|
334
355
|
probe_failed_cache: 没问通 {provider}(网络 / key 不对 / 那个地址没有 /models)。下面是上次探到的那一份,可能已经过期 —— 也可以直接敲
|
|
335
356
|
probe_failed_static: 没问通 {provider}(网络 / key 不对 / 那个地址没有 /models)。下面是内置的那一份,可能已经过期 —— 也可以直接敲
|
|
336
357
|
probe_empty: '{provider} 一个模型名都没给出来,内置清单里也是空的 —— 直接敲一个吧'
|
|
337
358
|
probe_ok: 从 {provider} 问到 {count} 个
|
|
338
|
-
suggest_note:
|
|
359
|
+
suggest_note: 这些是探到的建议,不是全部 —— 新模型、自建的多半不在里面,照旧直接敲
|
|
339
360
|
refresh: 重新探
|
|
340
361
|
refresh_hint: 绕开缓存,重新问一次这家 provider
|
|
362
|
+
key_label: API Key
|
|
363
|
+
key_placeholder: 粘一把 key 进来
|
|
364
|
+
key_save: 保存 Key
|
|
365
|
+
key_saving: 存 Key…
|
|
366
|
+
key_show: 显示
|
|
367
|
+
key_hide: 隐藏
|
|
368
|
+
key_has: 已配置 {hint}({env})。存一把新的会盖掉它
|
|
369
|
+
key_none: 这把 key 优先进系统钥匙串;拿不到钥匙串才落 ~/.epoch/.env(0600)。写进去的是 {env}
|
|
370
|
+
key_saved_secure: 已存进 {backend}(加密)。模型清单已经用新 key 重新问过一遍了
|
|
371
|
+
key_saved_plain: ⚠️ 系统钥匙串用不了,这把 key 以明文存在了 {path}(权限 0600)。同机器上能读到这个文件的人就能拿到它
|
|
341
372
|
newsession:
|
|
342
373
|
open: 新建会话
|
|
343
374
|
dirpick:
|
|
344
375
|
back: 返回
|
|
345
376
|
anchors: 常去的地方
|
|
377
|
+
anchors_detail: 主目录、服务进程的启动目录、以及来过的工作区
|
|
346
378
|
up: 往上一层
|
|
347
379
|
loading: 读取中…
|
|
348
380
|
empty: 这一层没有子目录 —— 可以直接挑它,或者在下面敲一条路径
|
|
@@ -350,7 +382,10 @@ web:
|
|
|
350
382
|
show_hidden: 显示隐藏目录(. 开头的)
|
|
351
383
|
show_hidden_count: 显示隐藏目录(. 开头的,这一层有 {count} 个)
|
|
352
384
|
unreadable: 没权限进这个目录:{path}
|
|
353
|
-
|
|
385
|
+
into_of: 进入 {name}({path})
|
|
386
|
+
use: 就用 {name}
|
|
387
|
+
use_here: 就选这一层
|
|
388
|
+
use_here_of: 就选这一层:{path}
|
|
354
389
|
known: 来过
|
|
355
390
|
manual_label: 或者直接敲一条绝对路径
|
|
356
391
|
manual_hint: 例如 /Users/you/work/repo
|
|
@@ -363,14 +398,10 @@ web:
|
|
|
363
398
|
title: 今天想做点什么?
|
|
364
399
|
sidebar:
|
|
365
400
|
search: 搜索会话
|
|
366
|
-
capability: 身份 · 技能 · 连接器
|
|
367
|
-
plugins: 插件
|
|
368
401
|
automation: 自动化
|
|
369
402
|
automation_pending: 有 {count} 条定时任务欠着授权,到点了会再卡一次
|
|
370
403
|
settings: 设置
|
|
371
|
-
|
|
372
|
-
usage_session: 本会话用量
|
|
373
|
-
usage_run: 最近一轮用量
|
|
404
|
+
host_menu: 宿主菜单
|
|
374
405
|
cost: 花费
|
|
375
406
|
cost_of: 约 ${spent} / ${limit}
|
|
376
407
|
cost_est: 估算
|
|
@@ -386,6 +417,7 @@ web:
|
|
|
386
417
|
running: 进行中
|
|
387
418
|
updated_at: 最近活动
|
|
388
419
|
count: '{count} 条会话'
|
|
420
|
+
new_in_space: 在「{name}」里开一段新会话
|
|
389
421
|
empty: 还没有会话
|
|
390
422
|
no_match: 没有匹配的会话
|
|
391
423
|
acts: 会话「{title}」的操作
|
|
@@ -457,6 +489,18 @@ web:
|
|
|
457
489
|
clip_lines: 只显示了前 {shown} 行,这个文件一共 {total} 行。
|
|
458
490
|
clip_chars: 在第 {line} 行上截断了 —— 这一行太长。这个文件一共 {total} 行。
|
|
459
491
|
binary_note: 这类文件这儿看不了,用系统自带的程序打开。
|
|
492
|
+
file:
|
|
493
|
+
loading: 正在打开…
|
|
494
|
+
denied: 这个文件不在工作区里,或者被权限规则拦住了 —— 模型读不到的文件,这儿也看不到。
|
|
495
|
+
missing: 这个文件现在不在那儿了。
|
|
496
|
+
not_a_file: 这是一个目录,不是文件。
|
|
497
|
+
too_large: 这个文件太大,站内看不了。
|
|
498
|
+
unreadable: 这个文件读不出来。
|
|
499
|
+
no_answer: 服务端没有回答这条路径。
|
|
500
|
+
no_session: 还没有会话,看不了文件。
|
|
501
|
+
opaque: 这种文件浏览器画不出来。用你机器上的默认应用打开,或者下载下来看。
|
|
502
|
+
open_with_app: 用默认应用打开
|
|
503
|
+
download: 下载
|
|
460
504
|
plan:
|
|
461
505
|
empty: 这个会话还没有被批准的计划
|
|
462
506
|
empty_hint: 模型交上来的计划要你在输入区那块板上批一次;批过的那一份才会留在这儿。
|
|
@@ -506,7 +550,7 @@ web:
|
|
|
506
550
|
dismiss: 知道了
|
|
507
551
|
session_gone: 这段对话在服务端上已经没有了 —— 多半是服务端重启过,重启会换一个新会话。这一段回不来了,不过新的那个可以接着用。
|
|
508
552
|
session_gone_open: 去当前会话
|
|
509
|
-
session_gone_stuck:
|
|
553
|
+
session_gone_stuck: 这段对话在服务端上已经没有了。
|
|
510
554
|
thread:
|
|
511
555
|
thinking_label: 深度思考
|
|
512
556
|
head_estimate: 预计 {tokens} token
|
|
@@ -539,6 +583,8 @@ web:
|
|
|
539
583
|
art_no_file: 没能落盘 —— 这个产物打不开。
|
|
540
584
|
art_download: 下载 {name}
|
|
541
585
|
art_download_any: 下载这个产物
|
|
586
|
+
user_image_alt: 这条消息附的图片({mediaType})
|
|
587
|
+
user_image_alt_any: 这条消息附的图片
|
|
542
588
|
expand: 展开剩余 {count} 行
|
|
543
589
|
collapse: 收起
|
|
544
590
|
todo_title: 交付清单
|
|
@@ -662,6 +708,7 @@ web:
|
|
|
662
708
|
stalled: 《{title}》原地打转,已经停下
|
|
663
709
|
aborted: 《{title}》被中止了
|
|
664
710
|
filtered: 《{title}》被模型拒答了
|
|
711
|
+
compliance: 《{title}》触了内容合规限制
|
|
665
712
|
budget: 《{title}》触了预算上限,提前收工
|
|
666
713
|
failed: 《{title}》出错了
|
|
667
714
|
go: 查看
|
|
@@ -686,6 +733,9 @@ web:
|
|
|
686
733
|
placeholder_gone: 这段对话在服务端上已经没有了,发不出去
|
|
687
734
|
hint_queue: 排队发送
|
|
688
735
|
send: 发送
|
|
736
|
+
usage_session: 本会话
|
|
737
|
+
usage_run: 最近一轮
|
|
738
|
+
usage_detail: '{scope}用量:{up}↑ {down}↓'
|
|
689
739
|
commands_label: 斜杠命令
|
|
690
740
|
command_warnings: /{name} 展开时有几处要说明:
|
|
691
741
|
builtin_notice: /{name}
|
|
@@ -705,7 +755,8 @@ web:
|
|
|
705
755
|
workspace_pick_note: 清单是本机最近用过的那几个目录。要在一个没来过的目录里开会话,先在那儿跑一次 epoch。
|
|
706
756
|
workspace_browse: 打开本地文件夹…
|
|
707
757
|
workspace_browse_detail: 逐层挑一个目录,或者直接敲一条绝对路径(列的是跑 epoch 那台机器上的目录)
|
|
708
|
-
|
|
758
|
+
workspace_browse_native: 弹一个系统对话框来挑(跑 epoch 那台机器上的)
|
|
759
|
+
permission: 权限:{level}
|
|
709
760
|
plan_mode: 计划模式
|
|
710
761
|
plan_on_hint: 进计划模式:模型先只读地调研、交一份计划给你批,期间不动文件
|
|
711
762
|
plan_off_hint: 退出计划模式,回到进入前那一档权限
|
|
@@ -757,6 +808,10 @@ web:
|
|
|
757
808
|
lvl_bypass: 跳过全部检查
|
|
758
809
|
lvl_bypass_detail: 什么都不问,整条导轨会变红
|
|
759
810
|
blocked_managed: 这台机器装了企业托管设置,「跳过全部检查」那一档被它关掉了。详情见「设置 › 安全中心」
|
|
811
|
+
keep_env_pinned: 这一档只对当前这次有效:环境变量 EPOCH_PERMISSION 压着它,下次启动还是按那个来
|
|
812
|
+
keep_unwritable: 这一档只对当前这次有效:配置文件的写法这条路认不出来,没敢改它
|
|
813
|
+
keep_io: 这一档只对当前这次有效:配置文件没写成(盘是只读的,或者没有权限)
|
|
814
|
+
keep_no_config: 这一档只对当前这次有效:这个进程说不出用户配置文件在哪儿
|
|
760
815
|
fatal:
|
|
761
816
|
unauthorized: 没有访问凭据
|
|
762
817
|
unauthorized_hint: 回到起 epoch web 的那个终端,用它打印的那条带 token 的地址重新打开。
|
|
@@ -768,6 +823,7 @@ web:
|
|
|
768
823
|
pane_model: 模型与 Provider
|
|
769
824
|
pane_memory: 记忆与上下文
|
|
770
825
|
pane_spend: 用量与花费
|
|
826
|
+
history_only: 这段会话只剩历史,引擎还没装起来 —— 点开一段旧会话只回放对话,装引擎要等你发下一条消息。这一屏问的是那台引擎此刻的状态,所以现在没有东西可看:回到会话里发一条,它会自己接回来。
|
|
771
827
|
pane_budget: 预算
|
|
772
828
|
pane_tools: 工具
|
|
773
829
|
pane_about: 关于
|
|
@@ -793,8 +849,6 @@ web:
|
|
|
793
849
|
none_recorded: 这段对话跑过,但每一轮的账没有被记下来(这段会话早于记账那一次改动)。这些数字不会自己回来。
|
|
794
850
|
g_total: 合计
|
|
795
851
|
g_turns: 逐轮
|
|
796
|
-
total: 这 {turns} 轮一共 {tokens} token,约 {cost}。
|
|
797
|
-
total_tokens: 这 {turns} 轮一共 {tokens} token。
|
|
798
852
|
total_unmeasured: 这段会话跑了 {turns} 轮,但一轮的用量都没报上来,所以连 token 总数也没有。
|
|
799
853
|
partial: 上面这个金额只是其中 {priced} 轮的和 —— 另外 {unpriced} 轮报了用量,但那些轮用的模型查不到单价。下面那张表里费用那一格空着的就是它们。
|
|
800
854
|
unknown: 金额说不上来,不是没花钱:这几轮用的模型在这台机器上查不到单价,花了多少只有 provider 那一边知道。
|
|
@@ -820,6 +874,7 @@ web:
|
|
|
820
874
|
why: 为什么是这个值
|
|
821
875
|
chain_win: 生效
|
|
822
876
|
g_other: 其它
|
|
877
|
+
overridable_sum: 哪些键能被上层压过
|
|
823
878
|
overridable: 只有这几个键能被项目级 / 项目本地 / 命令行 / 企业托管压过去:{keys}。其余每一项都只有内置默认和用户级两层 —— 写进 .epoch/settings.json 也不会生效,启动诊断里会报一条「未知配置项」。
|
|
824
879
|
overridable_perm: 名单里的 permissions 是三张列表(allow / ask / deny),合并时取并集而不是高层覆盖,所以它的来源标注是逐条的 —— 在「安全中心 › 权限规则」那一节。
|
|
825
880
|
managed_locked: 这一项由这台机器上的企业托管设置定,改用户级或项目级都不会生效。那份文件普通用户写不了,要改得找管理员。
|
|
@@ -828,12 +883,13 @@ web:
|
|
|
828
883
|
save: 保存
|
|
829
884
|
new_value: 新的值
|
|
830
885
|
write_layer: 写进
|
|
886
|
+
write_file: 写进文件
|
|
831
887
|
dirty: 未保存
|
|
832
888
|
futile_shadowed: 写进{layer}也不会生效:{by}也写了这一项,它排在更上面,加载时会把你写的这个压回去。要让它生效,请改写{by}或更高的层。
|
|
833
889
|
futile_untrusted: 这个工作区还没被信任,{layer}里的设置在加载时会被整份丢掉(只有 deny 规则例外),所以写进去等于没写。先在「安全中心 › 工作区与信任」里信任这个目录,或者改写用户级 —— 用户级不过信任闸门。
|
|
834
890
|
wrote: 已写进{layer}:{value}
|
|
835
891
|
wrote_stale: 这个进程启动时读过一次配置就不再重读,所以它现在用的仍然是 {value} —— 重启 epoch web 之后才会换成刚写的那个值。新开一个会话也不行,配置是整个进程一份。
|
|
836
|
-
lede_model:
|
|
892
|
+
lede_model: 这个进程此刻在用的模型。改这里的行会写进 ~/.epoch/config.yaml。provider 和 API key 不在这一屏上 —— 那两样跑 epoch model 配。
|
|
837
893
|
k_model: 主模型
|
|
838
894
|
k_models_utility: 副模型
|
|
839
895
|
h_models_utility: 压缩上下文、生成会话标题这类杂活用它。没配就一律走主模型。
|
|
@@ -841,7 +897,7 @@ web:
|
|
|
841
897
|
k_fallback_providers: 降级链
|
|
842
898
|
h_fallback_providers: 主 provider 连不上时按这个顺序往下试。
|
|
843
899
|
lede_memory: 前两项决定一轮能装多少、能跑多少步;后两项决定装不下的时候怎么办。上下文窗口填大于模型真实上限的值只会换来一次 400。
|
|
844
|
-
k_context_length:
|
|
900
|
+
k_context_length: 上下文窗口(token)
|
|
845
901
|
h_context_length: 只在模型元数据查不到时才用这个值兜底;查得到就以元数据为准,填了也不生效。下面那条压缩线算的是引擎真在用的那个窗口。
|
|
846
902
|
k_max_turns: 单轮最多几步
|
|
847
903
|
h_max_turns: 一轮里模型最多调用几次工具。到顶就停下来把话说完。
|
|
@@ -852,8 +908,7 @@ web:
|
|
|
852
908
|
ctx_line: 这份配置下,提示词涨到 {tokens} token 时开始压缩 —— 上下文窗口 {window} 的 {percent}%。
|
|
853
909
|
ctx_line_caveat: 这是那条线本身。刚压过不久、或者连着几次压缩都失败时,跨线了也会先不压。
|
|
854
910
|
ctx_off: 自动压缩已关掉。长会话撞到上下文窗口上限时没有任何自动补救 —— 那一轮会直接失败,而且上下文不会自己变短。手动的 /compact 不受这个开关影响,仍然能用。
|
|
855
|
-
|
|
856
|
-
ctx_restart: 改完要重启 epoch web 那个进程才生效 —— 这个进程装配时读过一次配置就不再重读。
|
|
911
|
+
ctx_not_overridable: 这两行只写得进用户级:能被项目级配置覆盖的键只有那三个(下面那份名单),压缩不在里面 —— 否则一个仓库就能让你在它里面开的长会话悄悄撞满窗口。
|
|
857
912
|
budget_title: 此刻花在哪儿了
|
|
858
913
|
budget_used: 已用 {used},占 {limit} 窗口的 {percent}%。
|
|
859
914
|
budget_used_only: 已用 {used}。这个模型的上下文窗口查不到,所以说不出占了几成。
|
|
@@ -863,13 +918,21 @@ web:
|
|
|
863
918
|
budget_compacting: 正在压缩…
|
|
864
919
|
budget_compact_hint: 把早期消息重写成一份摘要,给接下来的对话腾出窗口。要发一次模型请求(花钱),但这段对话的记录一行都不会少 —— 变的只是下一轮送进模型的那一份。
|
|
865
920
|
lede_budget: 金额只在配了上限之后才出现在界面上。没配上限时这几行都是「未设置」,那也是默认状态。
|
|
866
|
-
k_budget_max_cost:
|
|
921
|
+
k_budget_max_cost: 花费上限(美元)
|
|
922
|
+
h_budget_max_cost: 按会话累计,不是单次请求的上限 —— 断了用 --resume 回来接着算。到线的那一轮不会先花掉再报:闸门在发下一发请求之前就拦。
|
|
867
923
|
k_budget_max_tokens: Token 上限
|
|
868
924
|
h_budget_max_tokens: 两把尺子都配了的话,闸门报更紧的那一份。
|
|
869
925
|
k_budget_warn_at: 用到几成时提醒
|
|
870
926
|
h_budget_warn_at: 百分比。只在跨线那一次提醒,不每轮刷屏。
|
|
871
927
|
k_budget_unknown_pricing: 模型没有定价数据时
|
|
872
928
|
h_budget_unknown_pricing: block 是直接拦下,warn 是告警放行。没有定价数据时花费是「不知道」而不是 0,两者必须分开处理。
|
|
929
|
+
ex_budget_max_cost: 例如 5
|
|
930
|
+
ex_budget_max_tokens: 例如 1000000
|
|
931
|
+
ex_budget_warn_at: 例如 80
|
|
932
|
+
blocked_empty: 这一格不能空着。清空不等于把这个配置项删掉 —— 这条路上没有删键这回事;要让它回到默认值,去上面那个文件里把这一行删掉。
|
|
933
|
+
blocked_pick: 上面那排里挑一个。
|
|
934
|
+
blocked_number: 这一格要一个数,「{text}」读不出数来。别带单位、别带千分位的逗号。
|
|
935
|
+
blocked_boolean: 这一格只认 true 和 false 两个词 —— 它们是要写进 yaml 的那两个字面量。
|
|
873
936
|
sec:
|
|
874
937
|
lede: 这个 agent 现在能碰什么、谁在管着它。
|
|
875
938
|
no_session: 还没有会话。安全状态里有三样东西按会话绑:工作区、它的信任判定、以及跟着信任走的项目级策略目录 —— 没有会话就没有「哪一个」可说。
|
|
@@ -993,7 +1056,7 @@ web:
|
|
|
993
1056
|
audit_code_headless_unauthorized: 非交互,未预授权
|
|
994
1057
|
audit_code_user_approved: 你批准了
|
|
995
1058
|
audit_code_user_denied: 你拒绝了
|
|
996
|
-
perm_where:
|
|
1059
|
+
perm_where: 两档都在输入框那一行改:换一次立刻生效,同时记成下面这个起点(写进 ~/.epoch/config.yaml),新会话和下次启动都从它开始。
|
|
997
1060
|
perm_now: 此刻
|
|
998
1061
|
perm_default: 默认
|
|
999
1062
|
perm_now_changed: (本会话改过)
|
|
@@ -1065,7 +1128,7 @@ web:
|
|
|
1065
1128
|
skill_unindexed: 未进索引
|
|
1066
1129
|
skills_capped_note: 有 {count} 条被 `skills.maxIndexed` 截在索引外:它们不占每一轮的上下文,模型也列不出它们。那一格调大或者去掉就能恢复。
|
|
1067
1130
|
skills_role_note: 有 {count} 条不在这段会话身份的技能白名单里,所以没进索引。⚠️ 那不是一把锁:正文照旧读得到 —— 收窄的是上下文预算,不是可达性。
|
|
1068
|
-
no_toggle:
|
|
1131
|
+
no_toggle: 没有「关掉一个技能」这个开关:只要文件在目录里,它就会被扫到。不想要它,用行尾那个「删除」把它连目录一起删掉(拿不回来);只是想省上下文的话,`skills.maxIndexed` 能给索引封顶。
|
|
1069
1132
|
import_entry: 导入技能
|
|
1070
1133
|
import_title: 导入技能
|
|
1071
1134
|
import_lede: 从这台跑着服务的机器上导入。接受一个含 SKILL.md 的文件夹、一棵「分类/名字」两层的技能树、一个打包好的 .zip,或者单独一份带 frontmatter 的 .md。
|
|
@@ -1096,6 +1159,11 @@ web:
|
|
|
1096
1159
|
skill_view_no_count: 看一眼不会影响它的评分 —— 那本账只记模型真的用过它的次数。
|
|
1097
1160
|
skill_truncated: 这份 SKILL.md 太大(一共 {bytes} 字节),下面只是开头那一截。要读全的话直接打开那个文件。
|
|
1098
1161
|
skill_bytes: 一共 {bytes} 字节
|
|
1162
|
+
skill_remove: 删除
|
|
1163
|
+
skill_remove_ask: 删掉 {name}?连它整个目录一起,删了拿不回来。
|
|
1164
|
+
skill_remove_yes: 删除
|
|
1165
|
+
skill_cancel: 取消
|
|
1166
|
+
skill_removed: 已经删掉 {name}。刚刚被删掉的是这个目录:
|
|
1099
1167
|
plugins: 插件
|
|
1100
1168
|
plug_lede: 一个插件是一包扩展物:斜杠命令、身份、技能、hook、deny 规则、MCP server。从这台机器上已加的市场里挑一个装下来 —— 这一页只能从那张单子里挑,指不了路径也传不了文件。
|
|
1101
1169
|
plug_installed_head: 装着的({count})
|
|
@@ -1297,6 +1365,9 @@ web:
|
|
|
1297
1365
|
how_to_block: 要挡住一个工具,就在权限规则表里加一条 deny。规则写进配置文件才算数,这个界面从头到尾不改配置 —— 安全中心那一屏能告诉你现在有哪些规则、各是哪一层加的。
|
|
1298
1366
|
goto_rules: 去看规则表
|
|
1299
1367
|
mcp_note: MCP 服务器带来的工具也在这张表里,名字长这样:mcp__<服务器名>__<工具名>。「来源」那一列写着它是从哪台服务器来的。
|
|
1368
|
+
tip:
|
|
1369
|
+
what: 说明
|
|
1370
|
+
about: '{name} 的说明'
|
|
1300
1371
|
about:
|
|
1301
1372
|
loading: 正在读…
|
|
1302
1373
|
lede: 出问题时把这一屏截下来贴进 issue,比描述现象快。
|
|
@@ -1419,15 +1490,26 @@ web:
|
|
|
1419
1490
|
remove_confirm: 删掉「{name}」?系统调度器里那条注册会一起撤掉。运行录像留着。
|
|
1420
1491
|
form_new: 新建定时任务
|
|
1421
1492
|
form_edit: 编辑定时任务
|
|
1493
|
+
g_what: 做什么
|
|
1494
|
+
g_what_note: 到点了让它干的那件事
|
|
1495
|
+
g_where: 在哪儿跑
|
|
1496
|
+
g_where_note: 不填也能跑,各有一个确定的缺省
|
|
1497
|
+
g_when: 什么时候跑
|
|
1498
|
+
g_may: 能做什么
|
|
1499
|
+
g_may_note: 这一组决定它半夜替你按下哪些「确认」
|
|
1500
|
+
g_cost: 花多少
|
|
1501
|
+
g_cost_note: 三把尺子,任何一把到顶都停
|
|
1502
|
+
required: 必填
|
|
1422
1503
|
f_name: 名称
|
|
1423
1504
|
f_prompt: 提示词
|
|
1424
1505
|
f_prompt_hint: 到点了让 agent 做什么。写清楚做完要留下什么 —— 没人在旁边追问。
|
|
1425
1506
|
f_workdir: 工作空间(可选)
|
|
1426
|
-
|
|
1427
|
-
f_workdir_note: 不填就跑在 ~/.epoch/automation/<任务 id>/ 里。它**不会**继承任何一个终端的当前目录。
|
|
1507
|
+
f_workdir_note: 不填就跑在 ~/.epoch/automation/<任务 id>/ 里。任何一个终端的当前目录它都不会继承。
|
|
1428
1508
|
f_workdir_default: ~/.epoch/automation/<任务 id>/
|
|
1509
|
+
f_workdir_none: 不指定工作空间
|
|
1429
1510
|
f_model: 模型(可选)
|
|
1430
1511
|
f_model_hint: 不填就用配置里那个
|
|
1512
|
+
f_model_provider_note: 挑了哪一家就记进这条任务,到点按它跑。⚠️ 到点时这台机器上这一家要是没配 key,它会退回默认模型接着跑,并在运行记录里记一条。
|
|
1431
1513
|
f_kind: 执行频率
|
|
1432
1514
|
k_daily: 每天
|
|
1433
1515
|
k_weekly: 每周
|
|
@@ -1443,11 +1525,14 @@ web:
|
|
|
1443
1525
|
f_days_note: 31 号在小月不触发 —— 两个平台的原生行为都是这样。
|
|
1444
1526
|
f_start: 生效开始(可选)
|
|
1445
1527
|
f_end: 生效结束(可选)
|
|
1528
|
+
f_window_note: 两头都算在内。哪一头不填就是那一头不限。到点了但不在区间里的那几次会记成「跳过(不在生效区间)」,不会补跑。
|
|
1529
|
+
f_window_once: 只跑一次的任务不能带生效区间 —— 它自己就是一个日期,所以这两格在这一档下填不了。
|
|
1446
1530
|
f_permission: 权限档
|
|
1447
1531
|
f_bypass_ack: 我明白:这个任务将在 {workDir} 里不经确认地做任何事,包括删文件和跑任意命令。
|
|
1448
1532
|
f_turns: 最多轮次
|
|
1533
|
+
f_turns_hint: 一轮里模型最多调用几次工具,1 到 1000。到顶就停下来把话说完。
|
|
1449
1534
|
f_timeout: 超时(分钟)
|
|
1450
|
-
f_timeout_note:
|
|
1535
|
+
f_timeout_note: 唯一能拦住「一条命令挂住了」的那把尺子。最多 24 小时。
|
|
1451
1536
|
f_budget: 这一次最多花多少(美元)
|
|
1452
1537
|
f_budget_why: 必填,而且我们不给默认值:这个任务没人看着,一个假默认会让「一觉醒来 40 美元」变成我们的错。
|
|
1453
1538
|
save_and_run: 保存并先跑一次
|
|
@@ -1797,6 +1882,8 @@ skill:
|
|
|
1797
1882
|
import_bad_name_dots: 技能名不能是 . 或 ..
|
|
1798
1883
|
import_bad_name_char: '技能名「{name}」里有不能当目录名的字符(< > : " / \ | ? * 和控制字符)。其中冒号是插件 / 宿主技能的前缀分隔符,用户级技能占用它会冒充成插件技能'
|
|
1799
1884
|
import_bad_name_trailing: 技能名「{name}」以点或空格结尾 —— Windows 上这样的目录建得出来却打不开
|
|
1885
|
+
remove_no_system: 技能系统这次没起来 —— 没有一份技能在这个进程里,也就没有能删的。看一眼启动诊断里 Skill 那几条
|
|
1886
|
+
remove_unknown: 没有叫「{name}」的技能 —— 手上这份清单可能已经旧了,刷新一下
|
|
1800
1887
|
host_capabilities:
|
|
1801
1888
|
loaded: '{namespace}:身份 {roles} 个、技能目录 {skillDirs} 个、MCP server {mcpServers} 台、工具 {tools} 个(前两样的名字加 {namespace}: 前缀,后两样加 {namespace}__ —— 它们要进工具名,而工具名里不能有冒号)'
|
|
1802
1889
|
bad_role_name: 身份 "{name}" 的名字不合法(只允许小写字母、数字、连字符,且不能以连字符开头),这一条已跳过;其余照常注入
|
|
@@ -1931,6 +2018,7 @@ mcp_write:
|
|
|
1931
2018
|
invalid: 配置无效
|
|
1932
2019
|
mcp_config:
|
|
1933
2020
|
invalid_json: 一个字节都没写 —— 这份内容不是合法的 JSON:{why}
|
|
2021
|
+
stale_disk: 一个字节都没写 —— 算这次改动的时候 ~/.epoch/mcp.json 被别人动过了;重新读一遍再改
|
|
1934
2022
|
role_write:
|
|
1935
2023
|
bad_name: 身份名「{name}」不能用 —— 只允许小写字母、数字和连字符,而且不能以连字符开头。这个名字同时是文件名和派活时用的那个词(delegate_task 的 role、--agent 的取值),所以收得严
|
|
1936
2024
|
taken: 已经有一个叫「{name}」的身份了 —— 换个名字。这里不覆盖也不自动改名:覆盖要删掉那份文件里你自己写的正文,改名会让派活时用的那个词和你敲进去的对不上
|
|
@@ -2069,6 +2157,7 @@ provider:
|
|
|
2069
2157
|
label_openai_compatible: OpenAI Compatible(通用适配)
|
|
2070
2158
|
response_format_with_tools: 同一次请求不能既要 tools 又要 responseFormat:模型要么调工具、要么出一段 JSON,只能挑一样
|
|
2071
2159
|
response_format_dropped: '{model} 没有接住这一轮的强制 JSON 约束(请求照常发出了),这一轮的输出可能不是 JSON'
|
|
2160
|
+
key_not_applicable: '{provider} 不用 API key,配了也不会被读到'
|
|
2072
2161
|
utility:
|
|
2073
2162
|
aborted: 这一次一次性补全在发出之前被中止了(未发送,未计费)
|
|
2074
2163
|
terminal_setup:
|
|
@@ -3121,6 +3210,7 @@ untrusted:
|
|
|
3121
3210
|
skipped: 工作区不受信任,项目{what}未加载(epoch trust 可信任当前目录)
|
|
3122
3211
|
what_commands: 命令
|
|
3123
3212
|
what_policy: 策略规则
|
|
3213
|
+
what_compliance: 合规词库
|
|
3124
3214
|
what_skills: 技能
|
|
3125
3215
|
what_roles: 角色
|
|
3126
3216
|
hooks_tail: 工作区不受信任,项目 hook 未加载(epoch trust 可信任当前目录)—— hook 会执行命令,这里没有「只收紧的那部分照样生效」的例外
|
|
@@ -3177,6 +3267,40 @@ policy_load:
|
|
|
3177
3267
|
not_kv: 既不是 [[rule]] 也不是 key = "value",已忽略:{preview}
|
|
3178
3268
|
before_first_rule: '{key} 出现在第一个 [[rule]] 之前,已忽略'
|
|
3179
3269
|
rule_skipped: '{message};该规则已跳过'
|
|
3270
|
+
compliance_cmd:
|
|
3271
|
+
cmd_root: 内容合规闸门的自检
|
|
3272
|
+
cmd_check: 判一段文本会不会被拦,命中的是哪几个字
|
|
3273
|
+
cmd_status: 这台机器上这层现在什么状态(开关 / 条数 / 各类别档位)
|
|
3274
|
+
arg_text: 要判的文本
|
|
3275
|
+
opt_stdin: 从标准输入读(判一整个文件时用)
|
|
3276
|
+
need_text: 要判什么?给一段文本,或者加 --stdin 从标准输入读
|
|
3277
|
+
disabled: '内容合规没启用(compliance.enabled: false),这一段不会被判'
|
|
3278
|
+
clean: 干净:一条都没命中
|
|
3279
|
+
verdict: 判定:{action},命中 {count} 条
|
|
3280
|
+
hit: ' [{category}] {action} ← {excerpt}(规则 {rule})'
|
|
3281
|
+
blocked: 这一档是 block:输入侧这次请求根本不发出去(也不计费);开了输出侧的话,命中那一句一个字都不会出现在屏幕上
|
|
3282
|
+
released: 过滤后:{text}
|
|
3283
|
+
status_enabled: 启用:{enabled}
|
|
3284
|
+
status_rules: 规则:生效 {active} 条(内置 {builtin} + 用户词库 {user})
|
|
3285
|
+
status_dir: 用户词库目录:{dir}
|
|
3286
|
+
status_scope: 通道:输出 {output} / 输入 {input} / 跳过代码 {code}
|
|
3287
|
+
status_action: ' {category} → {action}'
|
|
3288
|
+
status_project_note: 注意:项目级词库(<项目根>/.epoch/compliance/)要过工作区信任闸门,本命令不读它 —— 真会话里会读
|
|
3289
|
+
compliance:
|
|
3290
|
+
category_sep: 、
|
|
3291
|
+
category:
|
|
3292
|
+
sexual: 色情低俗
|
|
3293
|
+
political: 涉政 / 国家安全
|
|
3294
|
+
hate: 民族种族歧视
|
|
3295
|
+
violence: 暴力恐怖
|
|
3296
|
+
illegal: 违法犯罪
|
|
3297
|
+
self_harm: 自残自杀
|
|
3298
|
+
privacy: 个人敏感信息
|
|
3299
|
+
compliance_load:
|
|
3300
|
+
dir_read_failed: 合规词库目录读取失败:{reason}
|
|
3301
|
+
file_read_failed: 读取失败,已跳过整个文件:{reason}
|
|
3302
|
+
unknown_file: 文件名不是类别名,已跳过整个文件。认得的类别:{categories}(正则写成 <类别>.regex.txt,豁免词写成 exempt.txt)
|
|
3303
|
+
bad_regex: 正则编译失败,该条已跳过:{reason}
|
|
3180
3304
|
skill_load:
|
|
3181
3305
|
degraded: '{message};已按无 frontmatter 加载'
|
|
3182
3306
|
not_a_map: frontmatter 不是键值对(顶层要是一个 YAML 对象);已按无 frontmatter 加载
|
|
@@ -3279,7 +3403,12 @@ context_breakdown:
|
|
|
3279
3403
|
agent_run:
|
|
3280
3404
|
error: '错误: {message}'
|
|
3281
3405
|
images_unsupported: 当前模型不支持图片输入,已取消本次请求(未发送,未计费)。请换用支持视觉的模型(如 gpt-4o / claude-sonnet-4-6 / gemini-2.5-flash),或去掉 {count} 张图片后重试。
|
|
3406
|
+
images_dropped: '{provider} 把这一轮的 {count} 张图片丢掉了(它自己报的:{feature}),模型实际上没看见图 —— 这一轮的回答别当真。请求已发出并计费。多半是这个 provider 的 SDK 版本还不支持图片,或这个模型其实不认图。'
|
|
3407
|
+
images_dropped_provider_unknown: 当前 provider
|
|
3282
3408
|
content_filter: 模型因安全策略拒绝响应,请换一种方式提问。
|
|
3409
|
+
compliance_output: 这段回复触及内容合规限制({categories}),已停止输出。
|
|
3410
|
+
compliance_input: 你的消息触及内容合规限制({categories}),本次请求未发送,未计费。
|
|
3411
|
+
compliance_input_masked: 你的消息里有触及内容合规限制({categories})的词,已打码后再发给模型 —— 模型看到的不是你屏幕上这句的原文。
|
|
3283
3412
|
stalled: 检测到死循环:{info}。任务已终止。
|
|
3284
3413
|
stall_info: 连续 {count} 轮调用 {tool}({args}),检测到死循环
|
|
3285
3414
|
max_turns: 已达到最大轮次 {max},任务未完成即终止。
|
|
@@ -3468,6 +3597,7 @@ secret:
|
|
|
3468
3597
|
infra_misc:
|
|
3469
3598
|
shell_not_on_path: 'shell: 配置的 {kind}({exe})不在 PATH 上,已回退到 cmd.exe'
|
|
3470
3599
|
ripgrep_install_windows: winget install BurntSushi.ripgrep.MSVC(或 scoop install ripgrep)
|
|
3600
|
+
ripgrep_chmod_hint: chmod +x "{path}";这个目录归 root 时前面加 sudo
|
|
3471
3601
|
schema_failed: '{path} 校验失败({count} 处):\n{detail}'
|
|
3472
3602
|
schema_more: 还有 {count} 处问题未列出
|
|
3473
3603
|
schema_unknown_key: 未知配置项,已忽略(不影响其他配置生效)
|
|
@@ -3513,6 +3643,9 @@ boot:
|
|
|
3513
3643
|
managed_hooks_only: 企业托管设置开启了 allowManagedHooksOnly,用户级与项目级 hook 都不加载({path})
|
|
3514
3644
|
policy_load_failed: 加载失败(跳过)
|
|
3515
3645
|
perm_rules: 权限规则 {total} 条(allow {allow} / ask {ask} / deny {deny})
|
|
3646
|
+
compliance_ready: 生效 {active} 条(内置 {builtin} + 外部词库 {external})
|
|
3647
|
+
compliance_off: '未启用(compliance.enabled: false)'
|
|
3648
|
+
compliance_load_failed: 外部词库加载失败,只用内置种子表
|
|
3516
3649
|
commands_all_failed: '{count} 个文件都没能加载,当前没有可用的自定义命令'
|
|
3517
3650
|
command_allowed_tools: '{name} 的 allowed-tools 里 {tools} 不存在,已忽略'
|
|
3518
3651
|
tools_cost: '{count} 个({split})≈ {tokens}k tokens/轮'
|
|
@@ -3522,6 +3655,7 @@ boot:
|
|
|
3522
3655
|
shell_kind: '{kind}(terminal 工具的命令交给它执行)'
|
|
3523
3656
|
plugin_register_failed: 注册失败 ({reason})
|
|
3524
3657
|
ripgrep_missing: 未安装,file_search 不可用({hint})
|
|
3658
|
+
ripgrep_not_executable: 装下来了但没有执行位,file_search 暂时不可用({hint})
|
|
3525
3659
|
ripgrep_system: 用系统安装的 rg
|
|
3526
3660
|
ripgrep_builtin: 用内置的 rg{version}
|
|
3527
3661
|
mcp_none: 未配置(~/.epoch/mcp.json 不存在或为空)
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@epoch-agent/infra",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.3.1",
|
|
4
4
|
"private": false,
|
|
5
5
|
"description": "epoch-agent 基础设施:路径真源、SQLite 连接与迁移、日志、平台兼容、命令安全表",
|
|
6
6
|
"repository": {
|
|
@@ -35,9 +35,9 @@
|
|
|
35
35
|
"vitest": "^3.0.0"
|
|
36
36
|
},
|
|
37
37
|
"optionalDependencies": {
|
|
38
|
-
"@epoch-agent/vendor-ripgrep-darwin-
|
|
39
|
-
"@epoch-agent/vendor-ripgrep-win32-x64": "14.2.
|
|
40
|
-
"@epoch-agent/vendor-ripgrep-darwin-
|
|
38
|
+
"@epoch-agent/vendor-ripgrep-darwin-x64": "14.2.1",
|
|
39
|
+
"@epoch-agent/vendor-ripgrep-win32-x64": "14.2.1",
|
|
40
|
+
"@epoch-agent/vendor-ripgrep-darwin-arm64": "14.2.1"
|
|
41
41
|
},
|
|
42
42
|
"engines": {
|
|
43
43
|
"node": ">=22.0.0"
|