opencode-lobster-auth 0.1.0 → 0.1.2
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.md +181 -170
- package/README.zh-CN.md +156 -147
- package/index.mjs +210 -191
- package/lib/auth-login.mjs +154 -131
- package/lib/constants.mjs +41 -41
- package/lib/jwt.mjs +34 -34
- package/lib/sse.mjs +67 -67
- package/lib/usage.mjs +41 -41
- package/package.json +22 -9
package/README.zh-CN.md
CHANGED
|
@@ -1,147 +1,156 @@
|
|
|
1
|
-
# opencode-lobster-auth
|
|
2
|
-
|
|
3
|
-
为 [magpie](https://usemagpie.ai) 提供 provider `lobster`:登录
|
|
4
|
-
[LobsterAI](https://lobsterai.youdao.com)(有道龙虾,网易有道的桌面 agent)
|
|
5
|
-
账号,把它名下的模型接进来。约 30 个模型,含 DeepSeek、GLM、Kimi、Qwen、
|
|
6
|
-
MiniMax、豆包。
|
|
7
|
-
|
|
8
|
-
[English](README.md) · **中文**
|
|
9
|
-
|
|
10
|
-
## 安装
|
|
11
|
-
|
|
12
|
-
这是一个文件夹插件,没有发布到 npm:
|
|
13
|
-
|
|
14
|
-
```sh
|
|
15
|
-
magpie plugin add /path/to/magpie-lobster
|
|
16
|
-
magpie plugin login lobster
|
|
17
|
-
```
|
|
18
|
-
|
|
19
|
-
## 登录
|
|
20
|
-
|
|
21
|
-
两种方式,任选其一。两者都用有道账号标识(`yid`)给账号命名,所以对一个
|
|
22
|
-
已经用第一种方式登录过的账号再用第二种登录,是原地替换。
|
|
23
|
-
|
|
24
|
-
- **浏览器登录(有道账号)。** 插件在本机 `127.0.0.1` 起一个回调服务,
|
|
25
|
-
magpie 打开有道登录页。浏览器带着授权码跳回来,插件拿它在
|
|
26
|
-
`/api/auth/exchange` 换取 token。存成一个 `oauth` 账号,带 access 与
|
|
27
|
-
refresh token 及到期时间,因此 magpie 会为它续期。
|
|
28
|
-
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
`
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
`
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
##
|
|
146
|
-
|
|
147
|
-
|
|
1
|
+
# opencode-lobster-auth
|
|
2
|
+
|
|
3
|
+
为 [magpie](https://usemagpie.ai) 提供 provider `lobster`:登录
|
|
4
|
+
[LobsterAI](https://lobsterai.youdao.com)(有道龙虾,网易有道的桌面 agent)
|
|
5
|
+
账号,把它名下的模型接进来。约 30 个模型,含 DeepSeek、GLM、Kimi、Qwen、
|
|
6
|
+
MiniMax、豆包。
|
|
7
|
+
|
|
8
|
+
[English](README.md) · **中文**
|
|
9
|
+
|
|
10
|
+
## 安装
|
|
11
|
+
|
|
12
|
+
这是一个文件夹插件,没有发布到 npm:
|
|
13
|
+
|
|
14
|
+
```sh
|
|
15
|
+
magpie plugin add /path/to/magpie-lobster
|
|
16
|
+
magpie plugin login lobster
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## 登录
|
|
20
|
+
|
|
21
|
+
两种方式,任选其一。两者都用有道账号标识(`yid`)给账号命名,所以对一个
|
|
22
|
+
已经用第一种方式登录过的账号再用第二种登录,是原地替换。
|
|
23
|
+
|
|
24
|
+
- **浏览器登录(有道账号)。** 插件在本机 `127.0.0.1` 起一个回调服务,
|
|
25
|
+
magpie 打开有道登录页。浏览器带着授权码跳回来,插件拿它在
|
|
26
|
+
`/api/auth/exchange` 换取 token。存成一个 `oauth` 账号,带 access 与
|
|
27
|
+
refresh token 及到期时间,因此 magpie 会为它续期。
|
|
28
|
+
- **远程浏览器登录。** 给 magpie 跑在服务器上、Docker 里,或者浏览器在另一台
|
|
29
|
+
机器上的情况:回调落在浏览器自己的 `127.0.0.1`,到不了 magpie。登录页的普通
|
|
30
|
+
query 里写明了回调端口,因此 magpie 会给出「回调 URL」输入框:登录后复制浏览器
|
|
31
|
+
停在的那个完整地址,粘贴进去,magpie 会在本机把它送到插件监听的端口。其余与
|
|
32
|
+
浏览器登录完全一样。
|
|
33
|
+
- **从桌面端导入。** 使用 LobsterAI 桌面端当前登录的账号。**不打开任何页面,
|
|
34
|
+
不需要输入任何东西。** 只读桌面端的 SQLite 库,绝不写入:
|
|
35
|
+
- Windows:`%APPDATA%\LobsterAI\lobsterai.sqlite`
|
|
36
|
+
- macOS:`~/Library/Application Support/LobsterAI/lobsterai.sqlite`
|
|
37
|
+
- Linux:`~/.config/LobsterAI/lobsterai.sqlite`
|
|
38
|
+
|
|
39
|
+
库不存在,或者被桌面端加密存放,这条路会带着说明失败,改用浏览器登录即可。
|
|
40
|
+
|
|
41
|
+
两种方式都保存在 magpie 的 `plugin-auth.json`。
|
|
42
|
+
|
|
43
|
+
### 为什么导入这条路不保存 token
|
|
44
|
+
|
|
45
|
+
导入方式**一个字节的凭据都不存**(`access` 和 `refresh` 都是空串,`expires`
|
|
46
|
+
为 0),只在每次请求时现读桌面端的库:
|
|
47
|
+
|
|
48
|
+
- 抄一份 `refreshToken` 会与桌面端共用同一个凭据:**谁先续期谁就把对方踢
|
|
49
|
+
下线**。留空则双方互不干扰。
|
|
50
|
+
- `expires` 为 0,magpie 因此永不续期(它只对设了到期时间的 `oauth` 账号做
|
|
51
|
+
续期),桌面端的会话不会被搅动。
|
|
52
|
+
- 现读意味着桌面端续期之后,插件下一次请求自动用上新 token,不必重新登录。
|
|
53
|
+
|
|
54
|
+
代价是:桌面端退出登录、卸载,或者库变得不可读,这个账号会**立刻**失效,
|
|
55
|
+
并被标记为需要重新登录。这比用一个已经悄悄失效的旧 token 更诚实。
|
|
56
|
+
|
|
57
|
+
### 续期
|
|
58
|
+
|
|
59
|
+
浏览器登录的账号由 magpie 通过插件的 `auth.refresh` 在到期前 6 小时续期。
|
|
60
|
+
导入的账号如上一节所述,结构性不会被续期。
|
|
61
|
+
|
|
62
|
+
插件从不调用 LobsterAI 自己的续期接口去验证或刷新任何东西:
|
|
63
|
+
`/api/auth/refresh` 可能消耗账号真实的 refresh token,因此刻意不碰它。
|
|
64
|
+
|
|
65
|
+
## 请求
|
|
66
|
+
|
|
67
|
+
对话走 `https://lobsterai-server.youdao.com/api/proxy/v1` 的 chat
|
|
68
|
+
completions。LobsterAI 有三个习惯被处理掉了:
|
|
69
|
+
|
|
70
|
+
- **所有回复都是 SSE**,即使请求里写了 `stream: false`。非流式调用方会拿到
|
|
71
|
+
由它重组出的一个完整 `chat.completion`;流式调用方拿到的就是原样的事件。
|
|
72
|
+
- **错误藏在 200 里。** LobsterAI 把错误放进流里(`event: error`),状态码
|
|
73
|
+
仍是 200 —— 这样调用方没有可故障切换的依据。插件读首条记录,还原成它真正
|
|
74
|
+
表示的状态:`40100` → 401,`40300` → 403,`42900` 或限流措辞 → 429,其余
|
|
75
|
+
→ 400。被 LobsterAI 拒绝的登录是真 401,原样透传并带上 magpie 的失效标记,
|
|
76
|
+
账号因此会被标出来。
|
|
77
|
+
- **请求带上桌面端的标识头**(`X-LobsterAI-Client-Version`、
|
|
78
|
+
`X-LobsterAI-Client-Capabilities`)。LobsterAI 不强制要求,但它们标明了
|
|
79
|
+
插件所说的特性集。
|
|
80
|
+
|
|
81
|
+
### 思考档位
|
|
82
|
+
|
|
83
|
+
模型的 `thinkingConfig` 决定它有哪些档位 —— 当前目录里是 `off`、`high`、
|
|
84
|
+
`max` —— 它们通过 LobsterAI 自己的字段上线:
|
|
85
|
+
`{"lobsterai_options":{"version":1,"thinking":{"level":"off"}}}`。
|
|
86
|
+
|
|
87
|
+
有两件事值得知道:
|
|
88
|
+
|
|
89
|
+
- **`lobsterai_options` 只发给自带档位表的模型。** 29 个模型里有 21 个没有
|
|
90
|
+
档位表,给这些模型带上该字段是硬错误(`code 4000`,*model does not have a
|
|
91
|
+
valid thinkingConfig*),整轮对话直接失败。只有在有档位表可映射时,档位才会
|
|
92
|
+
被传下去。
|
|
93
|
+
- **最低档对外叫 `none`,不叫 `off`。** magpie 不使用 variant 里存的东西,它
|
|
94
|
+
按自己的一条阶梯(`none/minimal/low/medium/high/xhigh/max`)把
|
|
95
|
+
`reasoning_effort` 映射到「模型声明过的那个档位名」。`off` 不在那条阶梯上,
|
|
96
|
+
所以声明成 `off` 的那一档永远选不中。插件对外声明 `none`,写给 LobsterAI
|
|
97
|
+
时再换回 `off`。
|
|
98
|
+
|
|
99
|
+
在 `deepseek-flash` 上实测:`none` 会让 `reasoning_content` 恰好为 0 字节,
|
|
100
|
+
而 `high`、`max` 和不指定档位都不会。
|
|
101
|
+
|
|
102
|
+
### Kimi K3
|
|
103
|
+
|
|
104
|
+
LobsterAI 的 `kimi-k3` 采样参数由服务端固定,因此 `temperature`、`top_p`、
|
|
105
|
+
`n` 和两个 penalty 会被删掉,`reasoning_effort` 固定为 `max`,缺少
|
|
106
|
+
`reasoning_content` 的 assistant 工具调用会被补一个空串。
|
|
107
|
+
|
|
108
|
+
`kimi-k3` 属于 LobsterAI「能用但没列出」的模型:`/api/models/available`
|
|
109
|
+
返回 29 个模型,其中没有 K3,但对 `kimi-k3` 发请求能正常作答。它保留在
|
|
110
|
+
本插件为未登录账号声明的兜底表里,所以 `lobster/kimi-k3` 是可选的 ——
|
|
111
|
+
上面那段处理也因此是**实际生效的**,不是预防性代码。
|
|
112
|
+
|
|
113
|
+
## 模型
|
|
114
|
+
|
|
115
|
+
登录后,列表来自账号自己(`/api/models/available`):29 个模型,各带上下文
|
|
116
|
+
窗口、是否收图片、以及它的思考档位。登录之前用一份 5 个模型的静态列表兜底,
|
|
117
|
+
这样 provider 在登录前就可见。
|
|
118
|
+
|
|
119
|
+
`costMultiplier` 成为 magpie 的 `rate`。它是**分时计价**:`deepseek-flash`
|
|
120
|
+
在 LobsterAI 的空闲时段是 0.05,高峰时段是 0.1(高峰为北京时间
|
|
121
|
+
09:00–12:00 与 14:00–18:00)。倍率是在拉列表时读的,所以可能有一阵子是过时
|
|
122
|
+
的。
|
|
123
|
+
|
|
124
|
+
## 用量
|
|
125
|
+
|
|
126
|
+
`magpie quota` 显示免费额度、它的到期时间和剩余点数,数据来自
|
|
127
|
+
`/api/user/quota` 与 `/api/user/profile-summary`。插件上报的是 `kept`:它自己
|
|
128
|
+
不续期,因此不该声称做过一次它没做的续期。
|
|
129
|
+
|
|
130
|
+
## 不做的事
|
|
131
|
+
|
|
132
|
+
- **企业账号。** LobsterAI 让它们走另一个页面(`EnterpriseIdentitySelect`)。
|
|
133
|
+
目前只处理个人账号。
|
|
134
|
+
- **经过验证的 `/api/auth/refresh`。** 调用它可能消耗账号真实的 refresh
|
|
135
|
+
token,因此没有实测。续期这条路是照着桌面端自己的代码写的,没有与服务端
|
|
136
|
+
核对过。
|
|
137
|
+
- **精确的输出上限。** 目录里没有这个字段。插件声明了保守的 32,000;实测
|
|
138
|
+
LobsterAI 接受 262,144,在 524,288 时返回 500,所以真实上限在两者之间。
|
|
139
|
+
- **OpenCode。** 这个插件是按 OpenCode 的 provider 插件格式写的 —— magpie
|
|
140
|
+
加载的正是这个格式 —— 但只在 magpie 上实测过。`auth.refresh`、
|
|
141
|
+
`auth.refreshLead` 以及 `package.json` 里的 `magpie` 字段是 magpie 自己的,
|
|
142
|
+
OpenCode 会忽略它们。
|
|
143
|
+
- **同时使用多个账号。** magpie 每个 provider 只保留一份登录。
|
|
144
|
+
|
|
145
|
+
## 开发
|
|
146
|
+
|
|
147
|
+
```sh
|
|
148
|
+
bun test
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
入口只负责装配钩子。逻辑都在 `lib/` 下,是普通函数,通过 `_internal` 暴露
|
|
152
|
+
出来 —— 因为 magpie 和 OpenCode 都会把每一个导出的函数当成一个独立插件。
|
|
153
|
+
|
|
154
|
+
## 许可
|
|
155
|
+
|
|
156
|
+
MIT
|