@dickpy/dsh-imagegen 1.5.0 → 1.5.1
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/lib/client.js +321 -318
- package/lib/client.js.map +1 -1
- package/lib/index.js +29 -5
- package/package.json +23 -17
- package/src/client/ImageGenPanel.tsx +2 -1
- package/src/client/SettingsCard.tsx +1 -1
- package/src/client/channels-form.ts +1 -1
- package/src/client/conversation-sync.ts +1 -1
- package/src/client/image-toolview.tsx +16 -10
- package/src/client/index.ts +5 -4
- package/src/client/mount.tsx +1 -1
- package/src/client/settings-form.ts +2 -1
- package/src/client/settings-scope.ts +9 -5
- package/src/index.ts +3 -3
- package/src/protocol.ts +1 -1
- package/src/routes.ts +4 -2
- package/src/settings-compat.ts +60 -0
package/lib/index.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import
|
|
1
|
+
import * as settingsModule from "@deepseek-ai/dsh-settings";
|
|
2
|
+
import { SettingsConflictError } from "@deepseek-ai/dsh-settings";
|
|
2
3
|
import z from "schemastery";
|
|
3
4
|
import { createHash, randomUUID } from "node:crypto";
|
|
4
5
|
import { promises } from "node:fs";
|
|
@@ -7,6 +8,29 @@ import path from "node:path";
|
|
|
7
8
|
import { fileURLToPath } from "node:url";
|
|
8
9
|
import { spawn } from "node:child_process";
|
|
9
10
|
import { defineTool } from "@deepseek-ai/dsh-tools";
|
|
11
|
+
//#region src/settings-compat.ts
|
|
12
|
+
const compatModule = settingsModule;
|
|
13
|
+
/** Brand namespaces where the installed settings package still exposes it. */
|
|
14
|
+
function settingsNamespaceCompat(value) {
|
|
15
|
+
return compatModule.settingsNamespace?.(value) ?? value;
|
|
16
|
+
}
|
|
17
|
+
/**
|
|
18
|
+
* Register an optional settings section across the rc.7 and alpha.2 APIs.
|
|
19
|
+
* rc.7 exposes a module helper; alpha.2 moves the helper onto the provider.
|
|
20
|
+
*/
|
|
21
|
+
function installSettingsSectionCompat(ctx, ns, schema, entry, hooks) {
|
|
22
|
+
const legacyInstaller = compatModule.installSettingsSection;
|
|
23
|
+
if (legacyInstaller !== void 0) {
|
|
24
|
+
legacyInstaller(ctx, ns, schema, entry, hooks);
|
|
25
|
+
return;
|
|
26
|
+
}
|
|
27
|
+
ctx.inject(["settings"], (sctx) => {
|
|
28
|
+
const provider = sctx.get("settings");
|
|
29
|
+
if (provider.installSection === void 0) throw new TypeError("dsh-settings does not expose installSection");
|
|
30
|
+
provider.installSection(ctx, ns, schema, entry, hooks);
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
//#endregion
|
|
10
34
|
//#region src/protocol.ts
|
|
11
35
|
/**
|
|
12
36
|
* Wire contract shared by the host and client halves of dsh-imagegen: the
|
|
@@ -16,7 +40,7 @@ import { defineTool } from "@deepseek-ai/dsh-tools";
|
|
|
16
40
|
/** Settings namespace this plugin owns (host settings seam + bridge). */
|
|
17
41
|
const IMAGEGEN_SETTINGS_NAMESPACE = "dsh-imagegen";
|
|
18
42
|
/** Published package version shared by the host updater and the client UI. */
|
|
19
|
-
const PLUGIN_VERSION = "1.5.
|
|
43
|
+
const PLUGIN_VERSION = "1.5.1";
|
|
20
44
|
/** Same-origin route family (loopback-only, mirroring the dsh-ssh fence). */
|
|
21
45
|
const SETTINGS_API = {
|
|
22
46
|
describe: "/api/dsh-imagegen/settings/describe",
|
|
@@ -2312,7 +2336,7 @@ function makeRoutes(deps) {
|
|
|
2312
2336
|
}
|
|
2313
2337
|
const expectedRevision = typeof body.expectedRevision === "number" ? body.expectedRevision : void 0;
|
|
2314
2338
|
try {
|
|
2315
|
-
await deps.settings.mutate(
|
|
2339
|
+
await deps.settings.mutate(ns, body.ops, expectedRevision);
|
|
2316
2340
|
} catch (error) {
|
|
2317
2341
|
writeJson(res, 200, failureOf(error));
|
|
2318
2342
|
return;
|
|
@@ -3446,7 +3470,7 @@ const inject = [
|
|
|
3446
3470
|
"commands"
|
|
3447
3471
|
];
|
|
3448
3472
|
/** The branded settings namespace of this plugin (the card edits it). */
|
|
3449
|
-
const ImageGenSettingsNamespace =
|
|
3473
|
+
const ImageGenSettingsNamespace = settingsNamespaceCompat(IMAGEGEN_SETTINGS_NAMESPACE);
|
|
3450
3474
|
const Config = z.object({
|
|
3451
3475
|
enabled: z.boolean().default(true),
|
|
3452
3476
|
announceToAgent: z.boolean().default(true),
|
|
@@ -3656,7 +3680,7 @@ function apply(ctx, config) {
|
|
|
3656
3680
|
text: guidanceFor(value.channels, value.defaultChannelId)
|
|
3657
3681
|
});
|
|
3658
3682
|
};
|
|
3659
|
-
|
|
3683
|
+
installSettingsSectionCompat(ctx, ImageGenSettingsNamespace, Config, config ?? {}, {
|
|
3660
3684
|
setSource: (source) => {
|
|
3661
3685
|
current = source;
|
|
3662
3686
|
sync();
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@dickpy/dsh-imagegen",
|
|
3
3
|
"description": "AI image generation plugin for the dsh web GUI: text-to-image and image-to-image through configurable provider channels (gpt-image-2 / grok-imagine-image / nanobanana series / seedream-5.0-pro / dall-e-3, with native xAI Grok Imagine, Google Nano Banana and ByteDance Seedream request shaping), with per-channel model catalogs and a New Session / Image Generation tab entry opening a three-column studio beside the native conversation.",
|
|
4
|
-
"version": "1.5.
|
|
4
|
+
"version": "1.5.1",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "lib/index.js",
|
|
7
7
|
"exports": {
|
|
@@ -15,9 +15,12 @@
|
|
|
15
15
|
},
|
|
16
16
|
"client": {
|
|
17
17
|
"inject": [
|
|
18
|
-
"@deepseek-ai/dsh-client-
|
|
18
|
+
"@deepseek-ai/dsh-client-store",
|
|
19
|
+
"@deepseek-ai/dsh-api-remotes",
|
|
20
|
+
"@deepseek-ai/dsh-api-session-controller",
|
|
19
21
|
"@deepseek-ai/dsh-client-connection",
|
|
20
22
|
"@deepseek-ai/dsh-client-ui-conversation",
|
|
23
|
+
"@deepseek-ai/dsh-client-ui-renderer",
|
|
21
24
|
"@deepseek-ai/dsh-client-ui-settings",
|
|
22
25
|
"@deepseek-ai/dsh-client-ui-tool"
|
|
23
26
|
],
|
|
@@ -28,21 +31,24 @@
|
|
|
28
31
|
"schemastery": "^3.18.0"
|
|
29
32
|
},
|
|
30
33
|
"devDependencies": {
|
|
31
|
-
"@deepseek-ai/cordis": "^4.0.
|
|
32
|
-
"@deepseek-ai/dsh-
|
|
33
|
-
"@deepseek-ai/dsh-
|
|
34
|
-
"@deepseek-ai/dsh-
|
|
35
|
-
"@deepseek-ai/dsh-client-
|
|
36
|
-
"@deepseek-ai/dsh-client-
|
|
37
|
-
"@deepseek-ai/dsh-client-
|
|
38
|
-
"@deepseek-ai/dsh-client-ui-
|
|
39
|
-
"@deepseek-ai/dsh-client-ui-
|
|
40
|
-
"@deepseek-ai/dsh-
|
|
41
|
-
"@deepseek-ai/dsh-
|
|
42
|
-
"@deepseek-ai/dsh-
|
|
43
|
-
"@deepseek-ai/dsh-
|
|
44
|
-
"@deepseek-ai/dsh-
|
|
45
|
-
"@deepseek-ai/dsh-
|
|
34
|
+
"@deepseek-ai/cordis": "^4.0.2",
|
|
35
|
+
"@deepseek-ai/dsh-api-remotes": "0.1.2-alpha.2",
|
|
36
|
+
"@deepseek-ai/dsh-api-session-controller": "0.1.2-alpha.2",
|
|
37
|
+
"@deepseek-ai/dsh-attachment": "0.1.2-alpha.2",
|
|
38
|
+
"@deepseek-ai/dsh-client-connection": "0.1.2-alpha.2",
|
|
39
|
+
"@deepseek-ai/dsh-client-locale": "0.1.2-alpha.2",
|
|
40
|
+
"@deepseek-ai/dsh-client-store": "0.1.2-alpha.2",
|
|
41
|
+
"@deepseek-ai/dsh-client-ui-conversation": "0.1.2-alpha.2",
|
|
42
|
+
"@deepseek-ai/dsh-client-ui-primitives": "0.1.2-alpha.2",
|
|
43
|
+
"@deepseek-ai/dsh-client-ui-renderer": "0.1.2-alpha.2",
|
|
44
|
+
"@deepseek-ai/dsh-client-ui-settings": "0.1.2-alpha.2",
|
|
45
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.1.2-alpha.2",
|
|
46
|
+
"@deepseek-ai/dsh-commands": "0.1.2-alpha.2",
|
|
47
|
+
"@deepseek-ai/dsh-host-webserver": "0.1.2-alpha.2",
|
|
48
|
+
"@deepseek-ai/dsh-llm": "0.1.2-alpha.2",
|
|
49
|
+
"@deepseek-ai/dsh-settings": "0.1.2-alpha.2",
|
|
50
|
+
"@deepseek-ai/dsh-system-prompt": "0.1.2-alpha.2",
|
|
51
|
+
"@deepseek-ai/dsh-tools": "0.1.2-alpha.2",
|
|
46
52
|
"@types/node": "^22.20.0",
|
|
47
53
|
"@types/react": "~18.3.1",
|
|
48
54
|
"@types/react-dom": "^18.3.5",
|
|
@@ -11,7 +11,8 @@
|
|
|
11
11
|
import { useEffect, useRef, useState, type CSSProperties, type PointerEvent as ReactPointerEvent } from 'react'
|
|
12
12
|
import { createPortal } from 'react-dom'
|
|
13
13
|
import { Button, Pill } from '@deepseek-ai/dsh-client-ui-primitives'
|
|
14
|
-
import type {
|
|
14
|
+
import type { SessionId } from '@deepseek-ai/dsh-api-remotes/client'
|
|
15
|
+
import type { ISessions } from '@deepseek-ai/dsh-api-session-controller/client'
|
|
15
16
|
import type { ImageAttachmentRef } from '@deepseek-ai/dsh-attachment'
|
|
16
17
|
import type { ImageGenApi } from './api.ts'
|
|
17
18
|
import { errorMessage, tt } from './helpers.ts'
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
|
|
15
15
|
import { useEffect, useRef, useState } from 'react'
|
|
16
16
|
import type { InjectFace, PropsLocale, PropsRuntime } from '@deepseek-ai/dsh-client-ui-slots'
|
|
17
|
-
import { createSnapshotStore, type SnapshotStore } from '@deepseek-ai/dsh-client-
|
|
17
|
+
import { createSnapshotStore, type SnapshotStore } from '@deepseek-ai/dsh-client-store'
|
|
18
18
|
import { CardForm, booleanField, secretField, textField, type CardActions, type CardShell, type FieldState as CardFieldState } from './settings-form.ts'
|
|
19
19
|
import { ChannelsForm, type ChannelDraft, type ChannelsFormActions, type ChannelsFormState } from './channels-form.ts'
|
|
20
20
|
import type { ImageGenScope } from './settings-scope.ts'
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
* - path ops never navigate *inside* the channels array.
|
|
13
13
|
*/
|
|
14
14
|
|
|
15
|
-
import { createSnapshotStore, type SnapshotStore } from '@deepseek-ai/dsh-client-
|
|
15
|
+
import { createSnapshotStore, type SnapshotStore } from '@deepseek-ai/dsh-client-store'
|
|
16
16
|
import type { ChannelConfig, ModelMapping } from '../protocol.ts'
|
|
17
17
|
import type { ImageGenScope, SettingsOp } from './settings-scope.ts'
|
|
18
18
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ImageAttachmentRef } from '@deepseek-ai/dsh-attachment'
|
|
2
2
|
import type { ConversationController, IConversation } from '@deepseek-ai/dsh-client-ui-conversation/client'
|
|
3
|
-
import type { SessionId } from '@deepseek-ai/dsh-
|
|
3
|
+
import type { SessionId } from '@deepseek-ai/dsh-api-remotes/client'
|
|
4
4
|
|
|
5
5
|
/** Document event used to bridge chat tool results into the image workspace. */
|
|
6
6
|
export const CHAT_IMAGE_EVENT = 'dsh-imagegen:chat-images'
|
|
@@ -1,7 +1,10 @@
|
|
|
1
1
|
/** Inline renderer for image-generation tool-result attachments. */
|
|
2
2
|
|
|
3
3
|
import type { ImageAttachmentRef } from '@deepseek-ai/dsh-attachment'
|
|
4
|
-
import type {
|
|
4
|
+
import type { Context as ClientContext } from '@deepseek-ai/cordis'
|
|
5
|
+
import type { SessionId } from '@deepseek-ai/dsh-api-remotes/client'
|
|
6
|
+
import type { ToolCallBlock } from '@deepseek-ai/dsh-client-ui-conversation/client'
|
|
7
|
+
import type {} from '@deepseek-ai/dsh-client-ui-renderer/client'
|
|
5
8
|
import { useEffect, useMemo, useState } from 'react'
|
|
6
9
|
import { AGENT_IMAGE_API } from '../protocol.ts'
|
|
7
10
|
import { CHAT_IMAGE_EVENT } from './conversation-sync.ts'
|
|
@@ -31,10 +34,9 @@ function isSettled(block: ToolCallBlock): block is Extract<ToolCallBlock, { kind
|
|
|
31
34
|
return 'kind' in block
|
|
32
35
|
}
|
|
33
36
|
|
|
34
|
-
function imageRefsOf(block: ToolCallBlock): ImageAttachmentRef[] {
|
|
35
|
-
if (!isSettled(block)) return []
|
|
36
|
-
|
|
37
|
-
return [...block.content, ...resultContent]
|
|
37
|
+
function imageRefsOf(block: ToolCallBlock): ImageAttachmentRef[] {
|
|
38
|
+
if (!isSettled(block)) return []
|
|
39
|
+
return block.content
|
|
38
40
|
.flatMap(content => content.type === 'image' ? [content.attachment] : [])
|
|
39
41
|
}
|
|
40
42
|
|
|
@@ -169,8 +171,12 @@ export function registerImageToolviews(ctx: ClientContext): void {
|
|
|
169
171
|
}
|
|
170
172
|
|
|
171
173
|
ctx.slots.inject('tool.call.toolview', function* () {
|
|
172
|
-
for (const key of ['generate_image', 'edit_image', 'get_image_generation_task']) {
|
|
173
|
-
yield ctx.slots.register({
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
}
|
|
174
|
+
for (const key of ['generate_image', 'edit_image', 'get_image_generation_task']) {
|
|
175
|
+
yield ctx.slots.register({
|
|
176
|
+
name: 'tool.call.toolview',
|
|
177
|
+
key,
|
|
178
|
+
inject: (sessionId: string) => ({ sessionId: sessionId as SessionId }),
|
|
179
|
+
}, ImageToolView)
|
|
180
|
+
}
|
|
181
|
+
})
|
|
182
|
+
}
|
package/src/client/index.ts
CHANGED
|
@@ -11,12 +11,13 @@
|
|
|
11
11
|
* whole boot when a plugin apply throws, and an external plugin must not take
|
|
12
12
|
* the GUI down.
|
|
13
13
|
*/
|
|
14
|
-
import type { ClientContext } from '@deepseek-ai/
|
|
15
|
-
import type { ISessions } from '@deepseek-ai/dsh-
|
|
14
|
+
import type { Context as ClientContext } from '@deepseek-ai/cordis'
|
|
15
|
+
import type { ISessions } from '@deepseek-ai/dsh-api-session-controller/client'
|
|
16
16
|
import type { ConnectionHandle } from '@deepseek-ai/dsh-client-connection/client'
|
|
17
17
|
// Type-only: pulls the locale plugin's Context merge (ctx.locale).
|
|
18
|
-
import type {} from '@deepseek-ai/dsh-client-locale/client'
|
|
19
|
-
|
|
18
|
+
import type {} from '@deepseek-ai/dsh-client-locale/client'
|
|
19
|
+
import type {} from '@deepseek-ai/dsh-client-ui-renderer/client'
|
|
20
|
+
// Type-only: pulls the LocaleNamespaceMap merge table.
|
|
20
21
|
import type {} from '@deepseek-ai/dsh-client-ui-slots'
|
|
21
22
|
import { ImageGenApi } from './api.ts'
|
|
22
23
|
import { ImageGenController } from './controller.ts'
|
package/src/client/mount.tsx
CHANGED
|
@@ -15,7 +15,7 @@
|
|
|
15
15
|
* and both get the `position: relative` base in panel.module.css.
|
|
16
16
|
*/
|
|
17
17
|
|
|
18
|
-
import type { ISessions } from '@deepseek-ai/dsh-
|
|
18
|
+
import type { ISessions } from '@deepseek-ai/dsh-api-session-controller/client'
|
|
19
19
|
import { createRoot, type Root } from 'react-dom/client'
|
|
20
20
|
import type { ImageGenApi } from './api.ts'
|
|
21
21
|
import type { ImageGenController } from './controller.ts'
|
|
@@ -7,7 +7,8 @@
|
|
|
7
7
|
* sibling UI package).
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
|
-
import { createSnapshotStore, type
|
|
10
|
+
import { createSnapshotStore, type SnapshotStore } from '@deepseek-ai/dsh-client-store'
|
|
11
|
+
import type { SettingsScope, SettingsScopeSnapshot } from '@deepseek-ai/dsh-client-ui-settings/client'
|
|
11
12
|
|
|
12
13
|
/** The write one field's staged text performs when the card is saved. */
|
|
13
14
|
export type FieldWrite =
|
|
@@ -10,10 +10,10 @@
|
|
|
10
10
|
|
|
11
11
|
import {
|
|
12
12
|
createSnapshotStore,
|
|
13
|
-
type SettingsScope,
|
|
14
|
-
type SettingsScopeSnapshot,
|
|
15
13
|
type SnapshotStore,
|
|
16
|
-
} from '@deepseek-ai/dsh-client-
|
|
14
|
+
} from '@deepseek-ai/dsh-client-store'
|
|
15
|
+
import type { SettingsPathOpView } from '@deepseek-ai/dsh-api-remotes/client'
|
|
16
|
+
import type { SettingsScope, SettingsScopeSnapshot } from '@deepseek-ai/dsh-client-ui-settings/client'
|
|
17
17
|
import { SETTINGS_API, type ChannelConfig } from '../protocol.ts'
|
|
18
18
|
|
|
19
19
|
/** The fields this plugin's settings card edits. */
|
|
@@ -158,6 +158,10 @@ class BridgeScopeController<T> implements SettingsScope<T> {
|
|
|
158
158
|
return this.enqueue(() => this.writeOps([{ op: 'unset', path: [field] }]))
|
|
159
159
|
}
|
|
160
160
|
|
|
161
|
+
mutate(ops: readonly SettingsPathOpView[], expectedRevision?: number): Promise<void> {
|
|
162
|
+
return this.enqueue(() => this.writeOps([...ops] as SettingsOp[], expectedRevision))
|
|
163
|
+
}
|
|
164
|
+
|
|
161
165
|
/** Apply several path ops in one revision-fenced mutate call (atomic save).
|
|
162
166
|
* Path ops may address plain-object fields (e.g. `channelSecrets.<id>`),
|
|
163
167
|
* but never navigate *inside* arrays — write array fields wholesale. */
|
|
@@ -206,8 +210,8 @@ class BridgeScopeController<T> implements SettingsScope<T> {
|
|
|
206
210
|
this.accept(view, writable)
|
|
207
211
|
}
|
|
208
212
|
|
|
209
|
-
private async writeOps(ops: SettingsOp[]): Promise<void> {
|
|
210
|
-
const revision = this.getSnapshot().revision
|
|
213
|
+
private async writeOps(ops: SettingsOp[], expectedRevision?: number): Promise<void> {
|
|
214
|
+
const revision = expectedRevision ?? this.getSnapshot().revision
|
|
211
215
|
let response
|
|
212
216
|
try {
|
|
213
217
|
response = await this.api.mutate({
|
package/src/index.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
*/
|
|
9
9
|
|
|
10
10
|
import type { Context } from '@deepseek-ai/cordis'
|
|
11
|
-
import {
|
|
11
|
+
import { installSettingsSectionCompat, settingsNamespaceCompat } from './settings-compat.ts'
|
|
12
12
|
import z from 'schemastery'
|
|
13
13
|
// Type-only: pulls the webServer Context merge (route registration).
|
|
14
14
|
import type {} from '@deepseek-ai/dsh-host-webserver'
|
|
@@ -43,7 +43,7 @@ export { listTemplates, readTemplateImage, refreshTemplates, clearTemplateMemo }
|
|
|
43
43
|
export { checkForUpdate, clearUpdateCache, compareVersions, CURRENT_VERSION, installUpdate, profileFromProcess } from './updater.ts'
|
|
44
44
|
|
|
45
45
|
/** The branded settings namespace of this plugin (the card edits it). */
|
|
46
|
-
export const ImageGenSettingsNamespace =
|
|
46
|
+
export const ImageGenSettingsNamespace = settingsNamespaceCompat(IMAGEGEN_SETTINGS_NAMESPACE)
|
|
47
47
|
|
|
48
48
|
/**
|
|
49
49
|
* Plugin config, validated by the same-named schemastery schema.
|
|
@@ -323,7 +323,7 @@ export function apply(ctx: Context, config?: Config): void {
|
|
|
323
323
|
})
|
|
324
324
|
}
|
|
325
325
|
|
|
326
|
-
|
|
326
|
+
installSettingsSectionCompat(ctx, ImageGenSettingsNamespace, Config, config ?? {}, {
|
|
327
327
|
setSource: (source) => {
|
|
328
328
|
current = source
|
|
329
329
|
sync()
|
package/src/protocol.ts
CHANGED
|
@@ -8,7 +8,7 @@
|
|
|
8
8
|
export const IMAGEGEN_SETTINGS_NAMESPACE = 'dsh-imagegen'
|
|
9
9
|
|
|
10
10
|
/** Published package version shared by the host updater and the client UI. */
|
|
11
|
-
export const PLUGIN_VERSION = '1.5.
|
|
11
|
+
export const PLUGIN_VERSION = '1.5.1'
|
|
12
12
|
|
|
13
13
|
/** Same-origin route family (loopback-only, mirroring the dsh-ssh fence). */
|
|
14
14
|
export const SETTINGS_API = {
|
package/src/routes.ts
CHANGED
|
@@ -9,7 +9,7 @@ import type { IncomingMessage, ServerResponse } from 'node:http'
|
|
|
9
9
|
import { randomUUID } from 'node:crypto'
|
|
10
10
|
import type { WebRoute } from '@deepseek-ai/dsh-host-webserver'
|
|
11
11
|
import type { ImageAttachmentRef, ImageMediaType, SaveImageAttachment } from '@deepseek-ai/dsh-attachment'
|
|
12
|
-
import { SettingsConflictError,
|
|
12
|
+
import { SettingsConflictError, type SettingsDescriptor } from '@deepseek-ai/dsh-settings'
|
|
13
13
|
import type { UpstreamConfig } from './engine.ts'
|
|
14
14
|
import { enhancePrompt, listImageModels, listPromptModels, type PromptModelConfig } from './prompt-enhancer.ts'
|
|
15
15
|
import { normalizeImageModels } from './image-models.ts'
|
|
@@ -563,7 +563,9 @@ export function makeRoutes(deps: ImageGenRoutesDeps): WebRoute[] {
|
|
|
563
563
|
}
|
|
564
564
|
const expectedRevision = typeof body.expectedRevision === 'number' ? body.expectedRevision : undefined
|
|
565
565
|
try {
|
|
566
|
-
|
|
566
|
+
// The alpha.2 settings package no longer exports settingsNamespace;
|
|
567
|
+
// the bridge already checked this value against our fixed namespace.
|
|
568
|
+
await deps.settings.mutate(ns, body.ops, expectedRevision)
|
|
567
569
|
} catch (error) {
|
|
568
570
|
writeJson(res, 200, failureOf(error))
|
|
569
571
|
return
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/** Compatibility helpers for the dsh-settings API transition. */
|
|
2
|
+
|
|
3
|
+
import type { Context } from '@deepseek-ai/cordis'
|
|
4
|
+
import * as settingsModule from '@deepseek-ai/dsh-settings'
|
|
5
|
+
import type { SettingsNamespace, SettingsSectionHooks } from '@deepseek-ai/dsh-settings'
|
|
6
|
+
import type z from 'schemastery'
|
|
7
|
+
|
|
8
|
+
type SettingsModuleCompat = {
|
|
9
|
+
settingsNamespace?: (value: string) => SettingsNamespace
|
|
10
|
+
installSettingsSection?: <T>(
|
|
11
|
+
ctx: Context,
|
|
12
|
+
ns: SettingsNamespace,
|
|
13
|
+
schema: z<T>,
|
|
14
|
+
entry: T,
|
|
15
|
+
hooks: SettingsSectionHooks<T>,
|
|
16
|
+
) => void
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
interface SettingsProviderCompat {
|
|
20
|
+
installSection?: <T>(
|
|
21
|
+
owner: Context,
|
|
22
|
+
ns: SettingsNamespace,
|
|
23
|
+
schema: z<T>,
|
|
24
|
+
entry: T,
|
|
25
|
+
hooks: SettingsSectionHooks<T>,
|
|
26
|
+
) => void
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const compatModule = settingsModule as unknown as SettingsModuleCompat
|
|
30
|
+
|
|
31
|
+
/** Brand namespaces where the installed settings package still exposes it. */
|
|
32
|
+
export function settingsNamespaceCompat(value: string): SettingsNamespace {
|
|
33
|
+
return compatModule.settingsNamespace?.(value) ?? value as SettingsNamespace
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
/**
|
|
37
|
+
* Register an optional settings section across the rc.7 and alpha.2 APIs.
|
|
38
|
+
* rc.7 exposes a module helper; alpha.2 moves the helper onto the provider.
|
|
39
|
+
*/
|
|
40
|
+
export function installSettingsSectionCompat<T>(
|
|
41
|
+
ctx: Context,
|
|
42
|
+
ns: SettingsNamespace,
|
|
43
|
+
schema: z<T>,
|
|
44
|
+
entry: T,
|
|
45
|
+
hooks: SettingsSectionHooks<T>,
|
|
46
|
+
): void {
|
|
47
|
+
const legacyInstaller = compatModule.installSettingsSection
|
|
48
|
+
if (legacyInstaller !== undefined) {
|
|
49
|
+
legacyInstaller(ctx, ns, schema, entry, hooks)
|
|
50
|
+
return
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
ctx.inject(['settings'], (sctx) => {
|
|
54
|
+
const provider = sctx.get('settings') as unknown as SettingsProviderCompat
|
|
55
|
+
if (provider.installSection === undefined) {
|
|
56
|
+
throw new TypeError('dsh-settings does not expose installSection')
|
|
57
|
+
}
|
|
58
|
+
provider.installSection(ctx, ns, schema, entry, hooks)
|
|
59
|
+
})
|
|
60
|
+
}
|