@klarkxy/dsh-plugin-kit 0.5.0 → 0.6.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.md CHANGED
@@ -4,9 +4,7 @@
4
4
 
5
5
  [简体中文](docs/README.zh-CN.md)
6
6
 
7
- A shared library used by the plugins in this repository. It adds no feature of its own and does not need to be installed separately; plugins that need it install it automatically.
8
-
9
- For plugin developers, the source code and type declarations are the reference.
7
+ A shared support library for the plugins in this repository, including the default auxiliary model and independent feature contexts. Plugins that depend on it install it automatically; refer to the source code and type declarations.
10
8
 
11
9
  ## License
12
10
 
@@ -4,9 +4,7 @@
4
4
 
5
5
  [English](../README.md)
6
6
 
7
- 本仓库插件共用的支撑库。它自身不提供功能,也不需要单独安装;需要它的插件会自动带上。
8
-
9
- 插件开发者请直接参考源码和类型声明。
7
+ 本仓库插件共用的支撑库,提供默认辅助模型、独立功能上下文等共享能力,依赖它的插件会自动安装;具体接口参见源码和类型声明。
10
8
 
11
9
  ## 许可证
12
10
 
@@ -0,0 +1,42 @@
1
+ //#region src/auxiliary-context.d.ts
2
+ /**
3
+ * Auxiliary request-context packing for feature model calls.
4
+ *
5
+ * A feature may prepend stable material (session facts, its own durable
6
+ * records) to the live request so provider-side caching reuses one prefix.
7
+ * Three invariants keep this honest and testable:
8
+ *
9
+ * - Material is rebuilt by the caller from current facts on every call;
10
+ * nothing here stores, accumulates or replays model outputs.
11
+ * - Order is caller-owned: stable material first, live request last.
12
+ * - A context that exceeds its byte budget fails loudly instead of
13
+ * silently dropping evidence.
14
+ *
15
+ * Pure and browser-safe: no host imports.
16
+ */
17
+ /** Thrown when packed context exceeds the caller's byte budget. */
18
+ declare class AuxiliaryContextTooLargeError extends Error {
19
+ readonly bytes: number;
20
+ readonly maxBytes: number;
21
+ constructor(bytes: number, maxBytes: number);
22
+ }
23
+ /**
24
+ * Join stable material segments for one request. The packed text must fit
25
+ * `maxBytes` or the call throws — the caller decides what to drop, so
26
+ * evidence is never silently truncated. Empty input packs to ''.
27
+ */
28
+ declare function packAuxiliaryContext(segments: readonly string[], maxBytes: number): string;
29
+ /**
30
+ * Assemble the single user message for an auxiliary model call: stable
31
+ * material in one labelled block first, the live request last. With no
32
+ * context the result is byte-identical to `text`, so callers without
33
+ * material keep exactly the previous wire shape.
34
+ */
35
+ declare function buildAuxiliaryUserText(request: {
36
+ feature?: string;
37
+ context?: string | readonly string[];
38
+ text: string;
39
+ }): string;
40
+ //#endregion
41
+ export { AuxiliaryContextTooLargeError, buildAuxiliaryUserText, packAuxiliaryContext };
42
+ //# sourceMappingURL=auxiliary-context.d.ts.map
@@ -0,0 +1,65 @@
1
+ //#region src/auxiliary-context.ts
2
+ /**
3
+ * Auxiliary request-context packing for feature model calls.
4
+ *
5
+ * A feature may prepend stable material (session facts, its own durable
6
+ * records) to the live request so provider-side caching reuses one prefix.
7
+ * Three invariants keep this honest and testable:
8
+ *
9
+ * - Material is rebuilt by the caller from current facts on every call;
10
+ * nothing here stores, accumulates or replays model outputs.
11
+ * - Order is caller-owned: stable material first, live request last.
12
+ * - A context that exceeds its byte budget fails loudly instead of
13
+ * silently dropping evidence.
14
+ *
15
+ * Pure and browser-safe: no host imports.
16
+ */
17
+ /** Thrown when packed context exceeds the caller's byte budget. */
18
+ var AuxiliaryContextTooLargeError = class extends Error {
19
+ bytes;
20
+ maxBytes;
21
+ constructor(bytes, maxBytes) {
22
+ super(`Auxiliary context is ${bytes} bytes, over the ${maxBytes}-byte budget.`);
23
+ this.name = "AuxiliaryContextTooLargeError";
24
+ this.bytes = bytes;
25
+ this.maxBytes = maxBytes;
26
+ }
27
+ };
28
+ const utf8 = new TextEncoder();
29
+ function byteLength(text) {
30
+ return utf8.encode(text).byteLength;
31
+ }
32
+ function normalizeSegments(context) {
33
+ if (context === void 0) return [];
34
+ return (typeof context === "string" ? [context] : context).filter((segment) => typeof segment === "string" && segment.length > 0);
35
+ }
36
+ /**
37
+ * Join stable material segments for one request. The packed text must fit
38
+ * `maxBytes` or the call throws — the caller decides what to drop, so
39
+ * evidence is never silently truncated. Empty input packs to ''.
40
+ */
41
+ function packAuxiliaryContext(segments, maxBytes) {
42
+ if (!Number.isSafeInteger(maxBytes) || maxBytes <= 0) throw new Error("Invalid auxiliary context budget");
43
+ const text = normalizeSegments(segments).join("\n");
44
+ if (byteLength(text) > maxBytes) throw new AuxiliaryContextTooLargeError(byteLength(text), maxBytes);
45
+ return text;
46
+ }
47
+ /** Only word characters, dots, colons and dashes are kept inside the feature attribute. */
48
+ function featureAttribute(feature) {
49
+ return feature.replaceAll(/[^\w.:-]/g, "_");
50
+ }
51
+ /**
52
+ * Assemble the single user message for an auxiliary model call: stable
53
+ * material in one labelled block first, the live request last. With no
54
+ * context the result is byte-identical to `text`, so callers without
55
+ * material keep exactly the previous wire shape.
56
+ */
57
+ function buildAuxiliaryUserText(request) {
58
+ const context = normalizeSegments(request.context);
59
+ if (!context.length) return request.text;
60
+ return `<auxiliary-context${request.feature ? ` feature="${featureAttribute(request.feature)}"` : ""}>\n${context.join("\n")}\n</auxiliary-context>\n<request>\n${request.text}\n</request>`;
61
+ }
62
+ //#endregion
63
+ export { AuxiliaryContextTooLargeError, buildAuxiliaryUserText, packAuxiliaryContext };
64
+
65
+ //# sourceMappingURL=auxiliary-context.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"auxiliary-context.js","names":[],"sources":["../src/auxiliary-context.ts"],"sourcesContent":["/**\n * Auxiliary request-context packing for feature model calls.\n *\n * A feature may prepend stable material (session facts, its own durable\n * records) to the live request so provider-side caching reuses one prefix.\n * Three invariants keep this honest and testable:\n *\n * - Material is rebuilt by the caller from current facts on every call;\n * nothing here stores, accumulates or replays model outputs.\n * - Order is caller-owned: stable material first, live request last.\n * - A context that exceeds its byte budget fails loudly instead of\n * silently dropping evidence.\n *\n * Pure and browser-safe: no host imports.\n */\n\n/** Thrown when packed context exceeds the caller's byte budget. */\nexport class AuxiliaryContextTooLargeError extends Error {\n readonly bytes: number\n readonly maxBytes: number\n constructor(bytes: number, maxBytes: number) {\n super(`Auxiliary context is ${bytes} bytes, over the ${maxBytes}-byte budget.`)\n this.name = 'AuxiliaryContextTooLargeError'\n this.bytes = bytes\n this.maxBytes = maxBytes\n }\n}\n\nconst utf8 = new TextEncoder()\n\nfunction byteLength(text: string): number {\n return utf8.encode(text).byteLength\n}\n\nfunction normalizeSegments(context: string | readonly string[] | undefined): readonly string[] {\n if (context === undefined) return []\n const list: readonly string[] = typeof context === 'string' ? [context] : context\n return list.filter(segment => typeof segment === 'string' && segment.length > 0)\n}\n\n/**\n * Join stable material segments for one request. The packed text must fit\n * `maxBytes` or the call throws — the caller decides what to drop, so\n * evidence is never silently truncated. Empty input packs to ''.\n */\nexport function packAuxiliaryContext(segments: readonly string[], maxBytes: number): string {\n if (!Number.isSafeInteger(maxBytes) || maxBytes <= 0) throw new Error('Invalid auxiliary context budget')\n const text = normalizeSegments(segments).join('\\n')\n if (byteLength(text) > maxBytes) throw new AuxiliaryContextTooLargeError(byteLength(text), maxBytes)\n return text\n}\n\n/** Only word characters, dots, colons and dashes are kept inside the feature attribute. */\nfunction featureAttribute(feature: string): string {\n return feature.replaceAll(/[^\\w.:-]/g, '_')\n}\n\n/**\n * Assemble the single user message for an auxiliary model call: stable\n * material in one labelled block first, the live request last. With no\n * context the result is byte-identical to `text`, so callers without\n * material keep exactly the previous wire shape.\n */\nexport function buildAuxiliaryUserText(request: {\n feature?: string\n context?: string | readonly string[]\n text: string\n}): string {\n const context = normalizeSegments(request.context)\n if (!context.length) return request.text\n const attribute = request.feature ? ` feature=\"${featureAttribute(request.feature)}\"` : ''\n return `<auxiliary-context${attribute}>\\n${context.join('\\n')}\\n</auxiliary-context>\\n<request>\\n${request.text}\\n</request>`\n}\n"],"mappings":";;;;;;;;;;;;;;;;;AAiBA,IAAa,gCAAb,cAAmD,MAAM;CACvD;CACA;CACA,YAAY,OAAe,UAAkB;EAC3C,MAAM,wBAAwB,MAAM,mBAAmB,SAAS,cAAc;EAC9E,KAAK,OAAO;EACZ,KAAK,QAAQ;EACb,KAAK,WAAW;CAClB;AACF;AAEA,MAAM,OAAO,IAAI,YAAY;AAE7B,SAAS,WAAW,MAAsB;CACxC,OAAO,KAAK,OAAO,IAAI,CAAC,CAAC;AAC3B;AAEA,SAAS,kBAAkB,SAAoE;CAC7F,IAAI,YAAY,KAAA,GAAW,OAAO,CAAC;CAEnC,QADgC,OAAO,YAAY,WAAW,CAAC,OAAO,IAAI,QAAA,CAC9D,QAAO,YAAW,OAAO,YAAY,YAAY,QAAQ,SAAS,CAAC;AACjF;;;;;;AAOA,SAAgB,qBAAqB,UAA6B,UAA0B;CAC1F,IAAI,CAAC,OAAO,cAAc,QAAQ,KAAK,YAAY,GAAG,MAAM,IAAI,MAAM,kCAAkC;CACxG,MAAM,OAAO,kBAAkB,QAAQ,CAAC,CAAC,KAAK,IAAI;CAClD,IAAI,WAAW,IAAI,IAAI,UAAU,MAAM,IAAI,8BAA8B,WAAW,IAAI,GAAG,QAAQ;CACnG,OAAO;AACT;;AAGA,SAAS,iBAAiB,SAAyB;CACjD,OAAO,QAAQ,WAAW,aAAa,GAAG;AAC5C;;;;;;;AAQA,SAAgB,uBAAuB,SAI5B;CACT,MAAM,UAAU,kBAAkB,QAAQ,OAAO;CACjD,IAAI,CAAC,QAAQ,QAAQ,OAAO,QAAQ;CAEpC,OAAO,qBADW,QAAQ,UAAU,aAAa,iBAAiB,QAAQ,OAAO,EAAE,KAAK,GAClD,KAAK,QAAQ,KAAK,IAAI,EAAE,qCAAqC,QAAQ,KAAK;AAClH"}
@@ -0,0 +1,57 @@
1
+ import { AuxiliaryModelDefaults } from "./contracts.js";
2
+ import { ReactNode } from "react";
3
+ import { Context } from "@deepseek-ai/cordis";
4
+ //#region src/auxiliary-model-client.d.ts
5
+ /** The stored row; re-exported so card consumers share the contract shape. */
6
+ type AuxiliaryModelSnapshot = AuxiliaryModelDefaults;
7
+ declare const AUXILIARY_MODEL_SEAT_ID = "auxiliary-model";
8
+ declare const AUXILIARY_MODEL_SEAT_ORDER = 55;
9
+ /** Theme-token-only stylesheet: officialUiCss scope plus the shared ModelMenu recipe. */
10
+ declare const auxiliaryModelCss: string;
11
+ /** The client services this card reads; the shared service passes ctx.root. */
12
+ interface AuxiliaryModelClient {
13
+ connection: {
14
+ rpc: {
15
+ call(channel: string, endpoint: string, payload: unknown): Promise<unknown>;
16
+ };
17
+ generation?: {
18
+ subscribe(listener: () => void): () => void;
19
+ };
20
+ };
21
+ remote?: {
22
+ session?: {
23
+ modelCatalog?: () => Promise<unknown>;
24
+ };
25
+ };
26
+ locale?: {
27
+ getSnapshot(): {
28
+ active: string;
29
+ };
30
+ subscribe(listener: () => void): () => void;
31
+ };
32
+ }
33
+ /**
34
+ * The shared card. All state comes from the shared host service over the
35
+ * plugin-kit RPC channel; the card only renders the stored row.
36
+ */
37
+ declare function AuxiliaryModelCard({ client, subscribe }: {
38
+ client: AuxiliaryModelClient;
39
+ /** Settings-change invalidation; injected for tests without a live stream. */
40
+ subscribe?: (change: () => void, error?: (message: string) => void) => () => void;
41
+ }): ReactNode;
42
+ /**
43
+ * Show the shared "default auxiliary model" card while the calling plugin is
44
+ * enabled.
45
+ *
46
+ * `ctx` is the plugin's own client context: the card itself is retained on the
47
+ * shared root context for as long as any participant lives, so an arbitrary
48
+ * subset of enabled plugins yields the same single card. The mount's slot wait
49
+ * and the change-stream contribution are owned by the root service — the first
50
+ * participant's unload cannot take the card down. Returns a disposer; it may
51
+ * be invoked by both ctx.effect and an explicit caller and releases at most
52
+ * once, so a double call cannot unbalance the shared refcount.
53
+ */
54
+ declare function registerAuxiliaryModelSettings(ctx: Context): () => void;
55
+ //#endregion
56
+ export { AUXILIARY_MODEL_SEAT_ID, AUXILIARY_MODEL_SEAT_ORDER, AuxiliaryModelCard, AuxiliaryModelClient, AuxiliaryModelSnapshot, auxiliaryModelCss, registerAuxiliaryModelSettings };
57
+ //# sourceMappingURL=auxiliary-model-client.d.ts.map