@yadsh/dsh-sleev 0.0.2 → 0.0.4
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 +1 -1
- package/README.zh-CN.md +1 -1
- package/compatibility.json +16 -0
- package/docs/development.md +1 -1
- package/lib/client.js +208 -142
- package/lib/index.js +40 -11
- package/lib/types/host/telemetry-store.d.ts +2 -2
- package/lib/types/index.d.ts +1 -0
- package/package.json +10 -5
package/README.md
CHANGED
|
@@ -10,7 +10,7 @@ Sleev routing observability for [DeepSeek Harness](https://github.com/deepseek-a
|
|
|
10
10
|
|
|
11
11
|
`dsh-sleev` observes provider routes that pass through the external Sleev context-optimization gateway. The current observer does not rewrite prompts, implement compaction, or route traffic itself: routing remains a normal `@deepseek-ai/dsh-llm-pi-ai` provider configuration.
|
|
12
12
|
|
|
13
|
-
[简体中文](README.zh-CN.md) · [Specification](
|
|
13
|
+
[简体中文](README.zh-CN.md) · [Specification](SPEC.md) · [Development guide](docs/development.md) · [Compatibility notes](docs/compatibility.md)
|
|
14
14
|
|
|
15
15
|
## Installation
|
|
16
16
|
|
package/README.zh-CN.md
CHANGED
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
`dsh-sleev` 用于观测经由外部 Sleev 上下文优化网关的提供商路由。当前观测器不会改写提示词、实现压缩或自行路由流量;路由仍由普通的 `@deepseek-ai/dsh-llm-pi-ai` 提供商配置负责。
|
|
12
12
|
|
|
13
|
-
[English](README.md) · [规范](
|
|
13
|
+
[English](README.md) · [规范](SPEC.md) · [开发指南](docs/development.md) · [兼容性说明](docs/compatibility.md)
|
|
14
14
|
|
|
15
15
|
## 安装
|
|
16
16
|
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{
|
|
2
|
+
"deepseekHarness": {
|
|
3
|
+
"channel": "next",
|
|
4
|
+
"range": ">=0.1.1-rc.2 <0.2.0",
|
|
5
|
+
"testedReleases": [
|
|
6
|
+
"0.1.1-rc.2"
|
|
7
|
+
],
|
|
8
|
+
"requiredHostFeatures": [
|
|
9
|
+
"llm/stream"
|
|
10
|
+
],
|
|
11
|
+
"requiredClientFeatures": [
|
|
12
|
+
"settings.plugin.item"
|
|
13
|
+
]
|
|
14
|
+
},
|
|
15
|
+
"node": "^22.19.0 || >=24.0.0"
|
|
16
|
+
}
|
package/docs/development.md
CHANGED
package/lib/client.js
CHANGED
|
@@ -4,9 +4,110 @@ window.__ModuleLoader__.load({
|
|
|
4
4
|
var module = { exports: {} };
|
|
5
5
|
var exports = module.exports;
|
|
6
6
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
7
|
+
let react_jsx_runtime = require("react/jsx-runtime");
|
|
7
8
|
let react = require("react");
|
|
8
9
|
let _deepseek_ai_dsh_client_runtime_client = require("@deepseek-ai/dsh-client-runtime/client");
|
|
9
|
-
|
|
10
|
+
//#region ../../packages/plugin-kit/lib/client/plugin-card-css.js
|
|
11
|
+
/**
|
|
12
|
+
* Canonical DSH settings-plugin card shell CSS — the single source of truth
|
|
13
|
+
* for the shared `dsh-plugin-card` outer shell (see AGENTS.md). Plugins must
|
|
14
|
+
* inject this CSS unchanged and may only append rules for their own controls
|
|
15
|
+
* inside the card body; plugin-specific shell styling is forbidden.
|
|
16
|
+
*/
|
|
17
|
+
const PLUGIN_CARD_SHELL_CSS = `
|
|
18
|
+
.dsh-plugin-card{border:1px solid var(--dsw-alias-border-l2);background:var(--dsw-alias-bg-layer-3);border-radius:12px;list-style:none;transition:border-color .16s,background .16s}
|
|
19
|
+
.dsh-plugin-card:hover{border-color:var(--dsw-alias-label-dimmed)}
|
|
20
|
+
.dsh-plugin-card--open{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-label-dimmed)}
|
|
21
|
+
.dsh-plugin-card__header{appearance:none;width:100%;font:inherit;color:inherit;text-align:left;cursor:pointer;background:0 0;border:0;border-radius:12px;align-items:center;gap:12px;padding:14px 16px;display:flex}
|
|
22
|
+
.dsh-plugin-card__header:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:-2px}
|
|
23
|
+
.dsh-plugin-card__head-text{flex-direction:column;flex:1;gap:4px;min-width:0;display:flex}
|
|
24
|
+
.dsh-plugin-card__name{color:var(--dsw-alias-label-primary);font-size:15px;font-weight:600;line-height:1.4}
|
|
25
|
+
.dsh-plugin-card__description{color:var(--dsw-alias-label-tertiary);font-size:13px;line-height:1.5}
|
|
26
|
+
.dsh-plugin-card__badge{white-space:nowrap;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);border-radius:999px;flex:none;padding:1px 8px;font-size:11px;font-weight:500;line-height:17px}
|
|
27
|
+
.dsh-plugin-card__chevron{width:14px;height:14px;color:var(--dsw-alias-label-tertiary);flex:none;transition:transform .16s}
|
|
28
|
+
.dsh-plugin-card--open .dsh-plugin-card__chevron{transform:rotate(180deg)}
|
|
29
|
+
.dsh-plugin-card__body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding-bottom:8px}
|
|
30
|
+
`;
|
|
31
|
+
//#endregion
|
|
32
|
+
//#region ../../packages/plugin-kit/lib/client/chevron.js
|
|
33
|
+
/**
|
|
34
|
+
* The standard disclosure chevron of the shared settings-card shell: a
|
|
35
|
+
* 14x14 inline SVG stroked with `currentColor` (round caps and joins).
|
|
36
|
+
* Font glyphs must not be used for this shape — their appearance and
|
|
37
|
+
* baseline vary by font and encoding.
|
|
38
|
+
*/
|
|
39
|
+
function ChevronDown() {
|
|
40
|
+
return (0, react_jsx_runtime.jsx)("svg", {
|
|
41
|
+
className: "dsh-plugin-card__chevron",
|
|
42
|
+
viewBox: "0 0 14 14",
|
|
43
|
+
fill: "none",
|
|
44
|
+
"aria-hidden": "true",
|
|
45
|
+
children: (0, react_jsx_runtime.jsx)("path", {
|
|
46
|
+
d: "m3.5 5.25 3.5 3.5 3.5-3.5",
|
|
47
|
+
stroke: "currentColor",
|
|
48
|
+
strokeLinecap: "round",
|
|
49
|
+
strokeLinejoin: "round"
|
|
50
|
+
})
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
//#endregion
|
|
54
|
+
//#region ../../packages/plugin-kit/lib/client/card-shell.js
|
|
55
|
+
/**
|
|
56
|
+
* Shared outer shell of a plugin configuration card (AGENTS.md contract): a
|
|
57
|
+
* direct `<li>` child of the host list with a full-width header button
|
|
58
|
+
* (`type="button"`, `aria-expanded`, accessible show/hide label, the
|
|
59
|
+
* title/description stack, an optional status badge, then the chevron) and a
|
|
60
|
+
* body rendered only while open. Plugin-specific controls belong inside the
|
|
61
|
+
* body and must not restyle the shell.
|
|
62
|
+
*/
|
|
63
|
+
function CardShell(props) {
|
|
64
|
+
const [open, setOpen] = (0, react.useState)(false);
|
|
65
|
+
const body = props.bodyClassName === void 0 ? "dsh-plugin-card__body" : `dsh-plugin-card__body ${props.bodyClassName}`;
|
|
66
|
+
return (0, react_jsx_runtime.jsxs)("li", {
|
|
67
|
+
className: open ? "dsh-plugin-card dsh-plugin-card--open" : "dsh-plugin-card",
|
|
68
|
+
children: [(0, react_jsx_runtime.jsxs)("button", {
|
|
69
|
+
type: "button",
|
|
70
|
+
className: "dsh-plugin-card__header",
|
|
71
|
+
"aria-expanded": open,
|
|
72
|
+
"aria-label": props.label(open),
|
|
73
|
+
onClick: () => {
|
|
74
|
+
setOpen(!open);
|
|
75
|
+
},
|
|
76
|
+
children: [
|
|
77
|
+
(0, react_jsx_runtime.jsxs)("span", {
|
|
78
|
+
className: "dsh-plugin-card__head-text",
|
|
79
|
+
children: [(0, react_jsx_runtime.jsx)("span", {
|
|
80
|
+
className: "dsh-plugin-card__name",
|
|
81
|
+
children: props.title
|
|
82
|
+
}), (0, react_jsx_runtime.jsx)("span", {
|
|
83
|
+
className: "dsh-plugin-card__description",
|
|
84
|
+
children: props.description
|
|
85
|
+
})]
|
|
86
|
+
}),
|
|
87
|
+
props.badge ?? null,
|
|
88
|
+
(0, react_jsx_runtime.jsx)(ChevronDown, {})
|
|
89
|
+
]
|
|
90
|
+
}), open ? (0, react_jsx_runtime.jsx)("div", {
|
|
91
|
+
className: body,
|
|
92
|
+
children: props.children
|
|
93
|
+
}) : null]
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Register the card component into the shared settings-plugins slot. Returns
|
|
98
|
+
* the registration disposer. Use this variant when the plugin drives the
|
|
99
|
+
* slot's inject-factory itself (e.g. to dispose a form controller alongside).
|
|
100
|
+
*/
|
|
101
|
+
function registerSettingsSlot(host, options) {
|
|
102
|
+
const slotOptions = {
|
|
103
|
+
name: options.slotName ?? "settings.plugin.item",
|
|
104
|
+
key: options.key,
|
|
105
|
+
...options.locale === void 0 ? {} : { locale: options.locale },
|
|
106
|
+
...options.inject === void 0 ? {} : { inject: options.inject }
|
|
107
|
+
};
|
|
108
|
+
return host.slots.register(slotOptions, options.component);
|
|
109
|
+
}
|
|
110
|
+
//#endregion
|
|
10
111
|
//#region src/client/settings-controller.ts
|
|
11
112
|
const DEFAULTS = {
|
|
12
113
|
routes: [],
|
|
@@ -239,18 +340,8 @@ window.__ModuleLoader__.load({
|
|
|
239
340
|
save: "保存",
|
|
240
341
|
saving: "保存中…"
|
|
241
342
|
};
|
|
242
|
-
const CARD_STYLES =
|
|
243
|
-
.dsh-sleev-
|
|
244
|
-
.dsh-sleev-card:hover{border-color:var(--dsw-alias-border-label-dimmed)}
|
|
245
|
-
.dsh-sleev-card.dsh-sleev-card-open{background:var(--dsw-alias-bg-layer-2);border-color:var(--dsw-alias-border-label-dimmed)}
|
|
246
|
-
.dsh-sleev-header{width:100%;appearance:none;border:0;background:none;font:inherit;color:inherit;text-align:left;cursor:pointer;display:flex;align-items:center;gap:12px;padding:14px 16px;border-radius:12px}
|
|
247
|
-
.dsh-sleev-header:focus-visible,.dsh-sleev-button:focus-visible,.dsh-sleev-reset:focus-visible,.dsh-sleev-input:focus-visible{outline:2px solid var(--dsw-alias-border-brand);outline-offset:2px}
|
|
248
|
-
.dsh-sleev-head-text{flex:1;min-width:0;display:flex;flex-direction:column;gap:4px}
|
|
249
|
-
.dsh-sleev-name{font-size:15px;font-weight:600;line-height:1.4;color:var(--dsw-alias-label-primary)}
|
|
250
|
-
.dsh-sleev-description{font-size:13px;line-height:1.5;color:var(--dsw-alias-label-tertiary)}
|
|
251
|
-
.dsh-sleev-chevron{flex:none;color:var(--dsw-alias-label-tertiary);transition:transform .16s ease;font-size:16px;line-height:1}
|
|
252
|
-
.dsh-sleev-card-open .dsh-sleev-chevron{transform:rotate(180deg)}
|
|
253
|
-
.dsh-sleev-body{border-top:1px solid var(--dsw-alias-border-l2);margin:0 16px;padding-bottom:8px}
|
|
343
|
+
const CARD_STYLES = `${PLUGIN_CARD_SHELL_CSS}
|
|
344
|
+
.dsh-sleev-button:focus-visible,.dsh-sleev-reset:focus-visible,.dsh-sleev-input:focus-visible{outline:2px solid var(--dsw-alias-brand-primary);outline-offset:2px}
|
|
254
345
|
.dsh-sleev-read-only{margin:12px 0 0;font-size:12px;line-height:1.5;color:var(--dsw-alias-label-tertiary)}
|
|
255
346
|
.dsh-sleev-pill{border-radius:999px;padding:1px 8px;font-size:11px;line-height:17px;font-weight:500;background:var(--dsw-alias-bg-module-platform);color:var(--dsw-alias-label-secondary);white-space:nowrap}
|
|
256
347
|
.dsh-sleev-field{display:flex;flex-direction:column;gap:6px;padding:12px 0}
|
|
@@ -312,7 +403,6 @@ textarea.dsh-sleev-input{height:64px;min-height:48px;padding:8px 12px;resize:ver
|
|
|
312
403
|
}
|
|
313
404
|
/** Settings card contributed to the official Plugins → Plugin configuration tab. */
|
|
314
405
|
function SleevSettingsCard(props) {
|
|
315
|
-
const [open, setOpen] = (0, react.useState)(false);
|
|
316
406
|
const state = props.useSleevSettings((snapshot) => snapshot);
|
|
317
407
|
if (!state.available) return null;
|
|
318
408
|
const blocked = !state.dirty || state.invalid || state.saving || !state.writable;
|
|
@@ -324,140 +414,116 @@ textarea.dsh-sleev-input{height:64px;min-height:48px;padding:8px 12px;resize:ver
|
|
|
324
414
|
resetLabel: props.t("reset"),
|
|
325
415
|
onReset: () => props.resetField(field)
|
|
326
416
|
});
|
|
327
|
-
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
"
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
className: "dsh-sleev-pill",
|
|
348
|
-
children: props.t("unsaved")
|
|
349
|
-
}) : null,
|
|
350
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
351
|
-
className: "dsh-sleev-chevron",
|
|
352
|
-
"aria-hidden": "true",
|
|
353
|
-
children: "⌄"
|
|
354
|
-
})
|
|
355
|
-
]
|
|
356
|
-
}), open ? /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
357
|
-
className: "dsh-sleev-body",
|
|
358
|
-
children: [
|
|
359
|
-
!state.writable ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
360
|
-
className: "dsh-sleev-read-only",
|
|
361
|
-
role: "status",
|
|
362
|
-
children: props.t("readOnly")
|
|
363
|
-
}) : null,
|
|
364
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SettingsField, {
|
|
417
|
+
return /* @__PURE__ */ (0, react_jsx_runtime.jsxs)(CardShell, {
|
|
418
|
+
title: props.t("title"),
|
|
419
|
+
description: props.t("description"),
|
|
420
|
+
label: (open) => `${props.t(open ? "collapse" : "expand")}: Sleev`,
|
|
421
|
+
badge: state.dirty ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("span", {
|
|
422
|
+
className: "dsh-plugin-card__badge",
|
|
423
|
+
children: props.t("unsaved")
|
|
424
|
+
}) : void 0,
|
|
425
|
+
children: [
|
|
426
|
+
!state.writable ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
427
|
+
className: "dsh-sleev-read-only",
|
|
428
|
+
role: "status",
|
|
429
|
+
children: props.t("readOnly")
|
|
430
|
+
}) : null,
|
|
431
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SettingsField, {
|
|
432
|
+
id: "sleev-routes",
|
|
433
|
+
label: props.t("routes"),
|
|
434
|
+
hint: props.t("routesHint"),
|
|
435
|
+
...common("routes"),
|
|
436
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
|
|
365
437
|
id: "sleev-routes",
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(
|
|
438
|
+
className: "dsh-sleev-input",
|
|
439
|
+
value: state.routes.text,
|
|
440
|
+
disabled: !state.writable,
|
|
441
|
+
onChange: edit("routes")
|
|
442
|
+
})
|
|
443
|
+
}),
|
|
444
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SettingsField, {
|
|
445
|
+
id: "sleev-route-prefixes",
|
|
446
|
+
label: props.t("routePrefixes"),
|
|
447
|
+
hint: props.t("routePrefixesHint"),
|
|
448
|
+
...common("routePrefixes"),
|
|
449
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("textarea", {
|
|
378
450
|
id: "sleev-route-prefixes",
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
451
|
+
className: "dsh-sleev-input",
|
|
452
|
+
value: state.routePrefixes.text,
|
|
453
|
+
disabled: !state.writable,
|
|
454
|
+
onChange: edit("routePrefixes")
|
|
455
|
+
})
|
|
456
|
+
}),
|
|
457
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SettingsField, {
|
|
458
|
+
id: "sleev-max-recent-calls",
|
|
459
|
+
label: props.t("maxRecentCalls"),
|
|
460
|
+
hint: props.t("maxRecentCallsHint"),
|
|
461
|
+
invalidLabel: props.t("invalidNumber"),
|
|
462
|
+
...common("maxRecentCalls"),
|
|
463
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsx)("input", {
|
|
391
464
|
id: "sleev-max-recent-calls",
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SettingsField, {
|
|
465
|
+
className: "dsh-sleev-input",
|
|
466
|
+
type: "number",
|
|
467
|
+
min: 1,
|
|
468
|
+
step: 1,
|
|
469
|
+
value: state.maxRecentCalls.text,
|
|
470
|
+
disabled: !state.writable,
|
|
471
|
+
"aria-invalid": state.maxRecentCalls.invalid,
|
|
472
|
+
onChange: edit("maxRecentCalls")
|
|
473
|
+
})
|
|
474
|
+
}),
|
|
475
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)(SettingsField, {
|
|
476
|
+
id: "sleev-log-level",
|
|
477
|
+
label: props.t("logLevel"),
|
|
478
|
+
hint: props.t("logLevelHint"),
|
|
479
|
+
...common("logLevel"),
|
|
480
|
+
children: /* @__PURE__ */ (0, react_jsx_runtime.jsxs)("select", {
|
|
409
481
|
id: "sleev-log-level",
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
id: "sleev-log-level",
|
|
415
|
-
className: "dsh-sleev-input",
|
|
416
|
-
value: state.logLevel.text,
|
|
417
|
-
disabled: !state.writable,
|
|
418
|
-
onChange: edit("logLevel"),
|
|
419
|
-
children: [
|
|
420
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
421
|
-
value: "off",
|
|
422
|
-
children: props.t("logOff")
|
|
423
|
-
}),
|
|
424
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
425
|
-
value: "info",
|
|
426
|
-
children: props.t("logInfo")
|
|
427
|
-
}),
|
|
428
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
429
|
-
value: "debug",
|
|
430
|
-
children: props.t("logDebug")
|
|
431
|
-
})
|
|
432
|
-
]
|
|
433
|
-
})
|
|
434
|
-
}),
|
|
435
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
436
|
-
className: "dsh-sleev-footer",
|
|
482
|
+
className: "dsh-sleev-input",
|
|
483
|
+
value: state.logLevel.text,
|
|
484
|
+
disabled: !state.writable,
|
|
485
|
+
onChange: edit("logLevel"),
|
|
437
486
|
children: [
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
children: props.t("saveFailed")
|
|
442
|
-
}) : null,
|
|
443
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
444
|
-
type: "button",
|
|
445
|
-
className: "dsh-sleev-button dsh-sleev-discard",
|
|
446
|
-
disabled: !state.dirty || state.saving,
|
|
447
|
-
onClick: props.discard,
|
|
448
|
-
children: props.t("discard")
|
|
487
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
488
|
+
value: "off",
|
|
489
|
+
children: props.t("logOff")
|
|
449
490
|
}),
|
|
450
|
-
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
491
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
492
|
+
value: "info",
|
|
493
|
+
children: props.t("logInfo")
|
|
494
|
+
}),
|
|
495
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("option", {
|
|
496
|
+
value: "debug",
|
|
497
|
+
children: props.t("logDebug")
|
|
456
498
|
})
|
|
457
499
|
]
|
|
458
500
|
})
|
|
459
|
-
|
|
460
|
-
|
|
501
|
+
}),
|
|
502
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsxs)("div", {
|
|
503
|
+
className: "dsh-sleev-footer",
|
|
504
|
+
children: [
|
|
505
|
+
state.failed ? /* @__PURE__ */ (0, react_jsx_runtime.jsx)("p", {
|
|
506
|
+
className: "dsh-sleev-save-error",
|
|
507
|
+
role: "status",
|
|
508
|
+
children: props.t("saveFailed")
|
|
509
|
+
}) : null,
|
|
510
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
511
|
+
type: "button",
|
|
512
|
+
className: "dsh-sleev-button dsh-sleev-discard",
|
|
513
|
+
disabled: !state.dirty || state.saving,
|
|
514
|
+
onClick: props.discard,
|
|
515
|
+
children: props.t("discard")
|
|
516
|
+
}),
|
|
517
|
+
/* @__PURE__ */ (0, react_jsx_runtime.jsx)("button", {
|
|
518
|
+
type: "button",
|
|
519
|
+
className: "dsh-sleev-button dsh-sleev-save",
|
|
520
|
+
disabled: blocked,
|
|
521
|
+
onClick: props.save,
|
|
522
|
+
children: props.t(state.saving ? "saving" : "save")
|
|
523
|
+
})
|
|
524
|
+
]
|
|
525
|
+
})
|
|
526
|
+
]
|
|
461
527
|
});
|
|
462
528
|
}
|
|
463
529
|
const inject = [
|
|
@@ -480,12 +546,12 @@ textarea.dsh-sleev-input{height:64px;min-height:48px;padding:8px 12px;resize:ver
|
|
|
480
546
|
}), "dsh-sleev: settings dictionaries");
|
|
481
547
|
const controller = new SleevSettingsController(ctx.settingsScope.bind({ namespace: SETTINGS_NAMESPACE }));
|
|
482
548
|
ctx.slots.inject("settings.plugin.item", () => {
|
|
483
|
-
const unregister = ctx
|
|
484
|
-
name: "settings.plugin.item",
|
|
549
|
+
const unregister = registerSettingsSlot(ctx, {
|
|
485
550
|
key: SETTINGS_NAMESPACE,
|
|
486
551
|
locale: LOCALE_NAMESPACE,
|
|
552
|
+
component: SleevSettingsCard,
|
|
487
553
|
inject: () => controller.inject()
|
|
488
|
-
}
|
|
554
|
+
});
|
|
489
555
|
return () => {
|
|
490
556
|
controller.dispose();
|
|
491
557
|
unregister();
|
package/lib/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { Service } from "@deepseek-ai/cordis";
|
|
2
2
|
import { installSettingsSection, settingsNamespace } from "@deepseek-ai/dsh-settings";
|
|
3
|
+
import { createHostLoggerSink, getPluginLogger } from "@yadsh/dsh-plugin-log";
|
|
3
4
|
import z from "@deepseek-ai/schemastery";
|
|
4
5
|
import { isAgentLoopRequest } from "@deepseek-ai/dsh-llm";
|
|
5
6
|
import { randomUUID } from "node:crypto";
|
|
@@ -141,13 +142,12 @@ var CallTelemetryStore = class {
|
|
|
141
142
|
const startedAt = this.now();
|
|
142
143
|
let usage;
|
|
143
144
|
let finished = false;
|
|
144
|
-
if (startConfig.logLevel === "debug") this.logger.debug(
|
|
145
|
+
if (startConfig.logLevel === "debug") this.logger.debug("sleev.call.start", {
|
|
145
146
|
callId,
|
|
146
147
|
provider: options.provider,
|
|
147
148
|
model: options.model,
|
|
148
|
-
kind
|
|
149
|
-
|
|
150
|
-
})}`);
|
|
149
|
+
kind
|
|
150
|
+
});
|
|
151
151
|
return {
|
|
152
152
|
observeUsage: (value) => {
|
|
153
153
|
usage = normalizeUsage(value);
|
|
@@ -176,9 +176,20 @@ var CallTelemetryStore = class {
|
|
|
176
176
|
this.completed.push(telemetry);
|
|
177
177
|
const finishConfig = this.reconfigure();
|
|
178
178
|
if (finishConfig.logLevel !== "off") {
|
|
179
|
-
const
|
|
180
|
-
|
|
181
|
-
|
|
179
|
+
const fields = {
|
|
180
|
+
callId: telemetry.callId,
|
|
181
|
+
provider: telemetry.provider,
|
|
182
|
+
model: telemetry.model,
|
|
183
|
+
kind: telemetry.kind,
|
|
184
|
+
durationMs: telemetry.durationMs,
|
|
185
|
+
...telemetry.providerUsage === void 0 ? {} : {
|
|
186
|
+
providerUsage: telemetry.providerUsage,
|
|
187
|
+
derived: telemetry.derived
|
|
188
|
+
},
|
|
189
|
+
result: telemetry.result
|
|
190
|
+
};
|
|
191
|
+
if (finishConfig.logLevel === "debug") this.logger.debug("sleev.call.end", fields);
|
|
192
|
+
else this.logger.info("sleev.call.end", fields);
|
|
182
193
|
}
|
|
183
194
|
}
|
|
184
195
|
};
|
|
@@ -197,6 +208,9 @@ var CallTelemetryStore = class {
|
|
|
197
208
|
//#endregion
|
|
198
209
|
//#region src/index.ts
|
|
199
210
|
const name = "dsh-sleev";
|
|
211
|
+
function pluginLogLevel(level) {
|
|
212
|
+
return level === "off" ? "silent" : level;
|
|
213
|
+
}
|
|
200
214
|
/** User-editable settings section rendered by the browser client card. */
|
|
201
215
|
const SLEEV_SETTINGS_NAMESPACE = settingsNamespace(SLEEV_SETTINGS_NAMESPACE_ID);
|
|
202
216
|
/** Host-side observer service. Routing itself remains owned by llm-pi-ai. */
|
|
@@ -204,6 +218,7 @@ var SleevIntegrationService = class extends Service {
|
|
|
204
218
|
static inject = ["llm"];
|
|
205
219
|
static Config = ConfigSchema;
|
|
206
220
|
telemetry;
|
|
221
|
+
logger;
|
|
207
222
|
constructor(ctx, input = {}) {
|
|
208
223
|
super(ctx, "sleev");
|
|
209
224
|
const resolvedEntry = resolveConfig(input);
|
|
@@ -214,12 +229,26 @@ var SleevIntegrationService = class extends Service {
|
|
|
214
229
|
logLevel: resolvedEntry.logLevel
|
|
215
230
|
};
|
|
216
231
|
let configSource = () => entry;
|
|
217
|
-
this.
|
|
232
|
+
this.logger = getPluginLogger({
|
|
233
|
+
pluginId: "dsh-sleev",
|
|
234
|
+
level: pluginLogLevel(resolvedEntry.logLevel),
|
|
235
|
+
console: "trace",
|
|
236
|
+
consoleSink: createHostLoggerSink(ctx.logger)
|
|
237
|
+
});
|
|
238
|
+
ctx.effect(() => async () => this.logger.close(), "dsh-sleev.logger");
|
|
239
|
+
this.telemetry = new CallTelemetryStore(this.logger.child("telemetry"), () => resolveConfig(configSource()));
|
|
218
240
|
installSettingsSection(ctx, SLEEV_SETTINGS_NAMESPACE, ConfigSchema, entry, {
|
|
219
241
|
setSource: (current) => {
|
|
220
242
|
configSource = current;
|
|
221
243
|
},
|
|
222
|
-
onChange: () =>
|
|
244
|
+
onChange: () => {
|
|
245
|
+
const config = this.telemetry.reconfigure();
|
|
246
|
+
this.logger.setLevel(pluginLogLevel(config.logLevel));
|
|
247
|
+
this.logger.info("telemetry.config.updated", {
|
|
248
|
+
logLevel: config.logLevel,
|
|
249
|
+
maxRecentCalls: config.maxRecentCalls
|
|
250
|
+
});
|
|
251
|
+
}
|
|
223
252
|
});
|
|
224
253
|
ctx.on("llm/stream", (options, next) => {
|
|
225
254
|
const config = resolveConfig(configSource());
|
|
@@ -227,10 +256,10 @@ var SleevIntegrationService = class extends Service {
|
|
|
227
256
|
const handle = this.telemetry.begin(options, classifyRequest(options));
|
|
228
257
|
return observeStream(next(), handle);
|
|
229
258
|
}, { global: true });
|
|
230
|
-
if (resolvedEntry.logLevel !== "off")
|
|
259
|
+
if (resolvedEntry.logLevel !== "off") this.logger.info("plugin.ready", {
|
|
231
260
|
routes: resolvedEntry.routes,
|
|
232
261
|
routePrefixes: resolvedEntry.routePrefixes
|
|
233
|
-
})
|
|
262
|
+
});
|
|
234
263
|
}
|
|
235
264
|
/** Bounded completed-call snapshot; no prompts, headers, or credentials. */
|
|
236
265
|
listRecentCalls() {
|
|
@@ -3,8 +3,8 @@ import type { ResolvedConfig } from "../shared/config.js";
|
|
|
3
3
|
import type { CallResult, OptimizerCallTelemetry, RequestKind } from "../shared/telemetry.js";
|
|
4
4
|
/** Minimal logger face used by Cordis and isolated unit tests. */
|
|
5
5
|
export interface TelemetryLogger {
|
|
6
|
-
debug(
|
|
7
|
-
info(
|
|
6
|
+
debug(event: string, fields?: Record<string, unknown>): void;
|
|
7
|
+
info(event: string, fields?: Record<string, unknown>): void;
|
|
8
8
|
}
|
|
9
9
|
/** Mutable handle kept only for the duration of a streaming call. */
|
|
10
10
|
export interface CallHandle {
|
package/lib/types/index.d.ts
CHANGED
|
@@ -14,6 +14,7 @@ export declare class SleevIntegrationService extends Service {
|
|
|
14
14
|
static inject: string[];
|
|
15
15
|
static Config: import("@deepseek-ai/schemastery").default<Config>;
|
|
16
16
|
private readonly telemetry;
|
|
17
|
+
private readonly logger;
|
|
17
18
|
constructor(ctx: Context, input?: Config);
|
|
18
19
|
/** Bounded completed-call snapshot; no prompts, headers, or credentials. */
|
|
19
20
|
listRecentCalls(): readonly OptimizerCallTelemetry[];
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@yadsh/dsh-sleev",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.4",
|
|
4
4
|
"description": "Sleev routing observability for DeepSeek Harness",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -50,6 +50,7 @@
|
|
|
50
50
|
"lib/**/*.js",
|
|
51
51
|
"lib/types/**/*.d.ts",
|
|
52
52
|
"cordis.patch.yml",
|
|
53
|
+
"compatibility.json",
|
|
53
54
|
"docs/*",
|
|
54
55
|
"README.md",
|
|
55
56
|
"README.zh-CN.md",
|
|
@@ -79,10 +80,11 @@
|
|
|
79
80
|
"@deepseek-ai/dsh-settings": ">=0.1.1-rc.2 <0.2.0",
|
|
80
81
|
"react": "^18.2.0"
|
|
81
82
|
},
|
|
82
|
-
"dependencies": {
|
|
83
|
+
"dependencies": {
|
|
84
|
+
"@yadsh/dsh-plugin-log": "^0.2.1"
|
|
85
|
+
},
|
|
83
86
|
"devDependencies": {
|
|
84
87
|
"@deepseek-ai/cordis": "4.0.1",
|
|
85
|
-
"@deepseek-ai/schemastery": "3.18.1",
|
|
86
88
|
"@deepseek-ai/dsh-client-locale": "0.1.1-rc.2",
|
|
87
89
|
"@deepseek-ai/dsh-client-runtime": "0.1.1-rc.2",
|
|
88
90
|
"@deepseek-ai/dsh-client-ui-settings": "0.1.1-rc.2",
|
|
@@ -91,15 +93,18 @@
|
|
|
91
93
|
"@deepseek-ai/dsh-llm": "0.1.1-rc.2",
|
|
92
94
|
"@deepseek-ai/dsh-llm-pi-ai": "0.1.1-rc.2",
|
|
93
95
|
"@deepseek-ai/dsh-settings": "0.1.1-rc.2",
|
|
96
|
+
"@deepseek-ai/schemastery": "3.18.1",
|
|
94
97
|
"@types/node": "^26.4.0",
|
|
95
98
|
"@types/react": "18.3.28",
|
|
96
99
|
"eslint": "10.9.1",
|
|
97
100
|
"prettier": "^3.6.2",
|
|
98
101
|
"react": "18.3.1",
|
|
99
102
|
"tsdown": "^0.22.14",
|
|
100
|
-
"tsx": "4.22.4",
|
|
103
|
+
"tsx": "^4.22.4",
|
|
101
104
|
"typescript": "^7.0.2",
|
|
102
|
-
"vitest": "^4.1.11"
|
|
105
|
+
"vitest": "^4.1.11",
|
|
106
|
+
"@yadsh/dsh-plugin-kit": "^0.1.0",
|
|
107
|
+
"@yadsh/dsh-config": "^0.0.0"
|
|
103
108
|
},
|
|
104
109
|
"publishConfig": {
|
|
105
110
|
"access": "public",
|