Files
msime-windows/engine/contracts
時崎 ギャラクシーandfanlusky add122fcc6 feat: 候选词翻译新增 AI 辅助提供方,收敛为单一 translation.provider (#876)
* feat(engine): 翻译凭据测试新增 translation.ai 服务类型

* feat(server): 候选词翻译新增 AI 辅助提供方,收敛为单一 translation.provider

* feat(ui-html): 候选词翻译新增 AI 辅助提供方并跟随单一 provider

* fix(server): 将 ai_translation 加入编译目标与测试套件

* fix(server): 在 AiTranslation 命名空间导出 ParseTranslations 供测试调用

* fix(server): 解析模型返回时剥除 Markdown 代码块标记

* fix(server): AI 候选词翻译校验占位 Token、收紧解析,翻译配置改读快照

- AI 翻译的 Token 改用 IsUsableSecret 校验,出厂模板的占位符不再被当成可用凭据
- 解析模型回复时,合法 JSON 但键不对、数组长度不符或残缺 JSON 一律作废,不再把原文当译文显示和写进释义库
- 从旧布尔推导出腾讯云时保留 tencent_tmt.enabled 门禁;在设置页明确选择时才打开,升级不会替用户向腾讯云发送候选词
- 候选词翻译读取的 provider 与各服务配置合成一份加锁快照,配置重载时整份替换,候选线程和翻译 worker 不再直接读会被改写的全局字符串;每个任务只解析当前服务的配置
- provider 与三个旧布尔一次原子写入;旧的 niutrans/custom enabled 开关改为切换 provider
- AI 联想与 AI 翻译共用 ChatCompletions 传输层,翻译超时与 AI 联想一致改为 8 秒
- 设置页凭据测试与运行时共用 AiTranslation::FromConfiguredTranslation,provider 白名单只保留 IsValidTranslationProvider 一处

* fix(ui-html): 候选词翻译的 AI 配置提示随 AI 辅助页实时更新

AI 辅助页改服务商、地址、Token 或模型后,翻译区的提示和摘要立刻刷新,不用重开设置窗口;可用性判断与服务端一致,占位 Token 不算已配置。

---------

Co-authored-by: fanlusky <1730976608@qq.com>
2026-10-12 16:47:04 +08:00
..

Product contracts

These headers are independently consumable C++17 contracts. Including them does not link the input engine, start threads, access dictionaries, or require any third-party code. The TSF text service consumes only these headers; the server consumes the same source by linking the engine. Both live in this repository — windows/ and server/ — and so does the engine, so one commit covers all three and there is no pin to keep in step.

windows_ipc.h owns the wire layouts, pipe names and opcodes. voice_composition_pipe.h owns voice framing. Consumers may wrap these headers but must not duplicate their definitions.

punctuation/policy.json is the source of truth for the ASCII punctuation keys and their Chinese translations. Its generated policy.h is consumed by the engine and included directly by the hosts that route punctuation keys. Stateful quote alternation and nested book-title marks remain part of the same contract, rather than being re-created in each host.

product_lock.py contains the shared product-lock primitives used by the three platform locks. See product_lock.md for the vendoring and byte-equality rule.

Main handshake

Reverse endpoints retain their 16-byte hello and PipeReady acknowledgement. Once both endpoints are registered, the new client sends the existing 304-byte ClientHello with:

Field Meaning
keycode MSIP magic
wch Major wire protocol version
point[0] Minor additive version
modifiers_down Supported capability bits
point[1] Required capability bits
request_id Nonzero registration correlation ID

The Server sends ProtocolReady or ProtocolMismatch on the registered reply endpoint before activating the main route. The reply echoes the correlation ID and contains major/minor, negotiated capabilities and magic in the first six UTF-16 units. These packets are consumed only during registration and are never text commits.

Existing DLLs with unversioned hello remain accepted by the new Server using the established v1 semantics; they receive no new opcode. New DLLs require an acknowledgement from the new Server within the existing bounded handshake budget. Against an old or incompatible Server they remain disconnected and use the existing raw-input fallback, rather than interpreting unnegotiated frames. A late acknowledgement from an old registration cannot authorize another one.

Append opcodes; never change released values or reuse them. An incompatible layout needs a new major protocol and an explicit migration, not another copy of a header. Minor additions must be optional capabilities.

CharacterSetShortcut is optional and is not included in the default capability set. Windows implementations that support it pass Capabilities | CharacterSetShortcut to Hello / Negotiate. Only after negotiating this bit may a Chinese-mode client consume Ctrl+Shift+F (no Alt or Windows modifier) and send the existing KeyEvent with keycode F and Shift/Control modifier bits. The server toggles the persisted character set without clearing composition, and refreshes the current candidate page and toolbar. It sends no key reply. Clients suppress auto-repeat and must not replay an ambiguously delivered toggle; older peers simply omit the optional bit.

tests/windows_ipc_contract.cpp executes wire-layout/upgrade/framing cases on all Engine CI platforms and both Windows TSF architectures.

TrilingualCycle is optional. A supporting client advertises its capability and consumes the existing configured language hotkeys only while the Server's TrilingualCycleChanged setting ([keybindings] trilingual_cycle) is enabled. After matching a hotkey through the existing shortcut handler, the client sends a normalized VK_SHIFT whose modifiers_down carries FanyImeTrilingualInput::EncodeCycleRequest(ime_open, japanese): an explicit request bit plus the client's own OPENCLOSE and native-language state. A plain VK_SHIFT is still the binary toggle and is never treated as a cycle, and raw Shift key-down events never request one. The Server computes the destination from the request's state with FanyImeTrilingualInput::Destination; if its setting was turned off while the request was in flight, it still answers, with the binary-toggle destination. The Server retains any already selected word prefix and commits the remaining raw spelling, matching the existing language toggle. It replies with TrilingualCycle: destination (0 Chinese, 1 Japanese, 2 English), a tab separator, and the exact text to commit. The client commits and ends composition before applying the destination compartment in the same edit session. The Server must not also send a worker candidate commit or compartment switch for that key, and leaves the requester out of the InputModeChanged broadcast: the reply is that client's language update. Clients that did not negotiate the capability retain their existing language toggle.

backend/protocol.json 定义 MSIME-Backend 的可选共通 HTTP 服务 API,详见后端协议与兼容性。