File: README.md
简体中文 · English
OpenAI Translator for Bob
使用 OpenAI、Google Gemini、MiniMax 或 OpenAI 兼容 API 进行翻译、润色和语法修正的 Bob 插件。
默认配置使用 OpenAI。安装后填写 API Key 即可开始翻译,其他选项按需修改。
安装与使用
- 安装 Bob 1.8.0 或更高版本。
- 下载并打开最新的 openai-translator.bobplugin。
- 打开 Bob 的服务配置,找到 OpenAI Translator,填写 API Key。
- 保存配置后即可翻译。
配置
使用 Gemini 或 MiniMax 时,在模型中选择对应选项;使用第三方 API 服务时,按其文档填写模型和完整 API URL。
功能
- 翻译 Bob 支持的语言。
- 源语言与目标语言相同时,自动进行润色和语法修正。
- 默认启用流式输出,并支持取消请求。
- 默认使用模型自身的推理设置,也可降至模型支持的最低档位。
- 系统指令可改变用途,用户指令可调整每次请求的术语、语气或格式。
开发与贡献
开发环境、验证命令和提交要求见贡献指南。运行时设计和外部文档依据见架构说明。
File: docs/architecture.md
Architecture
Last verified: 2026-07-23.
Runtime boundary
Bob runs plugins in JavaScriptCore, not Node.js or a browser. Runtime code may use JavaScript built-ins, Bob APIs, and bundled pure JavaScript only. The build produces one CommonJS main.js; Node.js is limited to build and test scripts.
The runtime path is intentionally small:
$option
-> parseOptions()
-> resolveModelControls()
-> provider codec
-> shared $http transport
-> Bob stream/completion callbackssrc/main.tsis the Bob entry point.src/config.tsparses and freezes one configuration object, derives the provider, and rejects invalid complete API URLs.src/utils/model-capabilities.tsowns the curated model catalog and model-specific reasoning mappings.src/adapter/*.tsowns provider URL, authentication, wire request, wire response, validation, and stream event shapes.src/adapter/base.tsowns cancellation, network lifecycle, and exactly-once completion.src/utils/sse.tsowns bounded SSE parsing independently of provider capability rules.
Adapters never read $option. Provider codecs receive a validated configuration and do not know how Bob stores options.
Configuration contract
Bob's public option schema provides static text and menu fields. It does not expose a documented conditional-field mechanism. The plugin therefore keeps the common path short instead of exposing every internal adapter choice.
The current configuration uses these decisions:
- The default OpenAI path parses and runs when Bob supplies only an API Key. Runtime defaults cover model, streaming, and reasoning.
- Provider is derived rather than user-selected. With no API URL, the model selects the official OpenAI, Gemini, or MiniMax adapter. With an API URL, Azure hosts and paths select Azure OpenAI, verified MiniMax official hosts retain the MiniMax stream codec, and other URLs use the OpenAI-compatible adapter.
- API URL is optional and complete. The
/responsesor/chat/completionssuffix selects the protocol without separate Base URL, path, or protocol fields. - Temperature is absent from the UI and every request. Provider defaults avoid invalid parameters as model sampling contracts evolve.
- Reasoning has two choices. Default sends no control. Disable maps to the lowest verified model-specific setting; models without a verified mapping receive no control.
- Editable System Prompt and User Prompt defaults preserve their distinct roles: the system prompt defines purpose, while the user prompt shapes each input within that purpose. Both support
$text,$sourceLang, and$targetLang. - The default system prompt starts with the translation role and explicitly prevents instruction-like source text from becoming a command. The raw source remains a separate user message.
- Menu values are case-insensitively sorted by
value; thecustommodel entry is the only fixed first item.
Provider contracts
| Provider | Protocol | Authentication | Validation |
|---|---|---|---|
| Azure OpenAI | Responses or Chat Completions | api-key header |
Minimal generation request |
| Gemini | GenerateContent | x-goog-api-key header |
Model listing |
| MiniMax | Chat Completions | Bearer token | Minimal generation request |
| OpenAI | Responses | Bearer token | GET /v1/models |
| OpenAI Compatible | Responses or Chat Completions | Bearer token | Minimal generation request |
Provider dispatch is an exhaustive TypeScript switch. A new wire provider requires one union member, one provider definition, one codec, a derivation rule, and contract tests. No user-facing provider menu, dependency-injection container, or secondary class hierarchy is needed.
Model controls
resolveModelControls(provider, model, mode) is the only runtime capability resolver.
Default always omits the provider control.
Only exact model IDs with a current provider contract receive a control:
| Model ID | Disable |
|---|---|
gemini-2.5-flash, gemini-2.5-flash-lite |
thinking budget 0 |
gemini-2.5-pro |
thinking budget 128 |
gemini-3-flash-preview, gemini-3.5-flash, gemini-3.5-flash-lite, gemini-3.6-flash |
thinking level minimal |
gemini-3-pro-preview, gemini-3.1-pro-preview |
thinking level low |
gpt-5 |
minimal |
gpt-5.3-codex |
low |
gpt-5.4-mini, gpt-5.6, gpt-5.6-luna, gpt-5.6-sol, gpt-5.6-terra |
none |
gpt-5-pro |
high |
MiniMax-M3 |
thinking disabled |
| Any other ID | omitted |
Request codecs translate the normalized result into reasoning, reasoning_effort, thinkingConfig, or thinking. Capability code does not construct transport payloads.
MiniMax requests set reasoning_split so reasoning does not enter the translated text. Its documented cumulative stream content is converted back to deltas before Bob callbacks.
MiniMax validation disables thinking and limits output for M3. It does not cap M2.x output because those models cannot disable thinking, and a short limit can end the response before translated content appears.
Gemini uses stateless generateContent and streamGenerateContent requests because each Bob translation is one independent generation. The Interactions API's stateful and agentic lifecycle is not needed here.
To add a curated model:
- Add its ID and provider to
MODEL_CATALOGin sorted order. - Add an exact capability entry only when current provider documentation verifies its parameter contract.
- Add the same menu entry to
public/info.json. - Add or update capability, provider-body, and metadata tests.
The metadata test fails if the menu and runtime catalog differ.
Transport invariants
- Streaming and non-streaming requests both receive
query.cancelSignal. - Every translation calls
query.onCompletiononce. - Provider error events are parsed before text deltas.
- Invalid SSE is an API error, not an empty success.
- SSE buffering is limited to 1 MiB.
- Non-streaming output is returned as one paragraph so Bob preserves model formatting and blank lines.
- Validation completes on every success, error, and unexpected-response path.
- API keys and authorization headers are never logged.
eventsource-parser remains bundled because it correctly handles arbitrary chunk boundaries and multiline SSE without relying on browser APIs.
Performance
bun run benchmark rebuilds the bundle, then reports absolute timings for capability resolution, adapter construction, request construction, and SSE parsing together with the current dist/main.js size. Each timing is the median of nine samples with 100,000 local operations.
The benchmark excludes network latency. Compare results only when the machine, Bun version, workload, and sampling method are the same; the repository does not claim a cross-version improvement without a freshly reproduced baseline.
Release safety
Local packages append a lowercase development build suffix to the repository version only inside the generated archive. Bob ignores lower, equal, and extra-component versions during installation; <current-version>dev is newer than the matching stable version and older than the next patch release.
Version metadata and its annotated tag are pushed atomically. A new GitHub release stays unpublished until its plugin asset uploads successfully. Reruns build from the tagged source: an unfinished draft asset may be replaced, while a published release is never modified and its existing asset supplies the Appcast hash.
The Appcast is committed only after the release asset is available. If the default branch advances before that commit is pushed, the push fails without moving the tag or replacing the published asset; rerunning the workflow rebuilds the Appcast from those canonical bytes.
Comparable-project review
The review used current repository heads on 2026-07-23. No reviewed project had a complete model-capability matrix.
| Project | Adopted | Rejected |
|---|---|---|
CaicoLeung/bob-plugin-ollama-translator at 1b08311 |
Small request bodies, shared streaming transport, bundled SSE parser | Unconstrained provider/model combinations and finish-reason-only completion |
kakehashi-inc/multi-ai-translator at 2385e3a |
Provider/dispatch responsibility boundary | Browser APIs, SDKs, fetch, and fixed cross-model generation parameters |
n-AChegYag/bob-plugin-grok-translator at 7a6d8a8 |
Provider-owned native wire shapes | Undocumented dependsOn, scattered provider switches, universal Temperature |
vitoegg/BobTranslate at dc19ca7 |
Compact provider metadata and terminal stream handling | Separate plugin packages, unconditional reasoning/Temperature, duplicated model defaults |
wuzeyou/bob-plugin-zhipu-translator at bc6a529 |
Provider-specific thinking enable/disable mapping | One global rule that assumes thinking always controls Temperature |
Bob documentation coverage
The official sitemap and plugin sidebar exposed 29 /plugin/ pages. All 29 were read on 2026-07-23.
| # | Official page | Application |
|---|---|---|
| 1 | Develop plugins | JavaScriptCore runtime boundary |
| 2 | Create a plugin | Required package files |
| 3 | Configure info.json | Static option schema and numeric text height |
| 4 | Implement main.js | Exported entry functions |
| 5 | Text translation | Query, stream, completion, cancellation, validation, timeout |
| 6 | OCR | Reviewed; outside this translate plugin |
| 7 | Text to speech | Reviewed; outside this translate plugin |
| 8 | Debug plugins | Bob log and exported-log workflow |
| 9 | Package plugins | Flat .bobplugin package layout |
| 10 | Publish plugins | Appcast version, hash, URL, minimum Bob version |
| 11 | API introduction | Available Bob globals |
| 12 | Modules | Simplified CommonJS, plugin-local modules only |
| 13 | Built-in modules | No assumption of Node built-ins |
| 14 | $env |
Reviewed; no runtime need |
| 15 | $info |
Plugin metadata boundary |
| 16 | $option |
Flat string settings read once |
| 17 | $log |
Secret-safe logging boundary |
| 18 | $http |
JSON headers, stream/final handler shape, timeout, cancellation |
| 19 | $websocket |
Reviewed; SSE over $http is sufficient |
| 20 | $file |
Read-only plugin directory and sandbox scope |
| 21 | $data |
Raw stream data contract |
| 22 | $timer |
Reviewed; no timer-based batching required |
| 23 | $signal |
Cancellation signal contract |
| 24 | Service error | Error type, message, addition, troubleshooting link |
| 25 | Translate result | Paragraph preservation and optional Bob 1.15 reasoning display |
| 26 | OCR result | Reviewed; outside this translate plugin |
| 27 | TTS result | Reviewed; outside this translate plugin |
| 28 | Built-in icons | Reviewed; repository icon retained |
| 29 | Language codes | Bob language IDs and supported-language list |
The linked Bob 1.8 plugin changes were also reviewed for streaming and cancellation behavior.
Provider sources
- Azure OpenAI Responses
- Cloudflare AI Gateway REST API
- Gemini API selection
- Gemini latest models and sampling changes
- Gemini prompting strategies
- Gemini thinking
- MiniMax China OpenAI-compatible API
- MiniMax OpenAI-compatible API
- OpenAI model guidance
- OpenAI prompt engineering
- OpenAI reasoning
- OpenAI Responses migration
- OpenRouter Quickstart
- Vercel AI Gateway Chat Completions
Rejected complexity
- Undocumented Bob option fields such as
dependsOn - A user-visible provider or API-protocol selector
- Separate API Base URL and API Path fields
- Provider SDKs,
fetch, browser streams, or Node.js runtime modules - A global Temperature override
- A dependency-injection container or generic protocol framework
- Multiple separately published plugins solely to obtain provider-specific settings forms
Manual Bob verification
Static checks cannot prove behavior inside the installed Bob host. Before release, install the package in Bob 1.8.0 and a current Bob version, confirm every option renders, validate one configured provider, and complete one streaming and one non-streaming translation without a runtime error.
File: docs/configuration_manual_CN.md
配置手册
填写 API Key 后即可使用默认的 OpenAI 配置,包括默认模型、官方 API、流式输出和模型默认推理设置。
最快开始
- 在 Bob 的服务配置中找到 OpenAI Translator。
- 填写 OpenAI API Key。
- 保存配置并开始翻译。
使用 Gemini 或 MiniMax 官方 API 时,选择对应模型。使用第三方 API 服务时,按其文档填写模型和完整 API URL。
API Key
多个 Key 可用英文逗号分隔,插件每次请求会随机选择一个。
Key 只会发送到最终使用的 API URL。插件不会记录 Key 或请求头。
模型
默认模型为 gpt-5.6-luna。内置模型包括:
gemini-3.5-flash-litegemini-3.6-flashgpt-5.4-minigpt-5.6-lunaMiniMax-M2.7-highspeedMiniMax-M3
API URL 留空时,插件按模型自动选择官方 API:
| 模型 | 使用的官方 API |
|---|---|
gemini-* |
Gemini GenerateContent API |
gpt-* 或其他模型 |
OpenAI Responses API |
MiniMax-* |
MiniMax Chat Completions API |
选择「自定义模型」后,填写 API 实际接受的模型 ID。OpenAI 兼容 API 可能使用带命名空间的模型 ID,例如 openai/...,应以服务文档为准。Azure OpenAI 使用部署名。
API URL
API URL 可留空。留空时使用模型对应的官方地址。
使用第三方 API 服务时填写完整请求 URL。当前支持 OpenAI 兼容 API 和 Azure OpenAI,地址必须以 /responses 或 /chat/completions 结尾。插件根据这个结尾选择请求格式。
常见示例:
- Azure OpenAI:
https://RESOURCE_NAME.openai.azure.com/openai/v1/responses - Cloudflare AI Gateway:
https://api.cloudflare.com/client/v4/accounts/ACCOUNT_ID/ai/v1/chat/completions - MiniMax 中国区:
https://api.minimaxi.com/v1/chat/completions - OpenAI 兼容 API:
https://gateway.example.com/v1/responses - OpenRouter:
https://openrouter.ai/api/v1/chat/completions - Vercel AI Gateway:
https://ai-gateway.vercel.sh/v1/chat/completions
填写 API URL 后,普通地址使用 Bearer Token。*.openai.azure.com 地址以及包含 /openai/v1 或 /openai/deployments/ 的 Azure 路径会自动使用 api-key 请求头。
流式输出
默认开启,译文会随模型生成逐步显示。关闭后会等待完整结果再显示。
两种模式都会响应 Bob 的取消操作。流式响应格式错误、API 错误或空结果都会作为失败返回,不会产生空白的成功结果。
推理
默认情况下,插件不发送推理控制参数,由模型决定。
| 选项 | 行为 |
|---|---|
| 默认 | 不发送推理控制参数,使用模型默认设置 |
| 关闭 | 支持关闭时禁用;无法完全关闭时使用最低档位 |
「关闭」只会向已确认支持该设置的模型发送参数。未知模型不会收到推理参数。第三方 API 对这些参数的支持程度不同;如果服务不支持,使用「默认」。
系统指令和用户指令
系统指令决定插件的用途和基本规则。要把默认翻译改成润色、改写或其他文本处理任务,应修改系统指令。
用户指令决定每次如何把原文交给模型。用途不变时,可在这里补充术语、语气、格式等本次请求规则。
两个字段都有可直接编辑的默认值,并支持:
$text:原文$sourceLang:源语言$targetLang:目标语言
例如,系统指令保持翻译用途时,可以把用户指令改为:
保留技术术语的英文原文,并保持 Markdown 格式:
$text同一变量出现多次时会全部替换。
Temperature
插件不提供 Temperature 配置,也不会发送 temperature。不同模型对该参数的支持正在分化,省略它可以使用模型维护的有效默认值,并避免向固定采样参数的模型发送无效字段。
排错
- 只填 API Key 仍验证失败:确认它是有效的 OpenAI Key,并可访问默认模型。
- 使用 Gemini 或 MiniMax 全球 API:选择对应模型,不要填写 API URL;MiniMax 中国区使用上面的中国区地址。
- 使用 OpenAI 兼容 API:确认模型 ID 与服务文档一致,并填写完整 API URL。
API URL 格式不正确:检查地址是否以/responses或/chat/completions结尾。- Azure OpenAI:自定义模型填写部署名,API URL 使用
*.openai.azure.com的完整请求地址。 - 翻译接口不支持推理参数:将「推理」改为「默认」。
官方参考:
- Azure OpenAI Responses API
- Bob 插件文档
- Cloudflare AI Gateway REST API
- Gemini API
- MiniMax OpenAI-compatible API
- MiniMax 中国区 OpenAI-compatible API
- OpenAI API
- OpenRouter Quickstart
- Vercel AI Gateway Chat Completions
File: docs/configuration_manual_EN.md
Configuration Manual
Enter an API key to use the default OpenAI configuration: the default model, official API, streaming output, and model-default reasoning behavior.
Quick start
- Find OpenAI Translator in Bob's service settings.
- Enter an OpenAI API key.
- Save the configuration and translate.
For the official Gemini or MiniMax API, select the corresponding model. For a third-party API service, enter the model and full API URL specified by the service.
API key
Separate multiple keys with commas to select one randomly for each request.
A key is sent only to the resolved API URL. The plugin does not log keys or request headers.
Model
The default model is gpt-5.6-luna. Built-in models are:
gemini-3.5-flash-litegemini-3.6-flashgpt-5.4-minigpt-5.6-lunaMiniMax-M2.7-highspeedMiniMax-M3
With an empty API URL, the model selects the official API:
| Model | Official API |
|---|---|
gemini-* |
Gemini GenerateContent API |
gpt-* or any other model |
OpenAI Responses API |
MiniMax-* |
MiniMax Chat Completions API |
After selecting Custom model, enter the model ID accepted by the API. An OpenAI-compatible API may use a namespaced ID such as openai/...; follow the service documentation. Azure OpenAI uses a deployment name.
API URL
The API URL may be empty. An empty value uses the official endpoint selected by the model.
For a third-party API service, enter the full request URL. The plugin currently supports OpenAI-compatible APIs and Azure OpenAI, and the URL must end in /responses or /chat/completions. The suffix selects the request format.
Common examples:
- Azure OpenAI:
https://RESOURCE_NAME.openai.azure.com/openai/v1/responses - Cloudflare AI Gateway:
https://api.cloudflare.com/client/v4/accounts/ACCOUNT_ID/ai/v1/chat/completions - MiniMax China:
https://api.minimaxi.com/v1/chat/completions - OpenAI-compatible API:
https://gateway.example.com/v1/responses - OpenRouter:
https://openrouter.ai/api/v1/chat/completions - Vercel AI Gateway:
https://ai-gateway.vercel.sh/v1/chat/completions
With an API URL, ordinary hosts use a Bearer token. A *.openai.azure.com host or an Azure path containing /openai/v1 or /openai/deployments/ automatically uses the api-key header.
Streaming
Streaming is enabled by default, so text appears as the model generates it. Disable it to wait for the complete result.
Both modes respond to Bob's cancellation action. Invalid stream data, API errors, and empty responses are returned as failures rather than blank successful results.
Reasoning
By default, the plugin omits reasoning controls and lets the model decide.
| Setting | Behavior |
|---|---|
| Default | Omit reasoning controls and use the model default |
| Disable | Disable reasoning where supported; otherwise use the lowest level |
Disable sends a reasoning control only to models with verified support. Unknown models receive no reasoning field. Support varies between third-party APIs; use Default if the service rejects the field.
System and user prompts
The system prompt defines the plugin's purpose and core rules. Change it to turn the default translation task into polishing, rewriting, or another text-processing task.
The user prompt defines how each input is presented to the model. While keeping the same purpose, use it to add terminology, tone, formatting, or other per-request rules.
Both fields have editable defaults and support:
$text: input text$sourceLang: source language$targetLang: target language
For example, while keeping translation as the system purpose, the user prompt can be:
Keep technical terms in English and preserve Markdown:
$textEvery occurrence of a variable is replaced.
Temperature
The plugin has no Temperature setting and does not send temperature. Model support for this parameter now differs, so omission uses a valid model-maintained default and avoids sending an invalid field to models with fixed sampling.
Troubleshooting
- Validation fails with only an API key: confirm that it is a valid OpenAI key with access to the default model.
- Gemini or the global MiniMax API: select the corresponding model and leave the API URL empty; for MiniMax China, use the China API URL above.
- OpenAI-compatible API: use the model ID from its documentation and enter the full API URL.
Invalid API URL: ensure the address ends in/responsesor/chat/completions.- Azure OpenAI: enter the deployment name as the custom model and use the full
*.openai.azure.comrequest URL. - The translation API rejects reasoning fields: set Reasoning to Default.
Official references:
- Azure OpenAI Responses API
- Bob plugin documentation
- Cloudflare AI Gateway REST API
- Gemini API
- MiniMax China OpenAI-compatible API
- MiniMax OpenAI-compatible API
- OpenAI API
- OpenRouter Quickstart
- Vercel AI Gateway Chat Completions
File: docs/README_EN.md
简体中文 · English
OpenAI Translator for Bob
Translate, polish, and correct grammar in Bob with OpenAI, Google Gemini, MiniMax, or an OpenAI-compatible API.
The default configuration uses OpenAI. Enter an API key after installation and start translating; change the other settings only when needed.
Install and use
- Install Bob 1.8.0 or later.
- Download and open the latest openai-translator.bobplugin.
- Open Bob's service settings, find OpenAI Translator, and enter an API key.
- Save the configuration and translate.
Configuration
For Gemini or MiniMax, select the corresponding model. For a third-party API service, enter the model and full API URL specified by the service.
See the configuration manual for reasoning and system and user prompts.
Features
- Translate every language supported by Bob.
- Polish and correct grammar when source and target languages match.
- Stream results by default and cancel in-flight requests.
- Use the model's default reasoning behavior, or reduce it to the lowest supported setting.
- Change the purpose with the system prompt and refine each request with the user prompt.
Development and contributions
See the contribution guide for the development environment, validation commands, and submission requirements. Runtime decisions and source references are in the architecture notes.