@dan-ai-studio/dshopencodego 0.1.68 → 0.1.70
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 +4 -1
- package/README.md +4 -1
- package/lib/client.js +96 -4
- package/lib/index.js +35 -9
- package/lib/types/config.d.ts +8 -0
- package/package.json +1 -1
package/README.en.md
CHANGED
|
@@ -101,6 +101,7 @@ Configuration lives in the profile's `cordis.patch.yml`:
|
|
|
101
101
|
# the timer restarts on every answer, so a connection in
|
|
102
102
|
# frequent use is never dropped; a long pause in a
|
|
103
103
|
# conversation costs one handshake (about 200ms)
|
|
104
|
+
requestGzip: true # gzip JSON request bodies of 1 KB or more; turn off if the gateway rejects them
|
|
104
105
|
maxRequestImageBytes: 6291456 # whole-request image payload cap (after base64, bytes)
|
|
105
106
|
requestImagePixelBudget: 1440000 # total-pixel budget for one image
|
|
106
107
|
requestImageMaxBytes: 400000 # encoded-byte target for one image (before base64)
|
|
@@ -141,6 +142,8 @@ The API key comes from the Harness credential store (reference name `OPENCODE_GO
|
|
|
141
142
|
- The settings page shows and accepts the value in **seconds** (a number of milliseconds is not readable at a glance) and stores it in milliseconds. Range: 1 to 1800000 milliseconds.
|
|
142
143
|
- Once a connection has been idle that long, the pool **reclaims it** on its own — no separate mechanism is needed. The actual release comes a couple of seconds later than the setting, which is the client's own small margin beyond the deadline the server states. When the plugin is unloaded, the pool is **closed with it**: the pool belongs to the plugin and should not be left behind on the machine.
|
|
143
144
|
|
|
145
|
+
**Request body gzip**: `requestGzip` is on by default; JSON bodies of 1 KB or more are gzipped (fastest level, off the event loop) with a `Content-Encoding: gzip` header, smaller bodies travel plain. The log's body size is the **actual wire bytes** — compare the same large request with the switch on and off to see what it saved. **If the gateway does not accept gzip it fails requests outright; turn the switch off** (one setting, no other coupling).
|
|
146
|
+
|
|
144
147
|
**Request log**: per-request records, on by default; turning them off returns the request path to exactly as without the log. The settings page's "Request log" group holds the master switch, the debug switch (pool events and the request user agent, default off), and the retention count (default 200).
|
|
145
148
|
|
|
146
149
|
- **Two entries, one page**:
|
|
@@ -148,7 +151,7 @@ The API key comes from the Harness credential store (reference name `OPENCODE_GO
|
|
|
148
151
|
- **A "Request log" View inside the conversation**: this session's requests, in place — answering "why was that turn slow" without leaving the chat.
|
|
149
152
|
- It is a page, not a floating card: the head, the summary (requests / failures / mean latency / mean first token / mean tok/s / mean cache hit / connection reuse) and the filters stay put while the table scrolls. Each row carries time, model, session, input/output/cache, **cache hit**, **tok/s**, first token, latency and status; clicking one expands its HTTP detail (method, protocol, URL, body size, redacted headers, request shape, result and usage, reasoning split, cache writes, per-request cost, content span). Filters: model, result, slow requests, session; groups: session, model, result; **click a column head to sort by it**, click again to flip.
|
|
150
153
|
- **tok/s** is the output rate over the decode window (first token to the end), on the same scale as the Harness's own per-turn reading (reasoning tokens included). A request that produced no token has no rate — none is invented. **A burst delivery has no rate either**: when the gateway holds a whole turn and flushes it at the end (common with reasoning models: 8 seconds of thinking invisible on the wire, then a hundred tokens in a few milliseconds), a sub-100ms content span is delivery shape, not generation speed — it shows as — and stays out of the mean.
|
|
151
|
-
- The session column names the **session title** (from the session catalog; falls back to the id, whose full spelling stays one hover away). The session filter matches titles and ids; session groups are headed the same way.
|
|
154
|
+
- The session column names the **session title** (from the session catalog; falls back to the id, whose full spelling stays one hover away). The session filter matches titles and ids; session groups are headed the same way. **Clicking a title opens that session** (an archived one refuses, and says so).
|
|
152
155
|
- **Cache hit** is the share of input tokens served from cache (cache reads over uncached input plus cache reads). No reported input means no share — none is invented either.
|
|
153
156
|
- **The In column is uncached new input**: the gateway reports a prompt as "uncached plus cache hits" and the log records only the new part — a fully prefix-cached turn reads as a tiny input with a 100% hit, which is not a bug. Hover a column head for its definition.
|
|
154
157
|
- Session ids are **always stored whole**: an id is a conversation identity, not a credential, and a truncated one reads two conversations as one.
|
package/README.md
CHANGED
|
@@ -100,6 +100,7 @@ DSH 桌面端是 Electron 壳 + 完整的 dsh Web 应用,本插件对它同样
|
|
|
100
100
|
keepAliveTimeoutMs: 600000 # 连接空闲保留:两次请求之间连接留多久(毫秒,1 ~ 1800000)
|
|
101
101
|
# 每次收到回答后重新计时,所以常用时连接不会被断开;
|
|
102
102
|
# 对话中每次停顿较久都要重新握手一次(约 200ms)
|
|
103
|
+
requestGzip: true # 1KB 以上的 JSON 请求体先 gzip 再发;网关如果拒绝就关掉它
|
|
103
104
|
maxRequestImageBytes: 6291456 # 整个请求的图片载荷上限(base64 之后,字节)
|
|
104
105
|
requestImagePixelBudget: 1440000 # 单张图的总像素预算
|
|
105
106
|
requestImageMaxBytes: 400000 # 单张图编码前的字节目标(base64 之前)
|
|
@@ -135,6 +136,8 @@ API Key 通过 Harness 凭证库提供(引用名 `OPENCODE_GO_API_KEY`),
|
|
|
135
136
|
|
|
136
137
|
**连接保留**:`keepAliveTimeoutMs` 决定**与网关的连接在两次请求之间保留多久**。计时器**每次收到回答后重新开始**,所以常用时连接不会被断开,它约束的只是两次请求之间的静默。默认 10 分钟。
|
|
137
138
|
|
|
139
|
+
**请求体压缩**:`requestGzip` 默认开启,1KB 以上的 JSON 请求先 gzip(最快档,异步压,不堵事件循环)再发,`Content-Encoding: gzip` 随行;1KB 以下原样走(压了也省不出什么)。日志里"请求体"记的是** wire 上的实际字节**——同一条大请求,开关两边对比一下就知道压了多少。**网关如果不吃 gzip 会直接 4xx,那时关掉这个开关就行**(一处配置,没有别的连带)。
|
|
140
|
+
|
|
138
141
|
- 背后的原因很实际:连接一旦被断开,下一次请求要重新做一次 TCP 与 TLS 握手,**到网关这一侧约 200 毫秒**,而这笔开销正好落在**下一轮的第一个 token 上**。对话里的停顿(读答案、思考、再打字)通常在 5 ~ 30 秒,正好跨过 HTTP 客户端默认的 4 秒,于是**几乎每一轮都在白付一次握手**。
|
|
139
142
|
- 这条只影响**固定了地址**(`pinnedAddresses`)的部署:没有固定地址时走的是系统自己的 fetch,本插件不加任何东西。
|
|
140
143
|
- 设置页里以**秒**显示与填写(毫秒的数字人读不出量级),存储时换算成毫秒。取值 1 ~ 1800000 毫秒。
|
|
@@ -147,7 +150,7 @@ API Key 通过 Harness 凭证库提供(引用名 `OPENCODE_GO_API_KEY`),
|
|
|
147
150
|
- **会话里的「请求日志」标签页**:就地看**本会话**的请求,回答"刚才那轮为什么慢"不用离开对话。
|
|
148
151
|
- 页面是一整页而不是浮层:标题、统计(请求数/失败数/平均耗时/平均首字/平均 tok/s/平均缓存命中/连接复用率)、筛选栏固定在上方,只有表格自己滚动。每行含时间、模型、会话、输入/输出/缓存、**缓存命中**、**tok/s**、首字、耗时与状态;点一行展开 HTTP 明细(方法、协议、地址、请求体大小、脱敏后的请求头、请求构成、结果与用量、推理拆分、缓存写入、单轮花费、内容跨度)。筛选有模型/结果/慢请求/会话,分组有会话/模型/结果;**点列头按该列排序**,再点一次反向。
|
|
149
152
|
- **tok/s** 是**首字到结束**这段解码窗口上的输出速率,口径与 Harness 自己的每轮读数一致(含推理 token)。没有 token 的请求没有速率——不编数。**突发推送同样没有速率**:网关把一整轮攒到最后一次性推过来时(推理模型常见:8 秒思考在 wire 上不可见,然后上百个 token 几毫秒内到达),内容跨度不足 100ms,算出来的"每秒几万 token"不是生成速度——显示为 —,也不计入平均。
|
|
150
|
-
- 会话列显示**会话标题**(标题来自会话目录;拿不到时回退显示 id,悬停可见完整 id)。会话筛选同时匹配标题与 id
|
|
153
|
+
- 会话列显示**会话标题**(标题来自会话目录;拿不到时回退显示 id,悬停可见完整 id)。会话筛选同时匹配标题与 id;按会话分组的组头同样显示标题。**点标题直接打开那个会话**(归档的打不开,会明说)。
|
|
151
154
|
- **缓存命中**是输入 token 里走缓存的占比(缓存读取/(未缓存输入+缓存读取))。网关没报输入就没有占比——同样不编数。
|
|
152
155
|
- **输入列是未缓存的新增 token**:网关把整段 prompt 拆成"未缓存+缓存命中"两部分上报,输入列只记新增的——同一会话前缀缓存全中时输入很小、缓存命中 100%,不是 bug。悬停列头有口径说明。
|
|
153
156
|
- 会话 id **始终完整记录**(它是会话身份,不是凭据;截断后两个会话会读成一个)。
|
package/lib/client.js
CHANGED
|
@@ -506,6 +506,8 @@ var en = {
|
|
|
506
506
|
refreshHint: "How long requests and the model picker reuse one listing.",
|
|
507
507
|
keepAliveLabel: "Connection kept idle (seconds)",
|
|
508
508
|
keepAliveHint: "How long a connection to the gateway is held between requests. Longer pauses in a conversation cost one handshake each; the timer restarts on every answer.",
|
|
509
|
+
requestGzipLabel: "Gzip request bodies",
|
|
510
|
+
requestGzipHint: "Compress JSON bodies of 1 KB or more before sending. Turn off if the gateway rejects requests.",
|
|
509
511
|
requestLogTitle: "Request log",
|
|
510
512
|
requestLogHint: "Per-request records for troubleshooting. On by default; turning it off returns the request path to exactly as without the log.",
|
|
511
513
|
requestLogPageHint: "One row per request. Click a column head to sort; the table scrolls and the filters stay put.",
|
|
@@ -516,6 +518,7 @@ var en = {
|
|
|
516
518
|
requestLogMaxEntriesHint: "50 to 500; oldest entries are dropped first. Default 200.",
|
|
517
519
|
requestLogOpen: "Open request log",
|
|
518
520
|
requestLogOpenFailed: "The request-log page could not be opened. Use the sidebar entry.",
|
|
521
|
+
requestLogOpenSessionFailed: "That session is archived and cannot be opened.",
|
|
519
522
|
requestLogClose: "Close",
|
|
520
523
|
requestLogRefresh: "Refresh",
|
|
521
524
|
requestLogEmpty: "No requests recorded. Turn the log on, then make a request.",
|
|
@@ -695,6 +698,8 @@ var zh = {
|
|
|
695
698
|
refreshHint: "\u8BF7\u6C42\u4E0E\u6A21\u578B\u9009\u62E9\u5668\u590D\u7528\u540C\u4E00\u4EFD\u5217\u8868\u7684\u65F6\u957F\u3002",
|
|
696
699
|
keepAliveLabel: "\u8FDE\u63A5\u7A7A\u95F2\u4FDD\u7559\uFF08\u79D2\uFF09",
|
|
697
700
|
keepAliveHint: "\u4E0E\u7F51\u5173\u7684\u8FDE\u63A5\u5728\u4E24\u6B21\u8BF7\u6C42\u4E4B\u95F4\u4FDD\u7559\u591A\u4E45\u3002\u5BF9\u8BDD\u4E2D\u6BCF\u6B21\u505C\u987F\u8F83\u4E45\u90FD\u8981\u91CD\u65B0\u63E1\u624B\u4E00\u6B21\uFF1B\u6BCF\u6B21\u6536\u5230\u56DE\u7B54\u540E\u8BA1\u65F6\u90FD\u4F1A\u91CD\u65B0\u5F00\u59CB\u3002",
|
|
701
|
+
requestGzipLabel: "\u8BF7\u6C42\u4F53 gzip \u538B\u7F29",
|
|
702
|
+
requestGzipHint: "1KB \u4EE5\u4E0A\u7684 JSON \u8BF7\u6C42\u4F53\u5148\u538B\u7F29\u518D\u53D1\uFF1B\u7F51\u5173\u5982\u679C\u62D2\u7EDD\u8BF7\u6C42\u5C31\u5173\u6389\u5B83\u3002",
|
|
698
703
|
requestLogTitle: "\u8BF7\u6C42\u65E5\u5FD7",
|
|
699
704
|
requestLogHint: "\u6392\u67E5\u7528\u7684\u9010\u8BF7\u6C42\u8BB0\u5F55\u3002\u9ED8\u8BA4\u5F00\u542F\uFF1B\u5173\u95ED\u540E\u8BF7\u6C42\u8DEF\u5F84\u4E0E\u6CA1\u6709\u8BE5\u65E5\u5FD7\u9010\u5B57\u8282\u4E00\u81F4\u3002",
|
|
700
705
|
requestLogPageHint: "\u6BCF\u4E2A\u8BF7\u6C42\u4E00\u884C\u3002\u70B9\u5217\u5934\u53EF\u6392\u5E8F\uFF1B\u8868\u683C\u6EDA\u52A8\uFF0C\u7B5B\u9009\u680F\u56FA\u5B9A\u5728\u4E0A\u65B9\u3002",
|
|
@@ -705,6 +710,7 @@ var zh = {
|
|
|
705
710
|
requestLogMaxEntriesHint: "50\uFF5E500 \u6761\uFF0C\u8D85\u9650\u4E22\u5F03\u6700\u65E7\u7684\u3002\u9ED8\u8BA4 200 \u6761\u3002",
|
|
706
711
|
requestLogOpen: "\u6253\u5F00\u8BF7\u6C42\u65E5\u5FD7",
|
|
707
712
|
requestLogOpenFailed: "\u6253\u4E0D\u5F00\u8BF7\u6C42\u65E5\u5FD7\u9875\u9762\uFF0C\u8BF7\u4ECE\u4FA7\u8FB9\u680F\u7684\u5165\u53E3\u6253\u5F00\u3002",
|
|
713
|
+
requestLogOpenSessionFailed: "\u8BE5\u4F1A\u8BDD\u5DF2\u5F52\u6863\uFF0C\u6253\u4E0D\u5F00\u3002",
|
|
708
714
|
requestLogClose: "\u5173\u95ED",
|
|
709
715
|
requestLogRefresh: "\u5237\u65B0",
|
|
710
716
|
requestLogEmpty: "\u6682\u65E0\u8BB0\u5F55\u3002\u5148\u6253\u5F00\u65E5\u5FD7\u5F00\u5173\uFF0C\u518D\u53D1\u8D77\u4E00\u6B21\u8BF7\u6C42\u3002",
|
|
@@ -1029,11 +1035,13 @@ function settingsOf(value) {
|
|
|
1029
1035
|
const requestLogEnabled = record["requestLogEnabled"];
|
|
1030
1036
|
const requestLogDebug = record["requestLogDebug"];
|
|
1031
1037
|
const requestLogMaxEntries = record["requestLogMaxEntries"];
|
|
1038
|
+
const requestGzip = record["requestGzip"];
|
|
1032
1039
|
return {
|
|
1033
1040
|
modelVisibility: Object.fromEntries(entries),
|
|
1034
1041
|
refreshMinutes: minutes,
|
|
1035
1042
|
pinnedAddresses: Object.fromEntries(pinEntries),
|
|
1036
1043
|
keepAliveTimeoutMs: typeof keepAlive === "number" ? keepAlive : DEFAULT_KEEP_ALIVE_TIMEOUT_MS,
|
|
1044
|
+
requestGzip: typeof requestGzip === "boolean" ? requestGzip : true,
|
|
1037
1045
|
requestLogEnabled: typeof requestLogEnabled === "boolean" ? requestLogEnabled : true,
|
|
1038
1046
|
requestLogDebug: typeof requestLogDebug === "boolean" ? requestLogDebug : false,
|
|
1039
1047
|
requestLogMaxEntries: typeof requestLogMaxEntries === "number" ? requestLogMaxEntries : DEFAULT_REQUEST_LOG_MAX_ENTRIES
|
|
@@ -1448,6 +1456,20 @@ var SectionController = class _SectionController {
|
|
|
1448
1456
|
() => this.set({ settings: { ...current, keepAliveTimeoutMs: milliseconds } })
|
|
1449
1457
|
);
|
|
1450
1458
|
}
|
|
1459
|
+
/**
|
|
1460
|
+
* Flip request-body gzip. Off returns every request to plain JSON; it is
|
|
1461
|
+
* the whole fallback plan if the gateway ever rejects a compressed body.
|
|
1462
|
+
*/
|
|
1463
|
+
async setRequestGzip(enabled) {
|
|
1464
|
+
const scope = this.services.scope;
|
|
1465
|
+
const current = this.state.settings;
|
|
1466
|
+
if (scope === void 0 || current === void 0 || !this.state.writable) return;
|
|
1467
|
+
if (typeof enabled !== "boolean") return;
|
|
1468
|
+
await this.write(
|
|
1469
|
+
() => scope.set("requestGzip", enabled),
|
|
1470
|
+
() => this.set({ settings: { ...current, requestGzip: enabled } })
|
|
1471
|
+
);
|
|
1472
|
+
}
|
|
1451
1473
|
/**
|
|
1452
1474
|
* Flip the request-log master switch. Off (the default) means no record is
|
|
1453
1475
|
* kept and the request path reads exactly as without the log.
|
|
@@ -1889,6 +1911,25 @@ function Section({ controller, t, getLocale, openRequestLog }) {
|
|
|
1889
1911
|
),
|
|
1890
1912
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: section_default.hint, children: t("keepAliveHint") })
|
|
1891
1913
|
] }),
|
|
1914
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("div", { className: section_default.row, children: [
|
|
1915
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: section_default.hint, children: [
|
|
1916
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)(
|
|
1917
|
+
"input",
|
|
1918
|
+
{
|
|
1919
|
+
type: "checkbox",
|
|
1920
|
+
checked: state.settings?.requestGzip ?? true,
|
|
1921
|
+
disabled: !editable || state.saving,
|
|
1922
|
+
onChange: (event) => {
|
|
1923
|
+
void act(async () => {
|
|
1924
|
+
await controller.setRequestGzip(event.target.checked);
|
|
1925
|
+
});
|
|
1926
|
+
}
|
|
1927
|
+
}
|
|
1928
|
+
),
|
|
1929
|
+
` ${t("requestGzipLabel")}`
|
|
1930
|
+
] }),
|
|
1931
|
+
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("span", { className: section_default.hint, children: t("requestGzipHint") })
|
|
1932
|
+
] }),
|
|
1892
1933
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: section_default.row, children: /* @__PURE__ */ (0, import_jsx_runtime.jsx)("strong", { children: t("requestLogTitle") }) }),
|
|
1893
1934
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("p", { className: section_default.hint, children: t("requestLogHint") }),
|
|
1894
1935
|
/* @__PURE__ */ (0, import_jsx_runtime.jsx)("div", { className: section_default.row, children: /* @__PURE__ */ (0, import_jsx_runtime.jsxs)("label", { className: section_default.hint, children: [
|
|
@@ -2071,10 +2112,10 @@ if (!document.querySelector("style[data-plugin-css=" + JSON.stringify(id2) + "]"
|
|
|
2071
2112
|
const style = document.createElement("style");
|
|
2072
2113
|
style.dataset.plugin = "@dan-ai-studio/dshopencodego";
|
|
2073
2114
|
style.dataset.pluginCss = id2;
|
|
2074
|
-
style.textContent = ".Lx7MOq_page{box-sizing:border-box;background:var(--dsw-alias-bg-base);height:100%;min-height:0;color:var(--dsw-alias-label-primary);flex-direction:column;display:flex}.Lx7MOq_pageLoose{height:auto}.Lx7MOq_pageLoose .Lx7MOq_tableWrap{overflow:visible}.Lx7MOq_pageLoose .Lx7MOq_stuck{z-index:3;background:var(--dsw-alias-bg-base);position:sticky;top:0}.Lx7MOq_pageLoose .Lx7MOq_table th{top:var(--request-log-stuck,0px)}.Lx7MOq_pageLoose .Lx7MOq_foot{z-index:2;background:var(--dsw-alias-bg-base);position:sticky;bottom:0}.Lx7MOq_head{flex-wrap:wrap;flex:none;align-items:center;gap:12px;padding:20px clamp(16px,3vw,32px) 12px;display:flex}.Lx7MOq_headText{min-width:0}.Lx7MOq_title{margin:0;font-size:20px;font-weight:500;line-height:28px}.Lx7MOq_subtitle{color:var(--dsw-alias-label-secondary);margin:4px 0 0;font-size:13px;line-height:20px}.Lx7MOq_headActions{flex:none;align-items:center;gap:8px;margin-left:auto;display:flex}.Lx7MOq_button{border:1px solid var(--dsw-alias-border-l2);border-radius:var(--dsw-radius-sm);background:var(--dsw-alias-bg-layer-1);height:28px;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;align-items:center;gap:6px;padding:0 12px;font-size:13px;display:inline-flex}.Lx7MOq_button:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.Lx7MOq_button:disabled{cursor:default;opacity:.5}.Lx7MOq_summary{flex-wrap:wrap;flex:none;gap:8px;padding:0 clamp(16px,3vw,32px) 12px;display:flex}.Lx7MOq_card{border:1px solid var(--dsw-alias-border-l2);border-radius:var(--dsw-radius-md);background:var(--dsw-alias-bg-layer-1);flex-direction:column;gap:2px;min-width:104px;padding:8px 12px;display:flex}.Lx7MOq_cardLabel{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:16px}.Lx7MOq_cardValue{font-variant-numeric:tabular-nums;font-size:16px;font-weight:500;line-height:22px}.Lx7MOq_cardError .Lx7MOq_cardValue{color:var(--dsw-alias-state-error-primary)}.Lx7MOq_cardWarn .Lx7MOq_cardValue{color:var(--dsw-alias-state-warn-primary)}.Lx7MOq_toolbar{flex-wrap:wrap;flex:none;align-items:center;gap:8px 12px;padding:0 clamp(16px,3vw,32px) 12px;display:flex}.Lx7MOq_field{color:var(--dsw-alias-label-secondary);align-items:center;gap:6px;font-size:13px;line-height:20px;display:inline-flex}.Lx7MOq_select,.Lx7MOq_input{border:1px solid var(--dsw-alias-border-l2);border-radius:var(--dsw-radius-sm);background:var(--dsw-alias-bg-layer-1);height:28px;color:var(--dsw-alias-label-primary);font:inherit;padding:0 8px;font-size:13px}.Lx7MOq_input{width:160px}.Lx7MOq_inputNumber{width:72px}.Lx7MOq_checkbox{accent-color:var(--dsw-alias-brand-primary)}.Lx7MOq_tableWrap{border:1px solid var(--dsw-alias-border-l2);border-radius:var(--dsw-radius-md);background:var(--dsw-alias-bg-layer-1);flex:1;min-height:0;margin:0 clamp(16px,3vw,32px);overflow:auto}.Lx7MOq_table{border-collapse:separate;border-spacing:0;width:100%;min-width:940px;font-size:13px;line-height:20px}.Lx7MOq_table th{z-index:1;border-bottom:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-tertiary);text-align:left;white-space:nowrap;padding:8px 10px;font-size:12px;font-weight:500;position:sticky;top:0}.Lx7MOq_thSortable{cursor:pointer;user-select:none}.Lx7MOq_thSortable:hover{color:var(--dsw-alias-label-primary)}.Lx7MOq_table td{border-bottom:1px solid var(--dsw-alias-border-l1);white-space:nowrap;font-variant-numeric:tabular-nums;padding:6px 10px}.Lx7MOq_table tbody tr:last-child td{border-bottom:none}.Lx7MOq_row{cursor:pointer}.Lx7MOq_row:hover td{background:var(--dsw-alias-interactive-bg-hover)}.Lx7MOq_rowOk td:first-child{box-shadow:inset 3px 0 0 var(--dsw-alias-border-l3)}.Lx7MOq_rowSlow td:first-child{box-shadow:inset 3px 0 0 var(--dsw-alias-state-warn-primary)}.Lx7MOq_rowFail td:first-child{box-shadow:inset 3px 0 0 var(--dsw-alias-state-error-primary)}.Lx7MOq_rowFail td:last-child,.Lx7MOq_rowSlow td:last-child{color:var(--dsw-alias-state-error-primary)}.Lx7MOq_group td{border-bottom:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);padding-top:12px;font-weight:500}.Lx7MOq_detail td{border-bottom:1px solid var(--dsw-alias-border-l1);white-space:normal;background:var(--dsw-alias-bg-layer-2);padding:12px 10px 16px}.Lx7MOq_detailGrid{grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:6px 24px;display:grid}.Lx7MOq_detailItem{gap:8px;min-width:0;font-size:13px;line-height:20px;display:flex}.Lx7MOq_detailLabel{color:var(--dsw-alias-label-tertiary);flex:none}.Lx7MOq_detailValue{overflow-wrap:anywhere;min-width:0;color:var(--dsw-alias-label-primary)}.Lx7MOq_mono{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px}.Lx7MOq_empty{text-align:center;color:var(--dsw-alias-label-tertiary);padding:48px 16px}.Lx7MOq_foot{color:var(--dsw-alias-label-tertiary);flex-wrap:wrap;flex:none;align-items:center;gap:12px;padding:12px clamp(16px,3vw,32px) 20px;font-size:12px;display:flex}.Lx7MOq_pager{align-items:center;gap:8px;margin-left:auto;display:flex}.Lx7MOq_notice{color:var(--dsw-alias-label-secondary);padding:0 clamp(16px,3vw,32px) 12px;font-size:13px;line-height:20px}.Lx7MOq_noticeError{color:var(--dsw-alias-state-error-primary)}";
|
|
2115
|
+
style.textContent = ".Lx7MOq_page{box-sizing:border-box;background:var(--dsw-alias-bg-base);height:100%;min-height:0;color:var(--dsw-alias-label-primary);flex-direction:column;display:flex}.Lx7MOq_pageLoose{height:auto}.Lx7MOq_pageLoose .Lx7MOq_tableWrap{overflow:visible}.Lx7MOq_pageLoose .Lx7MOq_stuck{z-index:3;background:var(--dsw-alias-bg-base);position:sticky;top:0}.Lx7MOq_pageLoose .Lx7MOq_table th{top:var(--request-log-stuck,0px)}.Lx7MOq_pageLoose .Lx7MOq_foot{z-index:2;background:var(--dsw-alias-bg-base);position:sticky;bottom:0}.Lx7MOq_head{flex-wrap:wrap;flex:none;align-items:center;gap:12px;padding:20px clamp(16px,3vw,32px) 12px;display:flex}.Lx7MOq_headText{min-width:0}.Lx7MOq_title{margin:0;font-size:20px;font-weight:500;line-height:28px}.Lx7MOq_subtitle{color:var(--dsw-alias-label-secondary);margin:4px 0 0;font-size:13px;line-height:20px}.Lx7MOq_headActions{flex:none;align-items:center;gap:8px;margin-left:auto;display:flex}.Lx7MOq_button{border:1px solid var(--dsw-alias-border-l2);border-radius:var(--dsw-radius-sm);background:var(--dsw-alias-bg-layer-1);height:28px;color:var(--dsw-alias-label-primary);font:inherit;cursor:pointer;align-items:center;gap:6px;padding:0 12px;font-size:13px;display:inline-flex}.Lx7MOq_button:hover:not(:disabled){background:var(--dsw-alias-interactive-bg-hover)}.Lx7MOq_button:disabled{cursor:default;opacity:.5}.Lx7MOq_summary{flex-wrap:wrap;flex:none;gap:8px;padding:0 clamp(16px,3vw,32px) 12px;display:flex}.Lx7MOq_card{border:1px solid var(--dsw-alias-border-l2);border-radius:var(--dsw-radius-md);background:var(--dsw-alias-bg-layer-1);flex-direction:column;gap:2px;min-width:104px;padding:8px 12px;display:flex}.Lx7MOq_cardLabel{color:var(--dsw-alias-label-tertiary);font-size:12px;line-height:16px}.Lx7MOq_cardValue{font-variant-numeric:tabular-nums;font-size:16px;font-weight:500;line-height:22px}.Lx7MOq_cardError .Lx7MOq_cardValue{color:var(--dsw-alias-state-error-primary)}.Lx7MOq_cardWarn .Lx7MOq_cardValue{color:var(--dsw-alias-state-warn-primary)}.Lx7MOq_toolbar{flex-wrap:wrap;flex:none;align-items:center;gap:8px 12px;padding:0 clamp(16px,3vw,32px) 12px;display:flex}.Lx7MOq_field{color:var(--dsw-alias-label-secondary);align-items:center;gap:6px;font-size:13px;line-height:20px;display:inline-flex}.Lx7MOq_select,.Lx7MOq_input{border:1px solid var(--dsw-alias-border-l2);border-radius:var(--dsw-radius-sm);background:var(--dsw-alias-bg-layer-1);height:28px;color:var(--dsw-alias-label-primary);font:inherit;padding:0 8px;font-size:13px}.Lx7MOq_input{width:160px}.Lx7MOq_inputNumber{width:72px}.Lx7MOq_checkbox{accent-color:var(--dsw-alias-brand-primary)}.Lx7MOq_sessionLink{color:var(--dsw-alias-link);font:inherit;text-align:left;cursor:pointer;white-space:nowrap;background:0 0;border:none;padding:0}.Lx7MOq_sessionLink:hover{text-decoration:underline}.Lx7MOq_tableWrap{border:1px solid var(--dsw-alias-border-l2);border-radius:var(--dsw-radius-md);background:var(--dsw-alias-bg-layer-1);flex:1;min-height:0;margin:0 clamp(16px,3vw,32px);overflow:auto}.Lx7MOq_table{border-collapse:separate;border-spacing:0;width:100%;min-width:940px;font-size:13px;line-height:20px}.Lx7MOq_table th{z-index:1;border-bottom:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-2);color:var(--dsw-alias-label-tertiary);text-align:left;white-space:nowrap;padding:8px 10px;font-size:12px;font-weight:500;position:sticky;top:0}.Lx7MOq_thSortable{cursor:pointer;user-select:none}.Lx7MOq_thSortable:hover{color:var(--dsw-alias-label-primary)}.Lx7MOq_table td{border-bottom:1px solid var(--dsw-alias-border-l1);white-space:nowrap;font-variant-numeric:tabular-nums;padding:6px 10px}.Lx7MOq_table tbody tr:last-child td{border-bottom:none}.Lx7MOq_row{cursor:pointer}.Lx7MOq_row:hover td{background:var(--dsw-alias-interactive-bg-hover)}.Lx7MOq_rowOk td:first-child{box-shadow:inset 3px 0 0 var(--dsw-alias-border-l3)}.Lx7MOq_rowSlow td:first-child{box-shadow:inset 3px 0 0 var(--dsw-alias-state-warn-primary)}.Lx7MOq_rowFail td:first-child{box-shadow:inset 3px 0 0 var(--dsw-alias-state-error-primary)}.Lx7MOq_rowFail td:last-child,.Lx7MOq_rowSlow td:last-child{color:var(--dsw-alias-state-error-primary)}.Lx7MOq_group td{border-bottom:1px solid var(--dsw-alias-border-l2);color:var(--dsw-alias-label-secondary);padding-top:12px;font-weight:500}.Lx7MOq_detail td{border-bottom:1px solid var(--dsw-alias-border-l1);white-space:normal;background:var(--dsw-alias-bg-layer-2);padding:12px 10px 16px}.Lx7MOq_detailGrid{grid-template-columns:repeat(auto-fit,minmax(220px,1fr));gap:6px 24px;display:grid}.Lx7MOq_detailItem{gap:8px;min-width:0;font-size:13px;line-height:20px;display:flex}.Lx7MOq_detailLabel{color:var(--dsw-alias-label-tertiary);flex:none}.Lx7MOq_detailValue{overflow-wrap:anywhere;min-width:0;color:var(--dsw-alias-label-primary)}.Lx7MOq_mono{font-family:ui-monospace,SFMono-Regular,Menlo,Consolas,monospace;font-size:12px}.Lx7MOq_empty{text-align:center;color:var(--dsw-alias-label-tertiary);padding:48px 16px}.Lx7MOq_foot{color:var(--dsw-alias-label-tertiary);flex-wrap:wrap;flex:none;align-items:center;gap:12px;padding:12px clamp(16px,3vw,32px) 20px;font-size:12px;display:flex}.Lx7MOq_pager{align-items:center;gap:8px;margin-left:auto;display:flex}.Lx7MOq_notice{color:var(--dsw-alias-label-secondary);padding:0 clamp(16px,3vw,32px) 12px;font-size:13px;line-height:20px}.Lx7MOq_noticeError{color:var(--dsw-alias-state-error-primary)}";
|
|
2075
2116
|
document.head.appendChild(style);
|
|
2076
2117
|
}
|
|
2077
|
-
var request_log_default = { "button": "Lx7MOq_button", "card": "Lx7MOq_card", "cardError": "Lx7MOq_cardError", "cardLabel": "Lx7MOq_cardLabel", "cardValue": "Lx7MOq_cardValue", "cardWarn": "Lx7MOq_cardWarn", "checkbox": "Lx7MOq_checkbox", "detail": "Lx7MOq_detail", "detailGrid": "Lx7MOq_detailGrid", "detailItem": "Lx7MOq_detailItem", "detailLabel": "Lx7MOq_detailLabel", "detailValue": "Lx7MOq_detailValue", "empty": "Lx7MOq_empty", "field": "Lx7MOq_field", "foot": "Lx7MOq_foot", "group": "Lx7MOq_group", "head": "Lx7MOq_head", "headActions": "Lx7MOq_headActions", "headText": "Lx7MOq_headText", "input": "Lx7MOq_input", "inputNumber": "Lx7MOq_inputNumber", "mono": "Lx7MOq_mono", "notice": "Lx7MOq_notice", "noticeError": "Lx7MOq_noticeError", "page": "Lx7MOq_page", "pageLoose": "Lx7MOq_pageLoose", "pager": "Lx7MOq_pager", "row": "Lx7MOq_row", "rowFail": "Lx7MOq_rowFail", "rowOk": "Lx7MOq_rowOk", "rowSlow": "Lx7MOq_rowSlow", "select": "Lx7MOq_select", "stuck": "Lx7MOq_stuck", "subtitle": "Lx7MOq_subtitle", "summary": "Lx7MOq_summary", "table": "Lx7MOq_table", "tableWrap": "Lx7MOq_tableWrap", "thSortable": "Lx7MOq_thSortable", "title": "Lx7MOq_title", "toolbar": "Lx7MOq_toolbar" };
|
|
2118
|
+
var request_log_default = { "button": "Lx7MOq_button", "card": "Lx7MOq_card", "cardError": "Lx7MOq_cardError", "cardLabel": "Lx7MOq_cardLabel", "cardValue": "Lx7MOq_cardValue", "cardWarn": "Lx7MOq_cardWarn", "checkbox": "Lx7MOq_checkbox", "detail": "Lx7MOq_detail", "detailGrid": "Lx7MOq_detailGrid", "detailItem": "Lx7MOq_detailItem", "detailLabel": "Lx7MOq_detailLabel", "detailValue": "Lx7MOq_detailValue", "empty": "Lx7MOq_empty", "field": "Lx7MOq_field", "foot": "Lx7MOq_foot", "group": "Lx7MOq_group", "head": "Lx7MOq_head", "headActions": "Lx7MOq_headActions", "headText": "Lx7MOq_headText", "input": "Lx7MOq_input", "inputNumber": "Lx7MOq_inputNumber", "mono": "Lx7MOq_mono", "notice": "Lx7MOq_notice", "noticeError": "Lx7MOq_noticeError", "page": "Lx7MOq_page", "pageLoose": "Lx7MOq_pageLoose", "pager": "Lx7MOq_pager", "row": "Lx7MOq_row", "rowFail": "Lx7MOq_rowFail", "rowOk": "Lx7MOq_rowOk", "rowSlow": "Lx7MOq_rowSlow", "select": "Lx7MOq_select", "sessionLink": "Lx7MOq_sessionLink", "stuck": "Lx7MOq_stuck", "subtitle": "Lx7MOq_subtitle", "summary": "Lx7MOq_summary", "table": "Lx7MOq_table", "tableWrap": "Lx7MOq_tableWrap", "thSortable": "Lx7MOq_thSortable", "title": "Lx7MOq_title", "toolbar": "Lx7MOq_toolbar" };
|
|
2078
2119
|
|
|
2079
2120
|
// src/client/RequestLogPage.tsx
|
|
2080
2121
|
var import_jsx_runtime2 = require("react/jsx-runtime");
|
|
@@ -2165,7 +2206,7 @@ function groupKey(entry, groupBy) {
|
|
|
2165
2206
|
return void 0;
|
|
2166
2207
|
}
|
|
2167
2208
|
}
|
|
2168
|
-
function RequestLogPage({ readLog, enabled, t, getLocale, sessionId, useSessions }) {
|
|
2209
|
+
function RequestLogPage({ readLog, enabled, canOpenSession, openSession, t, getLocale, sessionId, useSessions }) {
|
|
2169
2210
|
const [snapshot, setSnapshot] = (0, import_react2.useState)(void 0);
|
|
2170
2211
|
const [failure, setFailure] = (0, import_react2.useState)(void 0);
|
|
2171
2212
|
const [refreshing, setRefreshing] = (0, import_react2.useState)(false);
|
|
@@ -2177,6 +2218,7 @@ function RequestLogPage({ readLog, enabled, t, getLocale, sessionId, useSessions
|
|
|
2177
2218
|
const [groupBy, setGroupBy] = (0, import_react2.useState)("none");
|
|
2178
2219
|
const [page, setPage] = (0, import_react2.useState)(0);
|
|
2179
2220
|
const [expanded, setExpanded] = (0, import_react2.useState)(null);
|
|
2221
|
+
const [sessionOpenFailed, setSessionOpenFailed] = (0, import_react2.useState)(false);
|
|
2180
2222
|
const [sortKey, setSortKey] = (0, import_react2.useState)("atMs");
|
|
2181
2223
|
const [sortDir, setSortDir] = (0, import_react2.useState)("desc");
|
|
2182
2224
|
const [onlySession, setOnlySession] = (0, import_react2.useState)(sessionId !== void 0);
|
|
@@ -2298,7 +2340,25 @@ function RequestLogPage({ readLog, enabled, t, getLocale, sessionId, useSessions
|
|
|
2298
2340
|
children: [
|
|
2299
2341
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("td", { children: new Date(entry.atMs).toLocaleTimeString(getLocale(), { hour12: false }) }),
|
|
2300
2342
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("td", { className: request_log_default.mono, children: entry.model }),
|
|
2301
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
2343
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
2344
|
+
"td",
|
|
2345
|
+
{
|
|
2346
|
+
title: session.titled ? entry.session : void 0,
|
|
2347
|
+
className: session.titled ? void 0 : request_log_default.mono,
|
|
2348
|
+
children: session.titled && canOpenSession() ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
2349
|
+
"button",
|
|
2350
|
+
{
|
|
2351
|
+
type: "button",
|
|
2352
|
+
className: request_log_default.sessionLink,
|
|
2353
|
+
title: `${session.text} \xB7 ${entry.session}`,
|
|
2354
|
+
onClick: () => {
|
|
2355
|
+
setSessionOpenFailed(!openSession(entry.session));
|
|
2356
|
+
},
|
|
2357
|
+
children: session.text
|
|
2358
|
+
}
|
|
2359
|
+
) : session.text
|
|
2360
|
+
}
|
|
2361
|
+
),
|
|
2302
2362
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("td", { children: count2(entry.inputTokens) }),
|
|
2303
2363
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("td", { children: count2(entry.outputTokens) }),
|
|
2304
2364
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("td", { children: count2(entry.cacheReadTokens) }),
|
|
@@ -2413,6 +2473,7 @@ function RequestLogPage({ readLog, enabled, t, getLocale, sessionId, useSessions
|
|
|
2413
2473
|
] }),
|
|
2414
2474
|
!enabled() && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: request_log_default.notice, children: t("requestLogDisabled") }),
|
|
2415
2475
|
failure !== void 0 && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: `${request_log_default.notice} ${request_log_default.noticeError}`, children: failure }),
|
|
2476
|
+
sessionOpenFailed && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("p", { className: `${request_log_default.notice} ${request_log_default.noticeError}`, children: t("requestLogOpenSessionFailed") }),
|
|
2416
2477
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: request_log_default.summary, children: [
|
|
2417
2478
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { className: request_log_default.card, children: [
|
|
2418
2479
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { className: request_log_default.cardLabel, children: t("requestLogStatRequests") }),
|
|
@@ -2811,6 +2872,20 @@ function apply(ctx) {
|
|
|
2811
2872
|
layout.current = void 0;
|
|
2812
2873
|
};
|
|
2813
2874
|
});
|
|
2875
|
+
const sessionOpener = { current: void 0 };
|
|
2876
|
+
ctx.inject(["uiWorkspace"], (workspaceScope) => {
|
|
2877
|
+
sessionOpener.current = workspaceScope.uiWorkspace;
|
|
2878
|
+
return () => {
|
|
2879
|
+
sessionOpener.current = void 0;
|
|
2880
|
+
};
|
|
2881
|
+
});
|
|
2882
|
+
const sessionArchive = { current: void 0 };
|
|
2883
|
+
ctx.inject(["workspaces"], (archiveScope) => {
|
|
2884
|
+
sessionArchive.current = archiveScope.workspaces;
|
|
2885
|
+
return () => {
|
|
2886
|
+
sessionArchive.current = void 0;
|
|
2887
|
+
};
|
|
2888
|
+
});
|
|
2814
2889
|
const mounted = ctx.remote.$mount({
|
|
2815
2890
|
package: usageRemote.package,
|
|
2816
2891
|
descriptors: [
|
|
@@ -2863,6 +2938,23 @@ function apply(ctx) {
|
|
|
2863
2938
|
if (value === null || typeof value !== "object") return false;
|
|
2864
2939
|
return value.requestLogEnabled === true;
|
|
2865
2940
|
},
|
|
2941
|
+
// Whether a title click can open its session. The navigation service
|
|
2942
|
+
// is a separate composition member; without it titles stay text.
|
|
2943
|
+
canOpenSession: () => sessionOpener.current !== void 0,
|
|
2944
|
+
// Select a session and show its conversation: the same call the
|
|
2945
|
+
// sidebar's own rows make. Archived sessions refuse, and a throw
|
|
2946
|
+
// leaves the selection where it was — both read as false.
|
|
2947
|
+
openSession: (sessionId) => {
|
|
2948
|
+
const opener = sessionOpener.current;
|
|
2949
|
+
if (opener === void 0) return false;
|
|
2950
|
+
if (sessionArchive.current?.list.getSnapshot().archivedSessionIds.includes(sessionId) === true) return false;
|
|
2951
|
+
try {
|
|
2952
|
+
opener.openSession(sessionId);
|
|
2953
|
+
return true;
|
|
2954
|
+
} catch {
|
|
2955
|
+
return false;
|
|
2956
|
+
}
|
|
2957
|
+
},
|
|
2866
2958
|
t: (key) => translate(key),
|
|
2867
2959
|
getLocale: () => scope.locale.getLocale().active
|
|
2868
2960
|
};
|
package/lib/index.js
CHANGED
|
@@ -59979,7 +59979,7 @@ var require_mock_interceptor = __commonJS({
|
|
|
59979
59979
|
var require_mock_client = __commonJS({
|
|
59980
59980
|
"node_modules/undici/lib/mock/mock-client.js"(exports, module) {
|
|
59981
59981
|
"use strict";
|
|
59982
|
-
var { promisify } = __require("node:util");
|
|
59982
|
+
var { promisify: promisify2 } = __require("node:util");
|
|
59983
59983
|
var Client = require_client();
|
|
59984
59984
|
var { buildMockDispatch } = require_mock_utils();
|
|
59985
59985
|
var {
|
|
@@ -60027,7 +60027,7 @@ var require_mock_client = __commonJS({
|
|
|
60027
60027
|
this[kDispatches] = [];
|
|
60028
60028
|
}
|
|
60029
60029
|
async [kClose]() {
|
|
60030
|
-
await
|
|
60030
|
+
await promisify2(this[kOriginalClose])();
|
|
60031
60031
|
this[kConnected] = 0;
|
|
60032
60032
|
this[kMockAgent][Symbols.kClients].delete(this[kOrigin]);
|
|
60033
60033
|
}
|
|
@@ -60240,7 +60240,7 @@ var require_mock_call_history = __commonJS({
|
|
|
60240
60240
|
var require_mock_pool = __commonJS({
|
|
60241
60241
|
"node_modules/undici/lib/mock/mock-pool.js"(exports, module) {
|
|
60242
60242
|
"use strict";
|
|
60243
|
-
var { promisify } = __require("node:util");
|
|
60243
|
+
var { promisify: promisify2 } = __require("node:util");
|
|
60244
60244
|
var Pool = require_pool();
|
|
60245
60245
|
var { buildMockDispatch } = require_mock_utils();
|
|
60246
60246
|
var {
|
|
@@ -60288,7 +60288,7 @@ var require_mock_pool = __commonJS({
|
|
|
60288
60288
|
this[kDispatches] = [];
|
|
60289
60289
|
}
|
|
60290
60290
|
async [kClose]() {
|
|
60291
|
-
await
|
|
60291
|
+
await promisify2(this[kOriginalClose])();
|
|
60292
60292
|
this[kConnected] = 0;
|
|
60293
60293
|
this[kMockAgent][Symbols.kClients].delete(this[kOrigin]);
|
|
60294
60294
|
}
|
|
@@ -73563,6 +73563,8 @@ import {
|
|
|
73563
73563
|
resolveRetryPolicy
|
|
73564
73564
|
} from "@deepseek-ai/dsh-llm";
|
|
73565
73565
|
import { idleWatchdog, timeoutOf } from "@deepseek-ai/dsh-timeout";
|
|
73566
|
+
import { promisify } from "node:util";
|
|
73567
|
+
import { constants as zlibConstants, gzip as gzipCallback } from "node:zlib";
|
|
73566
73568
|
|
|
73567
73569
|
// src/catalog/index.ts
|
|
73568
73570
|
init_models();
|
|
@@ -75757,6 +75759,10 @@ var fields = {
|
|
|
75757
75759
|
maxTokens: Schema.union([Schema.const(null), Schema.number().step(1).min(1).max(Number.MAX_SAFE_INTEGER)])
|
|
75758
75760
|
})])).default({}),
|
|
75759
75761
|
modelProtocols: Schema.dict(Schema.string()).default({}),
|
|
75762
|
+
// On by default, off is the whole fallback plan: if the gateway ever
|
|
75763
|
+
// rejects a compressed body, one switch returns every request to plain
|
|
75764
|
+
// JSON with no other change.
|
|
75765
|
+
requestGzip: Schema.boolean().default(true),
|
|
75760
75766
|
// On by default: recording costs one call and one boolean per request
|
|
75761
75767
|
// plus a bounded ring, and buys a per-request trail whenever something
|
|
75762
75768
|
// looks wrong. Off returns the request path to exactly as without the
|
|
@@ -76610,6 +76616,21 @@ function bodyBytes(body) {
|
|
|
76610
76616
|
if (ArrayBuffer.isView(body)) return body.byteLength;
|
|
76611
76617
|
return void 0;
|
|
76612
76618
|
}
|
|
76619
|
+
var MIN_GZIP_BODY_BYTES = 1024;
|
|
76620
|
+
var gzipAsync = promisify(gzipCallback);
|
|
76621
|
+
async function gzipBody(armed, input, init) {
|
|
76622
|
+
const original = init?.body;
|
|
76623
|
+
const originalBytes = bodyBytes(original ?? void 0);
|
|
76624
|
+
if (!armed || typeof input !== "string" && !(input instanceof URL) || originalBytes === void 0 || originalBytes < MIN_GZIP_BODY_BYTES || typeof original !== "string" && !(original instanceof ArrayBuffer) && !ArrayBuffer.isView(original)) {
|
|
76625
|
+
return { body: original ?? null, bytes: originalBytes, headers: void 0 };
|
|
76626
|
+
}
|
|
76627
|
+
const bytes = typeof original === "string" ? Buffer.from(original) : original instanceof ArrayBuffer ? Buffer.from(original) : Buffer.from(original.buffer, original.byteOffset, original.byteLength);
|
|
76628
|
+
const compressed = await gzipAsync(bytes, { level: zlibConstants.Z_BEST_SPEED });
|
|
76629
|
+
const headers = new Headers(init?.headers);
|
|
76630
|
+
headers.delete("content-length");
|
|
76631
|
+
headers.set("content-encoding", "gzip");
|
|
76632
|
+
return { body: compressed, bytes: compressed.byteLength, headers };
|
|
76633
|
+
}
|
|
76613
76634
|
async function* observingTerminalUsage(events, observe) {
|
|
76614
76635
|
for await (const event of events) {
|
|
76615
76636
|
if (event.type === "done") observe(event.message.usage);
|
|
@@ -76795,12 +76816,17 @@ var OpencodeGoAdapter = class extends LlmAdapter {
|
|
|
76795
76816
|
}
|
|
76796
76817
|
});
|
|
76797
76818
|
const fetchFactory = this.options.fetch;
|
|
76798
|
-
const requestFetch =
|
|
76819
|
+
const requestFetch = fetchFactory === void 0 || span === void 0 && !config.requestGzip ? fetchFactory : () => {
|
|
76799
76820
|
const base = fetchFactory();
|
|
76800
76821
|
return (async (input, init) => {
|
|
76801
|
-
const
|
|
76802
|
-
|
|
76803
|
-
|
|
76822
|
+
const outgoing = await gzipBody(config.requestGzip, input, init);
|
|
76823
|
+
const response = await base(input, {
|
|
76824
|
+
...init,
|
|
76825
|
+
...outgoing.body === void 0 ? {} : { body: outgoing.body },
|
|
76826
|
+
...outgoing.headers === void 0 ? {} : { headers: outgoing.headers }
|
|
76827
|
+
});
|
|
76828
|
+
span?.request(typeof init?.method === "string" ? init.method : "POST", requestUrl(input), outgoing.bytes);
|
|
76829
|
+
span?.status(response.status);
|
|
76804
76830
|
return response;
|
|
76805
76831
|
});
|
|
76806
76832
|
};
|
|
@@ -77925,7 +77951,7 @@ function createUpdateChecker(deps) {
|
|
|
77925
77951
|
}
|
|
77926
77952
|
|
|
77927
77953
|
// src/update/version.ts
|
|
77928
|
-
var PLUGIN_VERSION = true ? "0.1.
|
|
77954
|
+
var PLUGIN_VERSION = true ? "0.1.70" : "0.0.0-dev";
|
|
77929
77955
|
|
|
77930
77956
|
// src/update/service.ts
|
|
77931
77957
|
import { TypertRemoteService as TypertRemoteService4 } from "@deepseek-ai/dsh-typert-protocol";
|
package/lib/types/config.d.ts
CHANGED
|
@@ -75,6 +75,14 @@ export interface OpencodeGoConfig {
|
|
|
75
75
|
* The escape hatch for a model whose family rule guessed wrong.
|
|
76
76
|
*/
|
|
77
77
|
modelProtocols: Record<string, string>;
|
|
78
|
+
/**
|
|
79
|
+
* Whether JSON request bodies of 1 KB or more are gzip-compressed before
|
|
80
|
+
* sending. On by default: the gateway is expected to accept
|
|
81
|
+
* `Content-Encoding: gzip`, and small bodies are never worth the overhead.
|
|
82
|
+
* If the gateway ever rejects compressed bodies, turn this off — the
|
|
83
|
+
* off switch is the whole fallback plan.
|
|
84
|
+
*/
|
|
85
|
+
requestGzip: boolean;
|
|
78
86
|
/**
|
|
79
87
|
* Whether the request log records anything at all. On by default: one
|
|
80
88
|
* call and one boolean per request, plus a bounded ring. Off returns the
|
package/package.json
CHANGED