dsh-model-input-toggle 0.0.0-stage → 1.0.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/package.json CHANGED
@@ -1,6 +1,50 @@
1
1
  {
2
2
  "name": "dsh-model-input-toggle",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "1.0.0",
4
+ "description": "在「设置 → 模型」页面为每个模型直接开关图片输入声明(llm-pi-ai 的 input / llm-deepseek 的 inputModalities),并提供端点实际能力验证。",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "main": "lib/index.js",
8
+ "exports": {
9
+ ".": "./lib/index.js",
10
+ "./client": "./lib/client.js",
11
+ "./package.json": "./package.json"
12
+ },
13
+ "files": [
14
+ "lib/index.js",
15
+ "lib/client.js",
16
+ "tools/verify-endpoint.mjs",
17
+ "tools/test.mjs",
18
+ "tools/test-host.mjs",
19
+ "tools/test-client.mjs",
20
+ "tools/settings-semantics.mjs",
21
+ "cordis.patch.yml",
22
+ "README.md"
23
+ ],
24
+ "bin": {
25
+ "dsh-verify-model-image": "./tools/verify-endpoint.mjs"
26
+ },
27
+ "scripts": {
28
+ "test": "node tools/test.mjs",
29
+ "verify": "node tools/verify-endpoint.mjs"
30
+ },
31
+ "engines": {
32
+ "node": ">=18"
33
+ },
34
+ "dsh": {
35
+ "bundle": {
36
+ "patch": "./cordis.patch.yml"
37
+ },
38
+ "client": {
39
+ "inject": [
40
+ "@deepseek-ai/dsh-client-ui-renderer"
41
+ ],
42
+ "platform": "web",
43
+ "immediately": true
44
+ }
45
+ },
46
+ "peerDependencies": {
47
+ "@deepseek-ai/cordis": "^4.0.1",
48
+ "react": "^18.2.0"
49
+ }
50
+ }
@@ -0,0 +1,68 @@
1
+ /**
2
+ * Reimplementation of the two dsh-settings internals that decide whether a
3
+ * write is correct, copied in behaviour from the shipped source so a test can
4
+ * prove the plugin's mutate ops do what it claims without mounting a host.
5
+ *
6
+ * - `applyPathOp` : `packages/host/settings/src/index.ts` — note that it only
7
+ * descends into PLAIN OBJECTS. An array-valued child is
8
+ * terminal, which is exactly why the plugin never puts an
9
+ * array index in a path.
10
+ * - `mergeLayers` : the resolved-value merge. Plain objects merge recursively;
11
+ * every other value, arrays included, replaces wholesale.
12
+ */
13
+
14
+ function isPlainObject(value) {
15
+ if (typeof value !== "object" || value === null || Array.isArray(value)) return false;
16
+ const proto = Object.getPrototypeOf(value);
17
+ return proto === Object.prototype || proto === null;
18
+ }
19
+
20
+ /** Apply one path op to a detached section, returning the next section. */
21
+ export function applyPathOp(section, op) {
22
+ const [head, ...rest] = op.path;
23
+ if (head === void 0) {
24
+ if (op.op === "unset") return {};
25
+ if (!isPlainObject(op.value)) throw new TypeError("settings mutate: setting the section root requires a plain object");
26
+ return { ...op.value };
27
+ }
28
+ if (rest.length === 0) {
29
+ if (op.op === "set") return { ...section, [head]: op.value };
30
+ const { [head]: _removed, ...kept } = section;
31
+ return kept;
32
+ }
33
+ const child = section[head];
34
+ if (!isPlainObject(child)) {
35
+ if (op.op === "unset") return section;
36
+ return { ...section, [head]: applyPathOp({}, { ...op, path: rest }) };
37
+ }
38
+ return { ...section, [head]: applyPathOp(child, { ...op, path: rest }) };
39
+ }
40
+
41
+ /** Apply an ordered op list. */
42
+ export function applyPathOps(section, ops) {
43
+ return ops.reduce((current, op) => applyPathOp(current, op), section);
44
+ }
45
+
46
+ /** Merge a lower and an upper layer with the shipped semantics. */
47
+ export function mergeLayers(under, over) {
48
+ if (over === void 0) return under;
49
+ if (!isPlainObject(under) || !isPlainObject(over)) return over;
50
+ const merged = { ...under };
51
+ for (const [key, value] of Object.entries(over)) {
52
+ merged[key] = key in merged ? mergeLayers(merged[key], value) : value;
53
+ }
54
+ return merged;
55
+ }
56
+
57
+ /** Throw when a value is not structurally what the caller expects (assertions). */
58
+ export function assert(condition, message) {
59
+ if (!condition) throw new Error(`assertion failed: ${message}`);
60
+ }
61
+
62
+ /** Deep structural equality over lossless JSON, with a path in the message. */
63
+ export function assertDeepEqual(actual, expected, label, path = "$") {
64
+ if (JSON.stringify(actual) === JSON.stringify(expected)) return;
65
+ throw new Error(
66
+ `${label}: mismatch at ${path}\n actual: ${JSON.stringify(actual)}\n expected: ${JSON.stringify(expected)}`
67
+ );
68
+ }