Ma
|
b673c50005
|
chore(release): prepare v1.8.0 documentation
|
2026-08-17 11:03:08 +08:00 |
|
Ma
|
e7c0446557
|
refactor(core): unify production harness and context flow
|
2026-08-16 17:49:43 +08:00 |
|
Ma
|
d1d6d8ec13
|
refactor: center creation workflows on pi harness
|
2026-08-16 11:35:00 +08:00 |
|
Ma
|
35bb2efdb6
|
refactor(core): run production workers through pi harness
|
2026-08-14 22:36:34 +08:00 |
|
Ma
|
6651fa7e5f
|
feat(skills): bind production modes to dedicated expertise
|
2026-08-14 15:33:26 +08:00 |
|
Ma
|
7f3bdd59c4
|
refactor(studio): enforce structured actions and expose context
|
2026-08-14 13:42:50 +08:00 |
|
Ma
|
8dee4cb236
|
feat(skills): ship professional story skill pack
|
2026-08-14 01:08:03 +08:00 |
|
Ma
|
bac7abcc2d
|
fix(studio): isolate import navigation from click events
|
2026-08-14 00:38:24 +08:00 |
|
Ma
|
6f1819bcf3
|
feat(studio): persist model catalogs and import external canon
|
2026-08-14 00:37:54 +08:00 |
|
Ma
|
1941101d82
|
fix(packages): link internal workspace dependencies
|
2026-08-14 00:36:09 +08:00 |
|
Ma
|
0da8637099
|
fix(studio): stop replayed production tasks
|
2026-08-02 01:09:55 +08:00 |
|
Ma
|
fc294385f1
|
fix(studio): close setup and chapter workspace gaps
|
2026-07-30 00:39:31 +08:00 |
|
Ma
|
d08bbed005
|
test(studio): account for LM Studio provider
|
2026-07-29 22:11:06 +08:00 |
|
Ma
|
66fad52bc4
|
fix(studio): widen chapter preview on large screens
|
2026-07-29 21:51:27 +08:00 |
|
Ma
|
cf40d4f923
|
feat(studio): allow custom cover base URLs
|
2026-07-29 21:50:58 +08:00 |
|
Ma
|
863d916272
|
feat(llm): add LM Studio local provider
|
2026-07-29 21:30:59 +08:00 |
|
Ma
|
7a0b1a7054
|
feat(studio): add safe chapter rewrite workspace
|
2026-07-29 21:15:32 +08:00 |
|
Ma
|
66449f05c4
|
fix(agent): run multi-chapter writes as one sequential task
|
2026-07-29 19:59:18 +08:00 |
|
Ma
|
c7851b94ad
|
chore(release): prepare v1.7.2
|
2026-07-28 17:18:39 +08:00 |
|
Ma
|
6e4ce0050e
|
refactor(skills): replace legacy capability system
|
2026-07-27 12:01:14 +08:00 |
|
Ma
|
41a1138fbd
|
feat(studio): import external skill folders
|
2026-07-27 00:56:00 +08:00 |
|
Ma
|
6a16a61977
|
chore(release): prepare v1.7.1
|
2026-07-16 14:08:53 +08:00 |
|
Ma
|
b98252bb49
|
feat(studio): compare narrative forecasts in book chat
|
2026-07-16 00:26:04 +08:00 |
|
Ma
|
e1eb12f636
|
feat(studio): retry the last failed chat message
GitHub issue #335 的"重试按钮"部分(推理强度参数 UI 不在本次范围)。
聊天轮请求失败后(/agent fetch 拒绝、/agent 返回 error 字段、模型返回空
内容、模型未选择、草稿会话落库失败),把这次 sendMessage 的原样参数
(text + options)记录到 SessionRuntime.lastFailedSend;ChatPage 在存在
记录且非聊天流式中时,在输入区上方显示"重试"按钮,点击调用新增的
retryLastSend action 用原参数重发,并在重发前清除记录避免重复点击双发。
不记录的情况:用户主动停止(abortSession 已先把 isChatStreaming 置回
false,各失败出口据此跳过)、确认式生产任务轮(任务失败由任务卡自己
展示)。新一轮发送开始时清除旧记录。
测试:store 层覆盖 fetch 拒绝记录、error 字段记录、重试请求体与首发
一致且记录清除、成功轮无记录、用户停止不记录、无记录时重试为空操作。
|
2026-07-15 15:48:13 +08:00 |
|
Ma
|
a975fb5423
|
feat(core): gate book-mutating tools while a production task runs
根因:后台生产任务运行期间,同会话并行聊天的 agent 仍持有全部生产工具
(agent-session.ts 的书籍会话工具表),只靠注入 backgroundTaskContext
提示词软约束,没有 host 层的硬门控——模型仍可能在任务运行中并发修改
同一本书。
修法(窄门控):
- core:AgentSessionConfig 加可选布尔 suppressProductionTools。为 true 时
工具表剔除会创建/修改书籍与产物的生产工具(sub_agent、generate_cover、
write_truth_file、rename_entity、patch_chapter_text、replace_chapter_text、
import_chapters);read/grep/ls、research/material 与 propose_action
保留——propose_action 引发的确认任务在 host 侧已有单任务 409 闸门。
该布尔纳入 Agent 缓存失效判断(与 backgroundTaskContext 同样处理),
任务开始/结束时缓存的 Agent 重建、工具表恢复。
- studio server:已判定"本会话任务运行中"并注入 backgroundTaskContext 的
同一处传 suppressProductionTools: true;任务状态提示词补一句
"生产类工具已临时不可用,任务结束后恢复"(zh/en 双语)。
|
2026-07-15 15:36:09 +08:00 |
|
Ma
|
bfae2d35cf
|
fix(studio): route id-less and compression events away from background task cards
三个事件路由缺陷(并行聊天与后台任务时互相串排):
- context:compression 处理器忽略服务端已带的 executionId,一律写进当前
聊天流消息:并行时任务 pipeline 的压缩事件会在聊天消息里长出
context-* 伪工具卡。
- 无 id 的 log / llm:progress 回退到"最近一张运行中工具卡":聊天轮还没有
自己的工具卡时会落到后台任务卡上(聊天日志串排进任务)。
- 服务端 broadcast("tool:update") 全仓无前端消费者,是死事件。
修法:
- context:compression 带 executionId 时按 id 定位任务卡,把压缩事件作为
阶段挂上去(不可变更新);卡不存在时丢弃,绝不写进聊天流消息;无 id
维持现状(聊天轮自己的压缩展示)。
- 无 id 回退改为"最近一张运行中的聊天轮工具卡":跳过带 background 标记的
任务卡;跳过后没有可挂的卡时丢弃(任务快照重放会带回任务自己的累积
日志,不丢信息)。
- 删除两处 tool:update 死广播(确认任务 onUpdate 内与聊天轮
tool_execution_update 转发),已 grep 确认零消费者、无测试引用。
|
2026-07-15 15:26:39 +08:00 |
|
Ma
|
29b6af4349
|
fix(studio): stop appending transcript messages to deleted sessions
根因:deletedSessionIds 只拦了任务快照持久化。任务成功/失败路径的
appendManualSessionMessages 仍会给已删除会话追加助手消息,底层
appendTranscriptEvents 是 mkdir + appendFile,会把已删除会话的 sessions
目录条目和 transcript 文件重新建出来(任务收尾追加正好落在删除之后)。
修法:server.ts 增加 appendSessionMessagesUnlessDeleted 守卫(检查
deletedSessionIds 后再调 appendManualSessionMessages),server 内全部
四处手动追加(外部编辑回复、确认分支的指令预写、成功收尾、失败收尾)
统一走守卫;refreshBookSessionFromTranscript 同样在会话已删除时直接
返回,不再刷新和广播标题。不改 core。
测试:把"删除运行中任务的会话"用例接回真实 transcript 实现与真实
deleteBookSession,任务错误路径走完后断言 transcript 文件不存在、
loadBookSession 返回 null(原用例只查了任务快照文件)。
|
2026-07-15 15:22:37 +08:00 |
|
Ma
|
0091c3c665
|
fix(studio): find running tasks in memory before the disk snapshot when deleting or aborting
根因:DELETE /sessions/:id 和 POST /sessions/:id/abort 都靠
loadReconciledTaskSnapshot 从磁盘快照拿 execution.id 再查 controller Map。
但任务的 AbortController 注册(同步)与首次快照持久化(在
executeConfirmedProductionAction 内部)之间有多个 await 间隙,窗口内的
删除/中止从磁盘读不到快照,刚启动的任务被漏掉、停不下来。
修法:reservedProductionSessions 从 Set<string> 升级为 Map<string, string>
(sessionId → taskId;预留时 confirmedTaskId 已生成,两处都在手)。新增
findRunningTaskController:优先查内存预留表拿 taskId → controller,磁盘
快照只作回退(覆盖进程重启后的对账场景)。DELETE 与 /abort scope=all
统一改走该入口;finally 的释放逻辑不变(Map.delete 同 key)。
测试:让任务开始时预写指令的首次 appendManualSessionMessages 挂起,制造
"controller 已注册、磁盘无快照"的窗口,断言窗口内 /abort 返回
aborted: true、DELETE 能让任务的中止信号生效且请求以错误结束。
|
2026-07-15 15:20:15 +08:00 |
|
Ma
|
28f2923fc0
|
fix(studio): reclassify a chat turn as a production task when the server starts one
根因:free-text"写下一章"(无 requestedIntent)在服务端经
isWriteNextProductionRequest 命中写章启发式后按后台生产任务执行,但前端
isConfirmedProductionSend 对 requestedIntent === undefined 直接返回 false,
该轮被当成聊天轮(isChatStreaming=true)。用户点"停止"时 ChatPage 按
聊天轮走 scope=chat,abortAgentSession 在 agent 会话注册表里找不到会话
(任务不在其中),第一次点停止什么都停不掉。
修法(前端无法预知服务端启发式,用事件驱动重分类):
- 服务端:确认式生产任务分支的 tool:start 广播加 background: true 标记,
聊天轮工具的 tool:start 不带。
- 前端 stream-events:收到带标记的 tool:start 且当前 isChatStreaming=true
时,把本轮重分类为任务轮——isChatStreaming 归 false(停止按钮据此走
scope=all 拿到任务控制器,用户可继续聊天),isStreaming 维持 true;
挂起的 fetch 返回后仍由 sendMessage 的 finally 按"是否还有任务在跑"收尾,
不会重复收尾或把任务流关掉。
- ToolExecution 加可选 background 字段并记到工具卡上;mergeTaskExecution
从任务快照恢复的卡同样补该标记(快照来源必然是后台任务,终态快照替换
整个 execution 时标记不能丢)。该标记供后续无 id 事件的回退路由使用。
|
2026-07-15 15:15:12 +08:00 |
|
Ma
|
8073aaa9f8
|
feat(studio): tag pipeline progress events with the task execution id
后台生产任务与聊天并行时,SSE 的 log / llm:progress / context:compression
事件只带 sessionId,前端只能把它们附加到"最近一张运行中的工具卡",导致
任务日志和进度串排进聊天轮的工具卡(反之亦然)。
服务端:/api/v1/agent 在构建 pipeline 之前生成确认式任务的 execution id,
经 buildPipelineConfig 新增的 executionIdForSSE 传给任务的 pipeline,该
pipeline 广播的三类进度事件都带上 executionId。按构建时打标而不是按
sessionId 查表打标:同会话并行聊天轮的 pipeline 是另一次请求单独构建的、
不带任务 id,聊天轮工具经 pipeline 广播的日志不会被误标成任务日志。
前端:log 与 llm:progress 处理器改为——事件带 executionId 时用
updateToolPartById 按 id 跨消息精确定位工具卡;不带时维持"最近一张运行中
的卡"回退(兼容聊天轮工具与旧版事件)。llm:progress 改为每个 executionId
一个节流器,任务与聊天并行时双方进度不会在"只保留最新事件"的节流器里
互相覆盖;带 id 但找不到卡的日志直接丢弃(任务快照重放会带回累积 logs),
不回退到最新卡。
测试:server 端验证任务运行期间广播的 log/llm:progress 带任务 execution
id、并行聊天轮与任务结束后的日志不带;store 端验证带 executionId 的
log/llm:progress 附加到更早的任务卡、不带的维持附加到最新运行中卡。
|
2026-07-15 12:23:20 +08:00 |
|
Ma
|
fc6babc335
|
fix(studio): persist the production instruction to the transcript at task start
根因:确认式生产任务(create_book/short_run/write_next 等)的用户指令,
要等任务完成/失败后才随助手工具消息一起传给 appendManualSessionMessages,
且只作为 request_started.input 落在 transcript 里——transcript 恢复逻辑
(deriveBookSessionFromTranscript)只把 role=user 的 message 事件还原成
用户气泡,从不读取 request_started.input。后果:
1. 任务运行期间刷新页面,GET session 的消息里没有这轮用户指令,用户气泡消失;
2. 任务完成后指令依然不会作为用户气泡恢复;
3. 并行聊天的消息先写入 transcript,重新加载后聊天排在生产指令前,顺序倒置。
修法:任务开始执行前(预留名额与快照检查之后、executeConfirmedProductionAction
之前)就把用户指令作为 role=user 的消息事件写进 transcript(时间戳为开始时刻);
成功与失败(ConfirmedActionExecutionError)两条完成路径改为只追加助手工具消息,
instruction 参数传空字符串,指令不会写第二遍。刷新场景下用户气泡来自 transcript、
运行中任务卡来自快照 mergeTaskExecution 按 execution id 合并,两者共存且不重复。
测试:server.test.ts 新增三条真实 transcript 往返用例(运行中刷新含指令气泡、
并行聊天轮后顺序按真实时间、失败路径指令只写一次),并把三条既有断言更新为
"开始预写指令 + 完成只补助手消息"的新契约;action.test.ts 新增前端恢复用例
(transcript 用户气泡 + 运行中任务卡合并不重复)。
|
2026-07-15 11:46:31 +08:00 |
|
Ma
|
790aace6b9
|
fix(studio): reserve the single-task slot atomically
根因:确认式生产任务的单任务检查是"await findActiveRunningTask 读快照 →
之后才 set AbortController"的 check-then-act 结构:两个并发确认请求都能在
对方注册 controller 之前通过检查,双任务同时启动、每会话唯一的任务快照
互相覆盖,前端丢失其中一个任务卡。
修法:
- server 闭包新增 reservedProductionSessions(sessionId 集合)。进入确认
分支后、任何 await 之前同步预留名额:占位失败的请求直接按
PRODUCTION_TASK_ALREADY_RUNNING 返回 409。
- 预留成功后再走既有的快照检查(防旧进程遗留的运行中快照等边界情况),
检查移入 try 块,finally 里与 activeConfirmedTasks 一起释放,任何出错
路径都不会遗留占位。
- 预留键固定为进入分支时的 sessionId:bookSession 之后可能因建书迁移被
重新赋值,finally 释放的必须是当初预留的那个键。
测试:用 loadBookSession 做屏障让两个并发确认请求同时到达检查窗口——
恰好一个 409、一个正常执行,败者的任务没有启动,胜者的快照收敛为
completed。修复前该场景两个请求都返回 200、任务双启动。
|
2026-07-15 11:21:08 +08:00 |
|
Ma
|
ea9bce50dd
|
fix(studio): don't close a streaming chat when a terminal task snapshot lands
根因:stream-events.ts 的 task:snapshot 处理里,终态快照只要通过了
hasInFlightExecution 门槛就无条件置 stream:null、isStreaming:false 并关闭
连接。竞态场景:任务刚结束、消息里还留着 in-flight 任务卡,此刻用户发消息
建立了新连接且聊天轮正在流式——服务端在连接建立时重放终态快照,门槛通过,
正在跑的聊天流被关掉,本轮所有增量事件全部丢失。
修法:接受终态快照时照常 merge 收尾任务卡,但只有聊天轮不在流式
(!isChatStreaming,从会话 runtime 读取)时才关闭连接、置 stream:null 和
isStreaming:false;聊天轮流式中则保持连接和流式状态,等聊天轮请求结束时
由 sendMessage 的收尾逻辑处理。
测试:聊天轮流式中 + 消息有 in-flight 任务卡 + 收到该任务的终态快照 →
任务卡转 completed、连接未关、isStreaming/isChatStreaming 仍为 true;
聊天轮结束后连接正常关闭。
|
2026-07-15 11:13:44 +08:00 |
|
Ma
|
a995e6a440
|
fix(studio): abort the production task when its session is deleted
根因:DELETE /api/v1/sessions/:sessionId 只删除会话文件和任务快照,不中止
任务的 AbortController。任务在后台继续跑、继续产出内容;而且任务的
onTaskChange 持久化会把快照文件重新写回磁盘,给已删除的会话"还魂"——
前端刷新后又能看到一个属于已删除会话的任务卡。
修法:
- DELETE 时通过 loadReconciledTaskSnapshot 找到该会话运行中的任务,
abort 它的 controller。
- server 闭包里新增 deletedSessionIds 集合:删除会话时先标记,
persistConfirmedTask 写盘前检查标记,已删除会话的任务持久化(包括中止
后的错误持久化)直接跳过,不再重建快照文件。
- POST /sessions 用同一个 sessionId 重新创建会话时移除标记,新会话的
生产任务照常持久化。
测试:删除有运行中任务的会话后,任务控制器的 signal 已中止;等任务的错误
路径走完后,快照文件不存在。
|
2026-07-15 11:11:36 +08:00 |
|
Ma
|
766c28e3e1
|
feat(studio): run write_next through the background task system
根因:Quick Action"写下一章"(actionSource=quick-action、requestedIntent=write_next)
不走确认式生产任务分支——isConfirmedProductionAction 只接受 button/slash 来源、
生产意图列表里也没有 write_next,写章走的是 shouldRunDirectWriteNext 的直跑路径:
没有 taskId、没有 AbortController、不写 task-store 快照。后果是写章期间发消息时
scope=chat 的中止杀不掉它、UI 端丢失后无法取消、刷新后无法恢复进度;前端
CONFIRMED_PRODUCTION_INTENTS 也不含 write_next,这一轮被当成聊天轮,阻塞写章
期间的后续发送。
修法:
- 服务端把 write_next 纳入确认式生产任务体系:shouldRunDirectWriteNext 更名为
isWriteNextProductionRequest,命中的三种写章触发方式(显式 write_next intent、
free-text 明确写章命令、写作指令启发式)统一归一为 confirmedIntent=write_next,
与其它确认式生产 intent 走同一条任务分支,获得 taskId、AbortController、磁盘
快照与单任务 409 闸门;原直跑代码块整体删除,不留第二条不可中止的执行通道。
- executeConfirmedProductionAction 新增 write_next 工具映射:
createWriteNextChapterTool 通过 pipeline.runWithAbortSignal 调用
writeNextChapter,让任务控制器的中止信号传进写作流程;结果文本沿用原直跑
路径的中英双语文案;审稿未通过时结果带 isError=true,任务卡按错误态展示、
请求仍按 200 返回结果文本,保持原直跑路径的对外行为。
- 前端 CONFIRMED_PRODUCTION_INTENTS 增加 write_next,且 quick-action 来源的
write_next 也算生产任务发送:写章轮不置 isChatStreaming,写章期间可以继续聊天。
测试:server.test.ts 新增三条(写章期间快照 running→completed、/abort 默认
scope 能把中止信号传进写作流程并把快照收敛为 error、写章期间第二个生产任务
409);message-policy.test.ts 补 isConfirmedProductionSend 的 write_next 用例。
|
2026-07-15 11:08:27 +08:00 |
|
Ma
|
39d2edfcc9
|
feat(studio): send messages alongside a running production task
此前任务运行期间用户发消息,前端会先中止任务再发送;聊天轮结束时
agent:complete 一到就关掉 SSE 连接,把还在跑的任务流也一起关了。
本次改动(issue #341 前端部分):
1. SessionRuntime 新增 isChatStreaming(聊天轮流式中);isStreaming 保持
"聊天轮或任务运行中"语义,Sidebar/PlayHud 等现有读取方不受影响。
确认式生产任务的发送轮不置 isChatStreaming(该请求挂起到任务结束,
期间用户仍可聊天),判定逻辑与服务端 isConfirmedProductionAction 对齐。
2. sendMessage 只挡 isChatStreaming:任务在跑时允许发送。发送时关掉旧的
任务恢复连接、换成新连接(单连接原则);任务卡不受影响——服务端在新
连接建立时重放 running 快照,任务日志与收尾均按 execution id 匹配。
3. 聊天轮收尾不再一律关连接:agent:complete/agent:error/agent:aborted
到达时,聊天轮还在进行或消息里还有 in-flight 任务卡就保持连接,等任务
自己的终态事件(tool:end → agent:complete)再关闭。sendMessage 的
finally 统一按"是否还有任务在跑"决定连接与 isStreaming 的最终状态。
4. tool:end / log / llm:progress 改为跨消息定位工具卡(按 execution id /
倒序找运行中的卡),并行聊天时任务卡挂在更早的任务轮消息上,原先只在
当前 streamTs 消息里找会漏更新。
5. 停止按钮分对象:聊天轮流式中 abort 用 scope=chat(只停聊天轮,任务
继续跑,也不把任务卡标记为失败);只有任务在跑时才 scope=all 停任务。
聊天轮出错时只把本轮消息里的运行中工具标记为失败,不连带任务卡。
|
2026-07-15 01:52:13 +08:00 |
|
Ma
|
c81272febb
|
feat(studio): keep production tasks running while the user chats
任务运行期间用户发消息,服务端此前无并发防护、agent 也感知不到任务存在。
本次改动(issue #341 服务端部分):
1. 拒绝并发生产任务:确认式生产分支开头用对账后的任务快照 +
activeConfirmedTasks 判断是否已有任务在跑,有则返回 409
(PRODUCTION_TASK_ALREADY_RUNNING,双语文案),不覆盖运行中的任务快照。
2. agent 感知后台任务:聊天路径构建 agent 会话前读取同一判断,任务在跑时
把任务状态块(工具名/label、状态、已运行时长、最近 3 条日志)作为
backgroundTaskContext 注入。core 侧 AgentSessionConfig 新增该可选字段,
附加到系统提示词末尾,并纳入 Agent 缓存失效判断,保证状态块跟着任务
的启停实时更新。
3. 停止接口分作用域:POST /sessions/:id/abort 接受可选 body
{ scope: "chat" | "all" }。scope=chat 只中止聊天轮(agent loop),
不触发任务 AbortController;默认 all 维持旧行为。
|
2026-07-15 01:39:10 +08:00 |
|
Ma
|
26e659d0ab
|
fix(studio): rewrite zombie running task snapshots after server restart
任务状态快照持久化在磁盘(.inkos/tasks/),但任务本体跑在 HTTP handler
里、AbortController 只存在内存 Map 中。server 进程在任务运行期间重启后,
磁盘上会留下永远 running 的快照:前端每次刷新都恢复出一个运行中的任务
卡,停止按钮只中止内存 controller、不更新磁盘,刷新后又变回 running。
现在三处读取快照的地方(SSE 重放、GET session、abort)统一走对账加载:
running/processing 快照若在 activeConfirmedTasks 中没有对应 controller,
只可能是进程重启过(正常流程里 controller 先于首次持久化进入 Map、晚于
终态持久化删除,无竞态窗口),直接把快照改写为 error 终态并保存。
|
2026-07-15 00:43:37 +08:00 |
|
Ma
|
80140e345f
|
fix(studio): ignore stale terminal task snapshots replayed onto new streams
服务端在每次 SSE 连接建立时都会重放该会话磁盘上的任务快照。此前前端
task:snapshot 监听器对终态快照无条件收尾并关闭 EventSource,导致会话
跑完一次确认式任务后,后续每一轮新消息的流都会在连接瞬间被旧的
completed 快照关掉:普通聊天丢失流式渲染,第二次生产任务的实时进度
整轮不可见(2e7985c 引入的回归)。
现在终态快照只在当前消息里确实存在同 id 且仍为 running/processing 的
任务卡时才生效(刷新恢复场景);否则视为上一轮任务的残留快照直接忽略。
|
2026-07-15 00:43:26 +08:00 |
|
Ma
|
fa20ad7cc8
|
fix(short): honor English language in Studio and CLI
|
2026-07-14 23:32:39 +08:00 |
|
Ma
|
d61993459a
|
fix(studio): stop reviving stale Play choices
|
2026-07-14 22:19:48 +08:00 |
|
Ma
|
2e7985c2f3
|
fix(studio): persist long-task progress across refresh
|
2026-07-14 20:14:20 +08:00 |
|
Ma
|
fd87b04c3f
|
chore(release): prepare v1.7.0
|
2026-07-11 18:03:27 +08:00 |
|
Ma
|
c202ce4a2d
|
fix(studio): normalize uploaded project paths
|
2026-07-11 14:15:13 +08:00 |
|
Ma
|
3fcc6ef90b
|
fix(core): recover stale book write locks
|
2026-07-11 01:47:37 +08:00 |
|
Ma
|
d316c8e4fe
|
feat(studio): complete translation review workflow
|
2026-07-10 02:39:16 +08:00 |
|
Ma
|
8ac666fbed
|
feat: add translation workflow
|
2026-07-08 14:03:19 +08:00 |
|
Ma
|
587bcdaaa1
|
feat(studio): server responses follow project language
服务端用户可见错误/提示与管线阶段、agent/工具标签按项目语言返回
(每次请求读取配置,切换语言即时生效);产线端点透传 language
|
2026-07-07 17:23:03 +08:00 |
|
Ma
|
e895739dd3
|
feat(studio): bilingual film wizard and service management pages
影游向导/分析面板/故事树/流程图残留、服务商列表/详情/配置来源卡/
快捷链接/服务分组全部双语
|
2026-07-07 17:23:03 +08:00 |
|
Ma
|
81abb7a39d
|
feat(studio): bilingual book sidebar, frame leftovers, truth-display
App 接线 setAppLanguage;侧栏各分区(角色/进度/摘要/伏笔/设定)、
Sidebar 会话操作与相对时间、导入页下拉项双语;truth-display 标签
按语言输出,去掉英文标签被强转中文的映射
|
2026-07-07 17:23:03 +08:00 |
|