sidekick-chat 0.2.9 → 0.2.10
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 +2 -0
- package/package.json +1 -1
- package/src/api.mjs +27 -4
- package/src/main.mjs +12 -1
package/README.md
CHANGED
package/package.json
CHANGED
package/src/api.mjs
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* `cortico_session` Cookie(和网页版同一个 `CORTICO_WEB_PASSWORD`)。接口本身见
|
|
6
6
|
* packages/world-chat/src/world.ts 的 `startHub`。
|
|
7
7
|
*/
|
|
8
|
+
import { randomUUID } from 'node:crypto';
|
|
8
9
|
import { authOrigin } from './config.mjs';
|
|
9
10
|
|
|
10
11
|
/** 鉴权没过:登录态失效或令牌不对,调用方据此提示重新登录。 */
|
|
@@ -13,6 +14,10 @@ export class AuthError extends Error {}
|
|
|
13
14
|
/** 连不上(没拿到响应):只有这种错才换备用线路,4xx / 5xx 不换。 */
|
|
14
15
|
export class NetworkError extends Error {}
|
|
15
16
|
|
|
17
|
+
class HttpError extends Error {
|
|
18
|
+
constructor(status, message) { super(message); this.status = status; }
|
|
19
|
+
}
|
|
20
|
+
|
|
16
21
|
const REQUEST_TIMEOUT_MS = 20_000;
|
|
17
22
|
|
|
18
23
|
export class SidekickApi {
|
|
@@ -76,9 +81,15 @@ export class SidekickApi {
|
|
|
76
81
|
if (signal?.aborted) throw signal.reason;
|
|
77
82
|
throw new NetworkError(networkHint(url, err));
|
|
78
83
|
}
|
|
79
|
-
|
|
84
|
+
let data;
|
|
85
|
+
try { data = await res.json(); }
|
|
86
|
+
catch (err) {
|
|
87
|
+
if (signal?.aborted) throw signal.reason;
|
|
88
|
+
if (!res.ok) data = {};
|
|
89
|
+
else throw new NetworkError(networkHint(url, err));
|
|
90
|
+
}
|
|
80
91
|
if (res.status === 401) throw new AuthError(data.error || '登录态已失效');
|
|
81
|
-
if (!res.ok) throw new
|
|
92
|
+
if (!res.ok) throw new HttpError(res.status, data.error || `HTTP ${res.status}`);
|
|
82
93
|
return data;
|
|
83
94
|
});
|
|
84
95
|
}
|
|
@@ -92,8 +103,20 @@ export class SidekickApi {
|
|
|
92
103
|
return this.request('GET', `v1/team/history?conv=${encodeURIComponent(conv)}&limit=${limit}`);
|
|
93
104
|
}
|
|
94
105
|
|
|
95
|
-
send({ conv, text, device, images }) {
|
|
96
|
-
|
|
106
|
+
async send({ conv, text, device, images }, { signal, onRetry } = {}) {
|
|
107
|
+
const body = { conv, text, device, images, client_id: randomUUID() };
|
|
108
|
+
let delay = 1000;
|
|
109
|
+
for (;;) {
|
|
110
|
+
signal?.throwIfAborted();
|
|
111
|
+
try { return await this.request('POST', 'v1/team/send', body, { signal }); }
|
|
112
|
+
catch (err) {
|
|
113
|
+
if (!(err instanceof NetworkError) && !(err instanceof HttpError && [408, 502, 503, 504].includes(err.status))) throw err;
|
|
114
|
+
onRetry?.(err);
|
|
115
|
+
signal?.throwIfAborted();
|
|
116
|
+
await sleep(delay, signal);
|
|
117
|
+
delay = Math.min(delay * 2, 10000);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
97
120
|
}
|
|
98
121
|
|
|
99
122
|
read(conv, seq) {
|
package/src/main.mjs
CHANGED
|
@@ -553,7 +553,17 @@ async function startChat(flags) {
|
|
|
553
553
|
|
|
554
554
|
async function sendText(text) {
|
|
555
555
|
const images = pendingImages.slice();
|
|
556
|
-
|
|
556
|
+
let warned = false;
|
|
557
|
+
const res = await api.send({ conv: convId, text, device: settings.device, ...(images.length ? { images } : {}) }, {
|
|
558
|
+
signal: ctl.signal,
|
|
559
|
+
onRetry: () => {
|
|
560
|
+
if (!warned) out('消息尚未确认送达,已保留并自动重试,请勿重复发送(退出客户端会停止重试)。');
|
|
561
|
+
warned = true;
|
|
562
|
+
},
|
|
563
|
+
}).catch((err) => {
|
|
564
|
+
if (!closed) out(`未发送的消息:${text}`);
|
|
565
|
+
throw err;
|
|
566
|
+
});
|
|
557
567
|
pendingImages = [];
|
|
558
568
|
ui?.attachments(0);
|
|
559
569
|
latest = Math.max(latest, res.seq);
|
|
@@ -570,6 +580,7 @@ async function startChat(flags) {
|
|
|
570
580
|
const text = line.trim();
|
|
571
581
|
if (!text) return;
|
|
572
582
|
markPresent();
|
|
583
|
+
if (text === '/quit' || text === '/exit') { shutdown(0); return; }
|
|
573
584
|
queue.push(() => (text.startsWith('/') ? handleSlash(text) : sendText(text)));
|
|
574
585
|
void drain();
|
|
575
586
|
});
|