dsh-connect-minimaxcode 0.6.8 → 0.7.0
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/README.en.md +85 -1
- package/README.md +85 -1
- package/docs/ACCOUNT-ENDPOINTS.md +118 -0
- package/docs/CREDENTIALS.md +65 -0
- package/docs/ERROR-TAXONOMY.md +72 -0
- package/docs/H3-GENERATION.md +109 -0
- package/docs/README.md +38 -0
- package/lib/client.js +179 -17
- package/lib/index.d.ts +40 -0
- package/lib/index.js +246 -12
- package/package.json +10 -9
package/README.en.md
CHANGED
|
@@ -57,10 +57,47 @@ Either:
|
|
|
57
57
|
1. **The MiniMax Code desktop app (China region) installed and signed in** — the plugin reuses its sign-in (the easy way)
|
|
58
58
|
2. **Nothing installed** — press "Sign in to MiniMax Code" on the plugin page; the plugin starts an OAuth device code flow and you confirm with your own MiniMax account in a browser (this needs `account.minimax.cn` to be reachable)
|
|
59
59
|
|
|
60
|
-
Plus DSH desktop (built-in core `>=0.
|
|
60
|
+
Plus DSH desktop (built-in core `>=0.1.6-alpha.2 <0.3.0`, see `engines.dsh` in `package.json`; tested on `0.2.2-rc.1`) or the Web profile.
|
|
61
61
|
|
|
62
62
|
> **Sending a picture needs the host's attachment service**: the plugin does not read images itself — the host's durable attachment service turns a stored reference into request bytes, and the plugin only connects the two. On a host without that service the plugin still loads and text still works; only image requests are refused (`pi-ai image input requires the durable attachment service`).
|
|
63
63
|
|
|
64
|
+
## Compatibility: the oldest DSH this works on
|
|
65
|
+
|
|
66
|
+
**The oldest supported DSH is `0.1.6-alpha.2`** — that is the range in `engines.dsh`. The plugin used to declare `0.2.1-rc.2`, which was a conservative floor rather than a technical one; this time the host packages' published history was searched, and the floor moved down to the version where each feature actually exists.
|
|
67
|
+
|
|
68
|
+
The host publishes its own packages under **the same version numbers as the desktop** (DSH `0.2.2-rc.1` ships `0.2.2-rc.1` packages), so "which release first had this API" can be answered straight from npm. Every row below was read out of that version's published source:
|
|
69
|
+
|
|
70
|
+
| Host capability | First version | What the plugin uses it for |
|
|
71
|
+
| --- | --- | --- |
|
|
72
|
+
| `llm.registerAdapter` | `0.0.1-rc.1` | registering the MiniMax Code provider |
|
|
73
|
+
| `webServer.register` (`kind: 'exact'`) | `0.0.1-rc.1` | the status, action, generation and capability routes |
|
|
74
|
+
| `attachments.saveImage` | `0.0.1-rc.1` | storing a generated picture as an attachment |
|
|
75
|
+
| client `slots` / `sessions` services | `0.0.1-rc.3` | the credit pill and the composer tool row |
|
|
76
|
+
| `conversation.input.left` slot | `0.0.1-rc.1` | where the pill and the generate entry sit |
|
|
77
|
+
| `dsh.client.inject` / `immediately` | `0.0.1-rc.1` | loading the client half |
|
|
78
|
+
| `session.beginSubmission` / `binding()` / `scope()` | `0.1.2-alpha.2` | the picture going out **and showing up in the conversation** |
|
|
79
|
+
| `inputActions.addAttachments` / `conversation.createDrafts` | `0.1.3-alpha.2` | the picture going into the input box (the draft channel) |
|
|
80
|
+
| **`plugins.bundle.config` slot** | **`0.1.6-alpha.2`** | **the plugin page (generation panel, check-in switch, the full bill)** |
|
|
81
|
+
| **`cordis.patch` manifest patch** | **`0.1.6-alpha.2`** | **offering the provider in the model picker without changing the default** |
|
|
82
|
+
|
|
83
|
+
**The last two rows are the real floor.** The plugin page and the manifest patch both begin at `0.1.6-alpha.2`; older hosts only have the plugin manager's own `settings.plugin.item` — a card inside the settings section, on a keyed slot — which is not a plugin page.
|
|
84
|
+
|
|
85
|
+
### What an older host still gets
|
|
86
|
+
|
|
87
|
+
The plugin is not useless on an older host; it gives up one thing at a time. That is also why the floor sits at `0.1.6-alpha.2` rather than lower: **the plugin page is the plugin's main surface** (the H3 generation panel, the check-in switch and the detailed balance all live there), and claiming support while it is missing would be a lie.
|
|
88
|
+
|
|
89
|
+
| Host version | What still works | What is missing |
|
|
90
|
+
| --- | --- | --- |
|
|
91
|
+
| `>= 0.1.6-alpha.2` | everything | —— |
|
|
92
|
+
| `0.1.3-alpha.2` – `0.1.6-alpha.1` | the models, the credit pill, the generate entry in the composer, a picture reaching the conversation | no plugin page (the generation panel and the check-in switch live there); the manifest patch has no effect, so the model must be picked by hand |
|
|
93
|
+
| `0.1.2-alpha.2` – `0.1.3-alpha.1` | less again: the picture can still be sent straight through the session | no draft channel (`createDrafts` / `addAttachments` did not exist yet) |
|
|
94
|
+
| `< 0.1.2-alpha.2` | the text models and the credit display | a picture reaches the model but **does not show in the conversation** (no local echo, `beginSubmission`) |
|
|
95
|
+
|
|
96
|
+
A host that does not know a manifest field ignores it (the manifest is not validated strictly), so an old host does not refuse the plugin over `cordis.patch` — it merely has no effect.
|
|
97
|
+
|
|
98
|
+
> This table was **read out of the published history of every host package on npm**, version by version — not estimated.
|
|
99
|
+
>
|
|
100
|
+
> **And it does not stop at an inference**: this repository's lockfile resolves the host packages to `0.1.6-alpha.2`, so every release compiles, builds and runs the whole suite **against that oldest host** — the floor is verified on every release, not concluded once. The method is written down in the repository: pull each host package at each version and look for the API in the source it shipped.
|
|
64
101
|
## Installation
|
|
65
102
|
|
|
66
103
|
**Option 1: install from the Git repository** (recommended, gets the latest code)
|
|
@@ -382,8 +419,55 @@ The OAuth token is valid for about an hour and is refreshed automatically by the
|
|
|
382
419
|
- **The context window is declared as the gateway's real ceiling (1,000,000), not the 512,000 in the catalog.** Upstream's `limit.context` is the *default* window and the billing tier boundary (input above 512k costs more); the largest entry of `context_window_options` is the ceiling the gateway enforces. Measured on 2026-10-25: 946,206 tokens were served normally, 1,050,000 were refused (`invalid params, context window exceeds limit (2013)`). Declaring 512,000 meant every turn of a long conversation was reported as `pi-ai detected context overflow` — while the model had answered perfectly well and the reply was thrown away.
|
|
383
420
|
- **The device code flow needs `account.minimax.cn` to be reachable**, and the browser that authorizes it has to be able to sign in to a MiniMax account. On some restricted networks the authorization page cannot be opened.
|
|
384
421
|
|
|
422
|
+
## How to read the version number
|
|
423
|
+
|
|
424
|
+
The plugin follows semantic versioning, and **each level means the same thing** — so the version number says what to expect:
|
|
425
|
+
|
|
426
|
+
| Version | What it means |
|
|
427
|
+
| --- | --- |
|
|
428
|
+
| **patch** (x.y.**z**) | a defect is fixed. **No new configuration key, no interface change.** The existing surface and behaviour stay; one thing that was wrong is now right. |
|
|
429
|
+
| **minor** (x.**y**.0) | a **user-visible** capability is added, or the shape of an existing message changes. **No interface change**; the meaning of the existing configuration keys is unchanged. |
|
|
430
|
+
| **major** (**x**.0.0) | a breaking change: the meaning of an existing configuration key changes, the surface is rearranged enough to need re-learning, or the host interface it depends on has moved on. |
|
|
431
|
+
|
|
432
|
+
Every entry in the changelog opens with why it is that level, and with **what this release deliberately did not do** — the boundaries are worth knowing more than the features, so they come first.
|
|
385
433
|
## Changelog
|
|
386
434
|
|
|
435
|
+
### 0.7.0 (2026-11-15)
|
|
436
|
+
|
|
437
|
+
> The version is **minor**: a new "Diagnostics" section and a switch for showing the balance in the composer, and a different shape for the message a failed generation shows. **No interface change**; the meaning of the existing configuration keys is unchanged.
|
|
438
|
+
|
|
439
|
+
#### Added
|
|
440
|
+
|
|
441
|
+
- **A "Diagnostics" section on the plugin page**: a read-only list of facts — the plugin version, the region, the upstream hosts, how the plugin is signed in, where the model catalog came from, which pieces of the host it found (eight of them), and **the upstream's own words about its most recent failure**. The one reason it exists is that **it can be copied into an issue as it stands**: there is no control in it that changes anything. The host's own version is **not** in it, because the host does not hand its version to a plugin — a line that had to be guessed would be worse than no line.
|
|
442
|
+
- **A "show the credit balance in the composer" switch**: on by default. Turning it off hides the balance in the pill and changes nothing else; it can be turned back on at any time.
|
|
443
|
+
|
|
444
|
+
#### Changed
|
|
445
|
+
|
|
446
|
+
- **A failed generation now says three things instead of one**: ① what to do (by the kind of failure); ② **that this request may already have been charged for** (when a video task was submitted and could not be read back); ③ **the upstream's own words**, collapsed, quoted rather than paraphrased.
|
|
447
|
+
- **Failures are classified** into `credentials` / `parameters` / `subscription` / `quota` / `rate-limited` / `upstream` / `local`, each with its own remedy. The classification reads the failure's *shape* (the HTTP status and the wording) rather than its code — a code is a number some other system chose, and the day it is renamed or withdrawn, a classifier keyed on it would quietly stop matching, while one keyed on what the failure *is* keeps working.
|
|
448
|
+
|
|
449
|
+
#### Deliberately not done
|
|
450
|
+
|
|
451
|
+
- **The session-title requests are not diverted to a lighter model.** The host sends one per new session, and it goes to the main model. Measured (2026-11-15): **our upstream catalog holds two models** (`MiniMax-M3` and `MiniMax-M3.1-Flash`, both with a 512K context, a 128K output and reasoning), there is **no lighter one**, and the catalog carries **no price field** — so there is no way to tell what diverting them would save. A change with no measured evidence behind it is not made.
|
|
452
|
+
- **No cooldown for the failures that spent nothing.** Only the ones where the upstream may have accepted the work, and may have charged for it, are held back; a bad parameter, a missing sign-in and a request refused locally cost nothing and may be retried at once.
|
|
453
|
+
- **No host version in the diagnostics.** The host does not offer its version to a plugin; that line could only be guessed.
|
|
454
|
+
- **No "drop the tools for this model" fallback.** Letting a model quietly lose every tool is harder to notice than an error.
|
|
455
|
+
|
|
456
|
+
#### Testing
|
|
457
|
+
|
|
458
|
+
- New: `tests/failure.spec.ts` (9), `tests/generation-cost.spec.ts` (7), `tests/failure-wording.spec.ts` (5), `tests/diagnostics.spec.ts` (6), `tests/control-layers.spec.ts` (6).
|
|
459
|
+
- **Mutation checks**: every fix in this release was reverted on its own to confirm the matching case turns red. All seven mutations of the classifier and all four of the cost distinction were caught. One mutation of the cost distinction **survived at first** — the case exercised the HTTP-failure branch while the mutation changed the "the answer was not JSON" one. Adding a case for that road caught it. It is exactly what "the test passed but was not proving what it claimed" looks like.
|
|
460
|
+
- The protocol findings moved into `docs/` (published with the package): H3 generation, the account endpoints, the credentials and the error taxonomy, each fact carrying the date it was measured.
|
|
461
|
+
|
|
462
|
+
### 0.6.9 (2026-11-13)
|
|
463
|
+
|
|
464
|
+
- **The oldest supported DSH moved from `0.2.1-rc.2` down to `0.1.6-alpha.2`.** The old floor was a conservative value, not a technical one. This release searched the host packages' published history version by version and, for every host capability the plugin uses, found the release it first appeared in.
|
|
465
|
+
- **The host publishes its own packages under the same version numbers as the desktop** (DSH `0.2.2-rc.1` ships `0.2.2-rc.1` packages), so "which release first had this API" can be answered straight from npm — every row of the compatibility table was read out of the source that host package version actually shipped.
|
|
466
|
+
- **Two things set the real floor**: the `plugins.bundle.config` slot the plugin page lives in, and the `cordis.patch` manifest patch that offers the provider in the model picker. Both begin at `0.1.6-alpha.2`. Older hosts only have the plugin manager's own `settings.plugin.item` — a card inside the settings section, on a keyed slot — which is not a plugin page.
|
|
467
|
+
- **Older hosts are not useless, they give up one thing at a time** (the README has the full table): from `0.1.3-alpha.2` the models, the credit pill, the generate entry in the composer and a picture reaching the conversation all work, only the plugin page is missing; from `0.1.2-alpha.2` a picture reaches the conversation too, only the draft channel is missing. A host that does not know a manifest field ignores it (the manifest is not validated strictly), so an old host does not refuse the plugin over `cordis.patch` — it merely has no effect.
|
|
468
|
+
- The peer dependency floors for the host packages moved to `>=0.1.6-alpha.2` as well, so an older host's own versions satisfy the range. **The lockfile resolves to `0.1.6-alpha.2`** — so every release compiles, builds and runs the whole suite against that oldest host, and the floor is verified on every release.
|
|
469
|
+
- The README gained a "Compatibility: the oldest DSH this works on" section (in both languages), with the evidence table and the degradation ladder.
|
|
470
|
+
|
|
387
471
|
### 0.6.8 (2026-11-13)
|
|
388
472
|
|
|
389
473
|
|
package/README.md
CHANGED
|
@@ -57,10 +57,47 @@
|
|
|
57
57
|
1. **已安装并登录 MiniMax Code 桌面 App(国内版)** —— 插件直接复用它的登录态(最省事)
|
|
58
58
|
2. **什么都不装** —— 在插件页面点「登录 MiniMax Code」,插件发起 OAuth 设备码流,你在浏览器里用自己的 MiniMax 账号确认,插件拿到自己的登录态(需要能访问 `account.minimax.cn`)
|
|
59
59
|
|
|
60
|
-
另外需要 DSH 桌面版(内置内核 `>=0.
|
|
60
|
+
另外需要 DSH 桌面版(内置内核 `>=0.1.6-alpha.2 <0.3.0`,见 `package.json` 的 `engines.dsh`;实测 `0.2.2-rc.1`)或 Web profile。
|
|
61
61
|
|
|
62
62
|
> **发图需要宿主提供附件服务**:图片不是插件自己读的,而是由宿主的持久化附件服务读成请求字节,插件只负责把附件引用接上去。宿主没有附件服务时,插件照常加载、文本照常对话,只是发图会被拒绝(`pi-ai image input requires the durable attachment service`)。
|
|
63
63
|
|
|
64
|
+
## 兼容性:最低支持哪个 DSH 版本
|
|
65
|
+
|
|
66
|
+
**最低支持 DSH `0.1.6-alpha.2`**(`engines.dsh` 里写的就是这个区间)。这一版之前插件声明的是 `0.2.1-rc.2`,那是个保守的下限,不是技术上的;这次下探宿主各包的发布历史后,把下限一路降到了每个功能真正存在的那一版。
|
|
67
|
+
|
|
68
|
+
宿主把它自己的各个包按**与桌面端相同的版本号**发布(DSH `0.2.2-rc.1` 里带的就是 `0.2.2-rc.1` 的包),所以「某个 API 最早出现在哪一版」可以直接对着 npm 上的宿主包查。下面这张表就是这么查出来的 —— 每一行都是宿主包那个版本号里的源码里**实际出现过**这个 API:
|
|
69
|
+
|
|
70
|
+
| 宿主能力 | 最早版本 | 插件拿它做什么 |
|
|
71
|
+
| --- | --- | --- |
|
|
72
|
+
| `llm.registerAdapter` | `0.0.1-rc.1` | 注册 MiniMax Code 模型提供者 |
|
|
73
|
+
| `webServer.register`(`kind: 'exact'`) | `0.0.1-rc.1` | 状态、动作、生成、自检四条路由 |
|
|
74
|
+
| `attachments.saveImage` | `0.0.1-rc.1` | 把生成的图存成附件 |
|
|
75
|
+
| 客户端 `slots` / `sessions` 服务 | `0.0.1-rc.3` | 积分胶囊与输入框工具行 |
|
|
76
|
+
| `conversation.input.left` 插槽 | `0.0.1-rc.1` | 胶囊与「生成图片」入口的落位 |
|
|
77
|
+
| `dsh.client.inject` / `immediately` | `0.0.1-rc.1` | 客户端半边能被加载 |
|
|
78
|
+
| `session.beginSubmission` / `binding()` / `scope()` | `0.1.2-alpha.2` | 图片发出去**并在对话里显示** |
|
|
79
|
+
| `inputActions.addAttachments` / `conversation.createDrafts` | `0.1.3-alpha.2` | 图片放进输入框(草稿通道) |
|
|
80
|
+
| **`plugins.bundle.config` 插槽** | **`0.1.6-alpha.2`** | **插件页(生成面板、签到开关、完整账单)** |
|
|
81
|
+
| **`cordis.patch` 清单补丁** | **`0.1.6-alpha.2`** | **把提供者加进模型选择器而不改默认模型** |
|
|
82
|
+
|
|
83
|
+
**最后两行是真正的下限**:插件页与清单补丁都从 `0.1.6-alpha.2` 起才有,更早的宿主只有插件管理器自己的 `settings.plugin.item`(设置页里的一张卡片,keyed 插槽),不是插件页。
|
|
84
|
+
|
|
85
|
+
### 更早的宿主会怎样
|
|
86
|
+
|
|
87
|
+
插件在更早的宿主上并非完全不能用,只是逐项减少。这也是为什么下限定在 `0.1.6-alpha.2` 而不是更低:**插件页是插件的主界面**(H3 生成面板、签到开关、完整账单都在里面),缺了它而对外声称支持,是骗人。
|
|
88
|
+
|
|
89
|
+
| 宿主版本 | 还能用什么 | 缺什么 |
|
|
90
|
+
| --- | --- | --- |
|
|
91
|
+
| `>= 0.1.6-alpha.2` | 全部功能 | —— |
|
|
92
|
+
| `0.1.3-alpha.2` ~ `0.1.6-alpha.1` | 模型、积分胶囊、输入框里的生成入口、图片进对话 | 没有插件页(生成面板与签到开关在插件页上);清单补丁不生效,需手动选模型 |
|
|
93
|
+
| `0.1.2-alpha.2` ~ `0.1.3-alpha.1` | 再减:图片仍可经会话直接发出 | 草稿通道不可用(`createDrafts` / `addAttachments` 还没有) |
|
|
94
|
+
| `< 0.1.2-alpha.2` | 文本模型与积分显示 | 图片发得出但**对话里不显示**(没有本地回执 `beginSubmission`) |
|
|
95
|
+
|
|
96
|
+
宿主不认识的清单字段会被忽略(不是严格校验),所以老宿主不会因为 `cordis.patch` 而拒绝安装插件 —— 它只是不生效。
|
|
97
|
+
|
|
98
|
+
> 这份表是**对着 npm 上宿主各包的发布历史逐版本查出来**的,不是估计的。
|
|
99
|
+
>
|
|
100
|
+
> **而且不只停在推断上**:本仓库的锁文件把宿主包解析到 `0.1.6-alpha.2`,因此每次发布的 CI 都会**对着这个最老的宿主**编译、构建并跑完全部用例 —— 下限是被每次发布验证着的,不是一次性的结论。查询方式见仓库里的说明:把每个宿主包的每个版本拉下来,看它发布出来的源码里有没有那个 API。
|
|
64
101
|
## 安装
|
|
65
102
|
|
|
66
103
|
**方式一:从 Git 仓库安装**(推荐,拿到最新代码)
|
|
@@ -393,8 +430,55 @@ OAuth 令牌有效期约 1 小时,由客户端自动续期。插件**只在自
|
|
|
393
430
|
- **上下文窗口按网关的真实上限声明(1,000,000),不是目录里的 512,000**。上游 `limit.context` 是**默认档位与计费分界**(输入超过 512k 的部分按更高倍率计费),`context_window_options` 里最大的一档才是网关执行的硬上限。实测(2026-10-25):946,206 tokens 正常受理,1,050,000 被拒(`invalid params, context window exceeds limit (2013)`)。此前按 512,000 声明,长会话一旦过线就**每一轮**都被判成「上下文溢出」,模型其实答得好好的,回复却被丢掉(`pi-ai detected context overflow`)。
|
|
394
431
|
- **设备码流需要能访问 `account.minimax.cn`**,且授权时要在浏览器里能登录 MiniMax 账号。某些内网或受限网络下打不开授权页。
|
|
395
432
|
|
|
433
|
+
## 版本号怎么读
|
|
434
|
+
|
|
435
|
+
本插件的版本号遵循语义化版本,**而且每一级对应的事情是固定的** —— 读版本号就能预知能发生什么:
|
|
436
|
+
|
|
437
|
+
| 版本号 | 意味着什么 |
|
|
438
|
+
| --- | --- |
|
|
439
|
+
| **patch**(x.y.**z**) | 修一处缺陷。**无新增配置项、无接口变化**。已有的界面与行为不变,只是某处原来不对。 |
|
|
440
|
+
| **minor**(x.**y**.0) | 新增一项**用户可见**的能力,或改变已有提示的形状。**无接口变化**,既有配置键的含义不变。 |
|
|
441
|
+
| **major**(**x**.0.0) | 破坏性变化:既有配置键的含义改变、界面重排到需要重新适应,或依赖的宿主接口换代。 |
|
|
442
|
+
|
|
443
|
+
更新记录里的每一版开头都写着这一版为什么是该级别,以及**这一版刻意没做什么** —— 边界比功能更值得知道,所以它写在了前面。
|
|
396
444
|
## 更新记录
|
|
397
445
|
|
|
446
|
+
### 0.7.0(2026-11-15)
|
|
447
|
+
|
|
448
|
+
> 版本号是 **minor**:新增「诊断信息」分栏与「在输入框显示余额」开关,并改变生成失败时的提示形状。**无接口变化**,既有配置键的含义不变。
|
|
449
|
+
|
|
450
|
+
#### 新增
|
|
451
|
+
|
|
452
|
+
- **插件页新增「诊断信息」分栏**:只读事实表 —— 插件版本、区域、上游地址、登录来源、模型目录来源、宿主提供了哪几块能力(八项)、以及**上游最近一次错误的原文**。这一栏存在的唯一理由是**能被整段复制进 issue**:里面没有任何会改设置的控件。宿主的版本号**不在其中**,因为宿主没有把它交给插件 —— 一个要靠猜的行比没有这一行更糟。
|
|
453
|
+
- **「在对话输入框显示积分余额」开关**:默认开。关掉即隐藏胶囊里的余额,积分与其它一切不受影响,随时可以再打开。
|
|
454
|
+
|
|
455
|
+
#### 改变
|
|
456
|
+
|
|
457
|
+
- **生成失败时的提示从一句话变成三件事**:① 该做什么(按失败性质分类);② **本次可能已被上游计费**(视频任务提交后读不回来时);③ **上游的原文**(折叠显示,原样引用不转述)。
|
|
458
|
+
- **失败按性质分类**:`credentials` / `parameters` / `subscription` / `quota` / `rate-limited` / `upstream` / `local` 七类,每类各有各的建议。分类**按失败的形状**(HTTP 状态与措辞)而不是按错误码 —— 错误码是别的系统取的号,它改名或撤销那天,按号分类的代码会安静地不再匹配,而按「失败是什么」分类不会。
|
|
459
|
+
|
|
460
|
+
#### 刻意没做
|
|
461
|
+
|
|
462
|
+
- **没有把会话标题请求改到轻量模型**。宿主每个新会话会发一次标题请求,走的是主模型。实测(2026-11-15):**我们的上游目录里只有两个模型**(`MiniMax-M3` 与 `MiniMax-M3.1-Flash`,同为 512K 上下文 / 128K 输出 / 推理模型),**没有更轻的模型**,而且目录里**没有价格字段** —— 无从判断改过去能省多少。没有实测证据支撑的改动不做。
|
|
463
|
+
- **没有给额度窗口之外的失败加冷却**。只给「上游可能已经受理、可能已计费」的那一类加;「参数错、没登录、本地就拒了」这类一分钱没花的失败**不加冷却**,改完立刻可以重试。
|
|
464
|
+
- **诊断栏里没有宿主版本号**。宿主没有向插件提供它的版本;那一行只能靠猜。
|
|
465
|
+
- **没有做「按模型摘除工具」的降级**。让模型静默失去全部工具能力,比报错更难被发现。
|
|
466
|
+
|
|
467
|
+
#### 测试
|
|
468
|
+
|
|
469
|
+
- 新增 `tests/failure.spec.ts`(9)、`tests/generation-cost.spec.ts`(7)、`tests/failure-wording.spec.ts`(5)、`tests/diagnostics.spec.ts`(6)、`tests/control-layers.spec.ts`(6)。
|
|
470
|
+
- **变异验证**:本轮的每一处修复都单独还原过,确认对应用例会转红。错误分类器的 7 个变异、扣费区分的 4 个变异,全部被抓到。其中「视频任务读回执失败是否算已扣费」这一条**最初变异存活了** —— 用例走的是 HTTP 失败分支,而变异改的是「响应体不是 JSON」那条路。补上那条路的用例之后,变异被抓住。这正是「测试通过了但证明的不是它声称的东西」的样子。
|
|
471
|
+
- 协议取证搬进 `docs/`(随包发布):H3 生成、账户接口、凭据、错误分类四篇,每条事实都带着测量日期。
|
|
472
|
+
|
|
473
|
+
### 0.6.9(2026-11-13)
|
|
474
|
+
|
|
475
|
+
- **最低支持的 DSH 版本从 `0.2.1-rc.2` 降到 `0.1.6-alpha.2`**。原来的下限是保守取值,不是技术上的。这一版把宿主各包的发布历史逐版本查了一遍,对每个插件用到的宿主能力,核出它最早出现在宿主包的哪个版本里。
|
|
476
|
+
- **宿主把它自己的包按与桌面端相同的版本号发布**(DSH `0.2.2-rc.1` 里带的就是 `0.2.2-rc.1` 的包),因此「某个 API 最早在哪一版」可以直接对着 npm 查 —— 本次兼容性表里的每一行,都是宿主包该版本号发布出来的源码里**实际出现过**这个 API。
|
|
477
|
+
- **真正的下限由两样东西决定**:插件页所在的 `plugins.bundle.config` 插槽,以及让提供者出现在模型选择器里的 `cordis.patch` 清单补丁 —— 两者都从 `0.1.6-alpha.2` 起才有。更早的宿主只有插件管理器自己的 `settings.plugin.item`(设置页里的一张卡片,keyed 插槽),不是插件页。
|
|
478
|
+
- **更早的宿主并非不能用,只是逐项减少**(README 有完整表格):`0.1.3-alpha.2` 起模型、积分胶囊、输入框里的生成入口、图片进对话都可用,只是没有插件页;`0.1.2-alpha.2` 起图片能发出并在对话里显示,只是没有草稿通道。宿主不认识的清单字段会被忽略(清单不是严格校验),所以老宿主不会因为 `cordis.patch` 拒绝安装插件 —— 只是它不生效。
|
|
479
|
+
- 宿主包的 peer 依赖下限同步降到 `>=0.1.6-alpha.2`,使老宿主自带的版本能满足区间。**锁文件也解析到 `0.1.6-alpha.2`** —— 于是每次发布的 CI 都会对着这个最老的宿主编译、构建并跑完全部用例,下限是被每次发布验证着的。
|
|
480
|
+
- README 新增「兼容性:最低支持哪个 DSH 版本」一节(中英文),含证据表与降级说明。
|
|
481
|
+
|
|
398
482
|
### 0.6.8(2026-11-13)
|
|
399
483
|
|
|
400
484
|
|
|
@@ -0,0 +1,118 @@
|
|
|
1
|
+
# The account endpoints
|
|
2
|
+
|
|
3
|
+
The upstream surfaces this plugin reads about the account, as measured on
|
|
4
|
+
**2026-11-12** (and re-measured on **2026-11-15** against a subscribed
|
|
5
|
+
account) in the **China** region.
|
|
6
|
+
|
|
7
|
+
## The membership answer
|
|
8
|
+
|
|
9
|
+
```
|
|
10
|
+
POST https://agent.minimax.cn/matrix/api/v1/commerce/get_membership_info
|
|
11
|
+
Authorization: Bearer <the desktop app's OAuth token>
|
|
12
|
+
Content-Type: application/json
|
|
13
|
+
Body: {}
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
The answer is the one place several facts arrive together:
|
|
17
|
+
|
|
18
|
+
| Field | Meaning |
|
|
19
|
+
| --- | --- |
|
|
20
|
+
| `op_credit_summary.total_remaining_amount` | the balance, free plus purchased |
|
|
21
|
+
| `op_credit_summary.purchased_remaining_amount` | the purchased part |
|
|
22
|
+
| `op_credit_summary.free_remaining_amount` | the granted part |
|
|
23
|
+
| `has_token_plan` | whether the account holds a plan |
|
|
24
|
+
| `token_plan_tier` | the plan's name, e.g. `Go` |
|
|
25
|
+
| `token_plan_expires_at` | when the plan ends, in milliseconds |
|
|
26
|
+
| `subscription_type` | `mplan` once a plan is held, `none` before |
|
|
27
|
+
| `opcredit_balance`, `total_remains_credit` | the older, flat view |
|
|
28
|
+
|
|
29
|
+
**The flat fields are a legacy view.** On an account that has migrated to the
|
|
30
|
+
credit pool they read zero even though credits remain, so the plugin uses
|
|
31
|
+
them only when the summary is absent altogether.
|
|
32
|
+
|
|
33
|
+
**A plan's tier is the upstream's own value.** `token_plan_tier` said `Go`
|
|
34
|
+
for the account measured here; another plan would say its own name. Only an
|
|
35
|
+
answer without that field falls back to a generic label.
|
|
36
|
+
|
|
37
|
+
## The plan's limit windows
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
GET https://api.minimax.cn/v1/token_plan/remains
|
|
41
|
+
Authorization: Bearer <the open-platform key>
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
**The field names and their meaning changed.** Before a plan was held the
|
|
45
|
+
answer carried `current_interval_used_percent` and
|
|
46
|
+
`current_weekly_used_percent` as strings (`"19%"`). With a plan it carries
|
|
47
|
+
`current_interval_remaining_percent` and `current_weekly_remaining_percent`
|
|
48
|
+
as plain numbers (`90`) — the *remaining* share, under a name that says so.
|
|
49
|
+
|
|
50
|
+
Both shapes are accepted, and what leaves the plugin is always the share
|
|
51
|
+
**used**: 92% remaining is 8% used. The window length is taken from the
|
|
52
|
+
answer's own edges rather than from the plan's terms, because the terms have
|
|
53
|
+
changed before: the measured answer is a five-hour window and a 168-hour one.
|
|
54
|
+
|
|
55
|
+
A window the upstream marks as unlimited (`current_*_status` of 3) carries no
|
|
56
|
+
allowance to be a percentage of, so it produces no window at all.
|
|
57
|
+
|
|
58
|
+
**An account without a plan gets `2062 no active token plan subscription`**
|
|
59
|
+
rather than an answer. That is the difference between "no windows" and "the
|
|
60
|
+
read failed", and the plugin tells them apart.
|
|
61
|
+
|
|
62
|
+
## The credit ledger
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
GET https://agent.minimax.cn/minimax-cloud/api/v1/credit/details?page_number=1&page_size=20
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
The answer's `details[]` carry `expire_at_ms` and the remaining amount. The
|
|
69
|
+
upstream's lots expire **day by day, spread over thirty-odd days**, so the
|
|
70
|
+
plugin's "expiring soon" window is a display choice, not something the
|
|
71
|
+
upstream states.
|
|
72
|
+
|
|
73
|
+
The credit-package summary lives at:
|
|
74
|
+
|
|
75
|
+
```
|
|
76
|
+
GET https://www.minimaxi.com/backend/account/token_plan_credit?business=Agent&device_platform=desktop
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
whose answer carries `total_credits`, `used_credits`, `remaining_credits`,
|
|
80
|
+
`credit_packages_details[]` and the `balance_breakdown` buckets.
|
|
81
|
+
|
|
82
|
+
## The usage profile
|
|
83
|
+
|
|
84
|
+
```
|
|
85
|
+
GET https://www.minimaxi.com/backend/account/token_plan/usage_summary?token_type=5&heatmap_days=365&business=Agent&device_platform=desktop
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
The answer carries `total_days`, `total_token_consumed`, `usage_ranking_percent`,
|
|
89
|
+
`most_active_day`, `active_days`, `current_consecutive_days`, and per-day
|
|
90
|
+
`date_model_usage[]` with a per-model breakdown (including
|
|
91
|
+
`cache_hit_percent`).
|
|
92
|
+
|
|
93
|
+
## What the catalog does not carry
|
|
94
|
+
|
|
95
|
+
**No promotion-shaped fields.** A search of the whole catalog answer for
|
|
96
|
+
`modelPromotions`, `promotions`, `activities`, `discount` and `free_trial`
|
|
97
|
+
found nothing. The plugin therefore draws no activity badge: a badge would
|
|
98
|
+
have to be invented, and an invented badge is worse than no badge.
|
|
99
|
+
|
|
100
|
+
**No price fields.** The model catalog carries the models and their limits,
|
|
101
|
+
but nothing about what a request costs, so the plugin cannot say what a
|
|
102
|
+
title request or a long turn spent.
|
|
103
|
+
|
|
104
|
+
## The model catalog
|
|
105
|
+
|
|
106
|
+
```
|
|
107
|
+
GET https://agent.minimax.cn/mavis/api/v1/models
|
|
108
|
+
Authorization: Bearer <the desktop app's OAuth token>
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
The answer carries `providers[].config.models`, each with `name`,
|
|
112
|
+
`attachment`, `reasoning`, `limit.context`, `limit.output` and `modalities`.
|
|
113
|
+
|
|
114
|
+
At the time of measurement the catalog carried **two** models,
|
|
115
|
+
`MiniMax-M3` and `MiniMax-M3.1-Flash`, both with a 512,000-token context and
|
|
116
|
+
a 128,000-token output limit. There was **no lighter model** in it — which
|
|
117
|
+
is why the plugin does not divert the host's session-title requests
|
|
118
|
+
elsewhere; see the changelog for that entry.
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# The credentials, and where they come from
|
|
2
|
+
|
|
3
|
+
The plugin can be signed in two ways, and they arrive by different paths.
|
|
4
|
+
Which one is in use is what the card reports as its sign-in source.
|
|
5
|
+
|
|
6
|
+
## The desktop app's login (the usual one)
|
|
7
|
+
|
|
8
|
+
The MiniMax Code desktop app leaves its login state in a file. The plugin
|
|
9
|
+
reads it and never writes it.
|
|
10
|
+
|
|
11
|
+
The file's location is probed per platform, and the card lists every path it
|
|
12
|
+
tried and why each one did not work — five distinct reasons, so that the
|
|
13
|
+
commonest misdiagnosis ("the app is not signed in") is not mistaken for
|
|
14
|
+
"the file is somewhere else".
|
|
15
|
+
|
|
16
|
+
The desktop app's token is what the **model gateway** takes:
|
|
17
|
+
|
|
18
|
+
```
|
|
19
|
+
POST https://agent.minimax.cn/mavis/api/v1/llm/v1/messages
|
|
20
|
+
Authorization: Bearer <the desktop app's OAuth token>
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
It is also what the **account endpoints** take — membership, the credit
|
|
24
|
+
ledger, the usage profile, and the credit-package summary that hands out the
|
|
25
|
+
open-platform key.
|
|
26
|
+
|
|
27
|
+
## The plugin's own login (the fallback)
|
|
28
|
+
|
|
29
|
+
With no desktop app on the machine, the plugin starts an OAuth device flow
|
|
30
|
+
from the card and keeps its own token under the Harness home. The person
|
|
31
|
+
confirms it in a browser.
|
|
32
|
+
|
|
33
|
+
That token serves the model gateway and the account endpoints too. The
|
|
34
|
+
**generation** endpoints do not take it — they take the open-platform key,
|
|
35
|
+
which the credit-package summary hands out.
|
|
36
|
+
|
|
37
|
+
## The open-platform key
|
|
38
|
+
|
|
39
|
+
```
|
|
40
|
+
GET https://www.minimaxi.com/backend/account/token_plan_credit?business=Agent&device_platform=desktop
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
The answer carries `api_key`, a `sk-cp-…` value. The plugin keeps it for as
|
|
44
|
+
long as it runs and never writes it to disk.
|
|
45
|
+
|
|
46
|
+
Passing the OAuth token to the generation endpoints instead is refused with
|
|
47
|
+
`1004 login fail: Please carry the API secret key`.
|
|
48
|
+
|
|
49
|
+
## The two paths that failed before
|
|
50
|
+
|
|
51
|
+
Both of these were real, and both are why the plugin reads the account
|
|
52
|
+
endpoints at all:
|
|
53
|
+
|
|
54
|
+
- **The model gateway read only the legacy JWT.** It now falls back to the
|
|
55
|
+
desktop app's OAuth credential, and a re-login takes effect without
|
|
56
|
+
restarting the host.
|
|
57
|
+
- **The credit endpoint was answered with an empty body.** The plugin now
|
|
58
|
+
reads the documented endpoints, and the answer's own summary.
|
|
59
|
+
|
|
60
|
+
## What the plugin never does
|
|
61
|
+
|
|
62
|
+
- It never writes to the desktop app's files.
|
|
63
|
+
- It never prints a token. The plugin's own state file holds the OAuth
|
|
64
|
+
credential; the open-platform key is held in memory only.
|
|
65
|
+
- It does not start a login of its own unless the card is pressed.
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
# How a failure is classified
|
|
2
|
+
|
|
3
|
+
The plugin turns an upstream refusal into three things a person can act on:
|
|
4
|
+
**what kind of failure it is**, **whether it may already have been charged
|
|
5
|
+
for**, and **the upstream's own words**.
|
|
6
|
+
|
|
7
|
+
## Why the classification is by shape
|
|
8
|
+
|
|
9
|
+
The upstream's failures arrive in several shapes: an HTTP status, a business
|
|
10
|
+
code, a sentence, sometimes all three. The obvious thing to key on is the
|
|
11
|
+
code — `2013` means a bad parameter, `2062` means no plan.
|
|
12
|
+
|
|
13
|
+
**The plugin does not.** It keys on the *shape* of the failure: the HTTP
|
|
14
|
+
status and the wording.
|
|
15
|
+
|
|
16
|
+
The reason is that a code is a number **some other system chose**. It may be
|
|
17
|
+
renamed, or withdrawn, or reused for something else, and a classifier that
|
|
18
|
+
keyed on it would one day quietly stop matching — the plugin would report
|
|
19
|
+
"something went wrong" for a failure it used to recognise, with no sign
|
|
20
|
+
that anything had changed. A classifier that keyed on the *kind* of failure
|
|
21
|
+
keeps working across renames, and only has to be extended when a genuinely
|
|
22
|
+
new kind appears.
|
|
23
|
+
|
|
24
|
+
This is the same rule the plugin follows elsewhere: a fact that travels with
|
|
25
|
+
the **data** may be relied on; a fact that travels with another system's
|
|
26
|
+
**code** may not.
|
|
27
|
+
|
|
28
|
+
## The kinds
|
|
29
|
+
|
|
30
|
+
| Kind | Recognised by | The remedy |
|
|
31
|
+
| --- | --- | --- |
|
|
32
|
+
| `credentials` | HTTP 401 / 403, or wording about a refused key or a failed sign-in | sign in again |
|
|
33
|
+
| `parameters` | HTTP 400 / 422, or wording about an invalid or unsupported value | change the request |
|
|
34
|
+
| `subscription` | wording about no active plan or subscription | check the plan |
|
|
35
|
+
| `quota` | wording about an insufficient balance or a spent quota | wait, or check the windows |
|
|
36
|
+
| `rate-limited` | HTTP 429, or wording about too many requests | wait |
|
|
37
|
+
| `upstream` | anything else | show the upstream's words and ask for a report |
|
|
38
|
+
| `local` | the request never left the plugin | fix it and try again |
|
|
39
|
+
|
|
40
|
+
**A failure that is not recognised is not guessed at.** It becomes
|
|
41
|
+
`upstream`, whose remedy is to show the upstream's own words — which is what
|
|
42
|
+
a report needs, and better than a confident wrong answer.
|
|
43
|
+
|
|
44
|
+
**The wording is checked before the status**, except for the two statuses
|
|
45
|
+
that name a class outright (401/403 and 429). The reason is that a bad
|
|
46
|
+
request can arrive for a reason that is not a bad request: the "no active
|
|
47
|
+
subscription" refusal arrives as HTTP 400, and telling the reader to change
|
|
48
|
+
the parameters would send them looking in the wrong place.
|
|
49
|
+
|
|
50
|
+
## What it cost
|
|
51
|
+
|
|
52
|
+
A failure that happened **before** the upstream accepted the work spent
|
|
53
|
+
nothing: a bad parameter, a refused credential, a request the plugin
|
|
54
|
+
refused to send. A retry after fixing something is free, and the plugin says
|
|
55
|
+
so.
|
|
56
|
+
|
|
57
|
+
A failure that happened **after** the upstream accepted the work — a video
|
|
58
|
+
task that was submitted and then could not be read back — may already have
|
|
59
|
+
been charged for. The plugin says so too, and holds off for a while.
|
|
60
|
+
|
|
61
|
+
## What the reader sees
|
|
62
|
+
|
|
63
|
+
Three lines, in this order:
|
|
64
|
+
|
|
65
|
+
1. **the remedy**, in the host's language;
|
|
66
|
+
2. **a warning when the work may have been charged for**;
|
|
67
|
+
3. **the upstream's own words**, collapsed — they are read when a report is
|
|
68
|
+
being written, not when the failure happens.
|
|
69
|
+
|
|
70
|
+
The upstream's words are shown **as they arrived**. A paraphrase would be a
|
|
71
|
+
guess about what the upstream meant, and the guess would be the thing a
|
|
72
|
+
reader would quote back.
|
|
@@ -0,0 +1,109 @@
|
|
|
1
|
+
# H3 image and video generation
|
|
2
|
+
|
|
3
|
+
The upstream endpoints this plugin calls to make a picture or a video with
|
|
4
|
+
H3, as measured on **2026-11-12** against the account this plugin was
|
|
5
|
+
developed with, in the **China** region.
|
|
6
|
+
|
|
7
|
+
Everything here was observed, not read from documentation — the endpoints are
|
|
8
|
+
not documented publicly. Where a measurement could be repeated, it was.
|
|
9
|
+
|
|
10
|
+
## Credentials
|
|
11
|
+
|
|
12
|
+
The generation endpoints do **not** take the OAuth bearer the model gateway
|
|
13
|
+
takes. They take the **open-platform key**, which the account's own credit
|
|
14
|
+
endpoint hands out:
|
|
15
|
+
|
|
16
|
+
```
|
|
17
|
+
GET https://www.minimaxi.com/backend/account/token_plan_credit?business=Agent&device_platform=desktop
|
|
18
|
+
Authorization: Bearer <the desktop app's OAuth token>
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
The answer carries `api_key` — a `sk-cp-…` value — and the plugin keeps it
|
|
22
|
+
for as long as it runs. Passing the OAuth token instead is refused with
|
|
23
|
+
`1004 login fail: Please carry the API secret key`, which arrives with
|
|
24
|
+
HTTP 200 and a code in the body.
|
|
25
|
+
|
|
26
|
+
## Images
|
|
27
|
+
|
|
28
|
+
```
|
|
29
|
+
POST https://api.minimax.cn/v1/images/generations
|
|
30
|
+
Authorization: Bearer <the open-platform key>
|
|
31
|
+
Content-Type: application/json
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The request carries `model`, `prompt`, `response_format`, and optionally
|
|
35
|
+
`n`, `aspect_ratio` and `area`.
|
|
36
|
+
|
|
37
|
+
| Model | Note |
|
|
38
|
+
| --- | --- |
|
|
39
|
+
| `MiniMax-H3-Image` | the default |
|
|
40
|
+
| `MiniMax-H3-Image-Highspeed` | the faster one |
|
|
41
|
+
|
|
42
|
+
The answer carries `data[]` with either a `url` (valid for **24 hours**) or
|
|
43
|
+
`b64_json`. It also carries `usage.generated_images`, `usage.total_tokens`
|
|
44
|
+
and a `request_id`.
|
|
45
|
+
|
|
46
|
+
The plugin downloads the bytes while the link is still fresh, because a
|
|
47
|
+
plugin that kept only the link would leave the picture behind.
|
|
48
|
+
|
|
49
|
+
## Videos
|
|
50
|
+
|
|
51
|
+
```
|
|
52
|
+
POST https://api.minimax.cn/v2/video_generation
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The request carries `model` and a `content[]` array whose entries are
|
|
56
|
+
`{type: 'text'}`, `{type: 'image_url', image_url: {url}, role: 'first_frame' | 'last_frame'}`.
|
|
57
|
+
`duration` is 4–15, `resolution` is `768P` or `2K`, and `ratio` runs from
|
|
58
|
+
`21:9` to `9:16`.
|
|
59
|
+
|
|
60
|
+
The answer carries a `task_id`; the state is read from:
|
|
61
|
+
|
|
62
|
+
```
|
|
63
|
+
GET https://api.minimax.cn/v2/query/video_generation/{task_id}
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
whose answer carries `task.status` (`running`, `succeeded`, and the failure
|
|
67
|
+
spellings), `task.content.url`, `task.resolution`, `task.duration`,
|
|
68
|
+
`task.ratio` and `task.usage.total_seconds`.
|
|
69
|
+
|
|
70
|
+
The v1 path answers "该模型请使用 /v2/video_generation 接口" — the model moved
|
|
71
|
+
to v2, and the old path says so.
|
|
72
|
+
|
|
73
|
+
## What a refusal looks like
|
|
74
|
+
|
|
75
|
+
**A refusal can arrive with HTTP 200.** The body carries `base_resp` with a
|
|
76
|
+
`status_code` that is not zero. Reading only the HTTP status would call
|
|
77
|
+
these a success.
|
|
78
|
+
|
|
79
|
+
| Code | Meaning, as observed |
|
|
80
|
+
| --- | --- |
|
|
81
|
+
| `1004` | the credential was refused (`login fail`) |
|
|
82
|
+
| `2013` | a parameter was refused; the message names the field |
|
|
83
|
+
| `2062` | `no active token plan subscription` — the account has no plan |
|
|
84
|
+
|
|
85
|
+
The plugin classifies these by shape, not by number: see
|
|
86
|
+
[ERROR-TAXONOMY.md](ERROR-TAXONOMY.md).
|
|
87
|
+
|
|
88
|
+
## What was charged
|
|
89
|
+
|
|
90
|
+
The plugin distinguishes two failures, because the difference decides whether
|
|
91
|
+
a retry is sensible:
|
|
92
|
+
|
|
93
|
+
- a failure **before** the upstream accepted the work (a bad parameter, a
|
|
94
|
+
refused credential, a request the plugin refused to send) spent nothing
|
|
95
|
+
and may be retried at once;
|
|
96
|
+
- a failure **after** the upstream accepted it — a video task that was
|
|
97
|
+
submitted and then could not be read back — may already have been charged
|
|
98
|
+
for, and a retry is another task and another charge.
|
|
99
|
+
|
|
100
|
+
The plugin says which of the two happened, in the same place it shows the
|
|
101
|
+
upstream's own words.
|
|
102
|
+
|
|
103
|
+
## Not measured
|
|
104
|
+
|
|
105
|
+
- Whether the 24-hour link can be refreshed rather than re-generated.
|
|
106
|
+
- What a partially completed video task costs.
|
|
107
|
+
- The international region's endpoints on this protocol: the same paths are
|
|
108
|
+
used against `api.minimaxi.com`, but nothing here was measured against
|
|
109
|
+
that region.
|
package/docs/README.md
ADDED
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The upstream protocols this plugin speaks, as they were measured.
|
|
3
|
+
*
|
|
4
|
+
* Each file records one upstream surface: the endpoints, the shape of what
|
|
5
|
+
* comes back, and — most importantly — what was actually observed, with the
|
|
6
|
+
* date it was observed. The upstream is not under this project's control and
|
|
7
|
+
* may change, so a reader needs to know how old a measurement is before
|
|
8
|
+
* trusting it.
|
|
9
|
+
*
|
|
10
|
+
* Nothing here is read at runtime. These are notes for whoever works on the
|
|
11
|
+
* plugin next, and for whoever reads a bug report about a field they do not
|
|
12
|
+
* recognise.
|
|
13
|
+
*/
|
|
14
|
+
|
|
15
|
+
# Upstream protocols
|
|
16
|
+
|
|
17
|
+
| Document | What it covers |
|
|
18
|
+
| --- | --- |
|
|
19
|
+
| [H3-GENERATION.md](H3-GENERATION.md) | The H3 image and video endpoints: requests, answers, the accounting, and what a refusal looks like. |
|
|
20
|
+
| [ACCOUNT-ENDPOINTS.md](ACCOUNT-ENDPOINTS.md) | The account endpoints: the membership answer, the credit ledger, the plan's limit windows, and the usage profile. |
|
|
21
|
+
| [CREDENTIALS.md](CREDENTIALS.md) | Where the login state comes from, and the two paths it can arrive by. |
|
|
22
|
+
| [ERROR-TAXONOMY.md](ERROR-TAXONOMY.md) | How a failure is classified, and why the classification is by shape rather than by code. |
|
|
23
|
+
|
|
24
|
+
## How a measurement is recorded
|
|
25
|
+
|
|
26
|
+
Every fact here carries the date it was measured and the endpoint it came
|
|
27
|
+
from. Two reasons:
|
|
28
|
+
|
|
29
|
+
- the upstream answers differently over time — the plan's window fields were
|
|
30
|
+
renamed and their meaning inverted between one release and the next, and a
|
|
31
|
+
note without a date would have said the wrong thing for months;
|
|
32
|
+
- a reader who wants to reproduce a measurement needs to know which build and
|
|
33
|
+
which account it came from, because an account without a plan gets a
|
|
34
|
+
different answer than one with it.
|
|
35
|
+
|
|
36
|
+
A measurement that has not been repeated in a long time is treated as a
|
|
37
|
+
hypothesis, not as a fact. The ones below were measured against the account
|
|
38
|
+
this plugin was developed with, in the region named in each document.
|