dsh-gpt-adapter 0.2.5 → 0.2.6
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 +7 -7
- package/README.zh-CN.md +7 -7
- package/THIRD_PARTY_NOTICES.md +7 -3
- package/dist/src/client/context-window-preset.d.ts +11 -0
- package/dist/src/client/native-context-settings.d.ts +3 -0
- package/lib/client.js +5178 -54
- package/package.json +1 -1
- package/scripts/build.mjs +36 -0
- package/scripts/native-context-settings.mjs +139 -0
package/package.json
CHANGED
package/scripts/build.mjs
CHANGED
|
@@ -3,6 +3,8 @@ import { mkdir, writeFile, rm, readFile } from 'node:fs/promises'
|
|
|
3
3
|
import { createHash } from 'node:crypto'
|
|
4
4
|
import { createRequire } from 'node:module'
|
|
5
5
|
import { compatibilitySource, menuSource } from './compat.mjs'
|
|
6
|
+
import { nativeContextSettingsSource } from './native-context-settings.mjs'
|
|
7
|
+
import { fileURLToPath } from 'node:url'
|
|
6
8
|
|
|
7
9
|
await rm('lib', { recursive: true, force: true })
|
|
8
10
|
await mkdir('lib', { recursive: true })
|
|
@@ -30,6 +32,7 @@ const settings = await readFile(
|
|
|
30
32
|
require.resolve('@deepseek-ai/dsh-client-ui-settings-models/client'),
|
|
31
33
|
'utf8',
|
|
32
34
|
)
|
|
35
|
+
const nativeContextSettings = nativeContextSettingsSource()
|
|
33
36
|
const styleNames = [
|
|
34
37
|
'customized',
|
|
35
38
|
'customizedSummary',
|
|
@@ -62,8 +65,41 @@ await build({
|
|
|
62
65
|
'react',
|
|
63
66
|
'react/jsx-runtime',
|
|
64
67
|
'@deepseek-ai/dsh-client-ui-primitives',
|
|
68
|
+
'@deepseek-ai/dsh-client-store',
|
|
65
69
|
],
|
|
66
70
|
plugins: [
|
|
71
|
+
{
|
|
72
|
+
name: 'native-context-settings',
|
|
73
|
+
setup(build) {
|
|
74
|
+
build.onResolve(
|
|
75
|
+
{ filter: new RegExp('^dsh-gpt-adapter/native-context-settings$') },
|
|
76
|
+
() => ({
|
|
77
|
+
path: 'native-context-settings',
|
|
78
|
+
namespace: 'gpt-context',
|
|
79
|
+
}),
|
|
80
|
+
)
|
|
81
|
+
build.onLoad({ filter: /.*/, namespace: 'gpt-context' }, () => ({
|
|
82
|
+
contents: `
|
|
83
|
+
import * as React from 'react';
|
|
84
|
+
import * as JSX from 'react/jsx-runtime';
|
|
85
|
+
import * as Primitives from '@deepseek-ai/dsh-client-ui-primitives';
|
|
86
|
+
import * as Store from '@deepseek-ai/dsh-client-store';
|
|
87
|
+
import { ContextWindowPreset } from ${JSON.stringify(fileURLToPath(new URL('../src/client/context-window-preset.tsx', import.meta.url)))};
|
|
88
|
+
import { isGptModel } from ${JSON.stringify(fileURLToPath(new URL('../src/capabilities.ts', import.meta.url)))};
|
|
89
|
+
import { validContextWindow } from ${JSON.stringify(fileURLToPath(new URL('../src/context-window.ts', import.meta.url)))};
|
|
90
|
+
const native = ((require) => { ${nativeContextSettings.body} })((name) => {
|
|
91
|
+
const modules = {'react': React, 'react/jsx-runtime': JSX, '@deepseek-ai/dsh-client-ui-primitives': Primitives, '@deepseek-ai/dsh-client-store': Store};
|
|
92
|
+
if (!(name in modules)) throw new Error('Unsupported native Models dependency: ' + name);
|
|
93
|
+
return modules[name];
|
|
94
|
+
});
|
|
95
|
+
export const NativeModelsSection = native.ModelsSection;
|
|
96
|
+
export const expectedModelsSectionSource = ${JSON.stringify(nativeContextSettings.expectedModelsSectionSource)};
|
|
97
|
+
`,
|
|
98
|
+
loader: 'js',
|
|
99
|
+
resolveDir: fileURLToPath(new URL('../', import.meta.url)),
|
|
100
|
+
}))
|
|
101
|
+
},
|
|
102
|
+
},
|
|
67
103
|
{
|
|
68
104
|
name: 'native-settings-styles',
|
|
69
105
|
setup(build) {
|
|
@@ -0,0 +1,139 @@
|
|
|
1
|
+
import { readFileSync } from 'node:fs'
|
|
2
|
+
import { createRequire } from 'node:module'
|
|
3
|
+
import ts from 'typescript'
|
|
4
|
+
|
|
5
|
+
/** Adapt the pinned native model field without editing the installed package. */
|
|
6
|
+
export function nativeContextSettingsSource() {
|
|
7
|
+
const require = createRequire(import.meta.url)
|
|
8
|
+
const pkg = require('@deepseek-ai/dsh-client-ui-settings-models/package.json')
|
|
9
|
+
if (pkg.version !== '0.2.2-rc.1')
|
|
10
|
+
throw new Error('Unsupported native Models UI ' + pkg.version)
|
|
11
|
+
const source = readFileSync(
|
|
12
|
+
require.resolve('@deepseek-ai/dsh-client-ui-settings-models/client'),
|
|
13
|
+
'utf8',
|
|
14
|
+
)
|
|
15
|
+
const ast = ts.createSourceFile(
|
|
16
|
+
'native-models.js',
|
|
17
|
+
source,
|
|
18
|
+
ts.ScriptTarget.Latest,
|
|
19
|
+
true,
|
|
20
|
+
ts.ScriptKind.JS,
|
|
21
|
+
)
|
|
22
|
+
const nodes = []
|
|
23
|
+
const walk = (node) => {
|
|
24
|
+
nodes.push(node)
|
|
25
|
+
ts.forEachChild(node, walk)
|
|
26
|
+
}
|
|
27
|
+
walk(ast)
|
|
28
|
+
const one = (matches, label) => {
|
|
29
|
+
if (matches.length !== 1)
|
|
30
|
+
throw new Error('Unsupported native Models UI: ' + label)
|
|
31
|
+
return matches[0]
|
|
32
|
+
}
|
|
33
|
+
const factory = one(
|
|
34
|
+
nodes.filter(
|
|
35
|
+
(node) =>
|
|
36
|
+
ts.isPropertyAssignment(node) &&
|
|
37
|
+
node.name.getText(ast) === 'factory' &&
|
|
38
|
+
ts.isArrowFunction(node.initializer) &&
|
|
39
|
+
node.initializer.parameters[0]?.name.getText(ast) === 'require',
|
|
40
|
+
),
|
|
41
|
+
'module factory',
|
|
42
|
+
).initializer
|
|
43
|
+
const models = one(
|
|
44
|
+
nodes.filter(
|
|
45
|
+
(node) =>
|
|
46
|
+
ts.isFunctionDeclaration(node) && node.name?.text === 'ModelsSection',
|
|
47
|
+
),
|
|
48
|
+
'ModelsSection',
|
|
49
|
+
)
|
|
50
|
+
const input = one(
|
|
51
|
+
nodes.filter(
|
|
52
|
+
(node) =>
|
|
53
|
+
ts.isCallExpression(node) &&
|
|
54
|
+
node.arguments[0] &&
|
|
55
|
+
ts.isStringLiteral(node.arguments[0]) &&
|
|
56
|
+
node.arguments[0].text === 'input' &&
|
|
57
|
+
node.arguments[1] &&
|
|
58
|
+
ts.isObjectLiteralExpression(node.arguments[1]) &&
|
|
59
|
+
node.arguments[1].properties.some(
|
|
60
|
+
(prop) =>
|
|
61
|
+
ts.isPropertyAssignment(prop) &&
|
|
62
|
+
prop.name.getText(ast) === 'value' &&
|
|
63
|
+
prop.initializer.getText(ast) === 'props[field].value',
|
|
64
|
+
),
|
|
65
|
+
),
|
|
66
|
+
'context capacity input',
|
|
67
|
+
)
|
|
68
|
+
let label = input.parent
|
|
69
|
+
while (
|
|
70
|
+
label &&
|
|
71
|
+
!(
|
|
72
|
+
ts.isCallExpression(label) &&
|
|
73
|
+
label.arguments[0] &&
|
|
74
|
+
ts.isStringLiteral(label.arguments[0]) &&
|
|
75
|
+
label.arguments[0].text === 'label'
|
|
76
|
+
)
|
|
77
|
+
)
|
|
78
|
+
label = label.parent
|
|
79
|
+
if (!label) throw new Error('Unsupported native Models UI: capacity label')
|
|
80
|
+
const eligible =
|
|
81
|
+
'field === "contextWindow" && props.inputField === "input" && isGptModel(model)'
|
|
82
|
+
const edits = [
|
|
83
|
+
{
|
|
84
|
+
start: input.getStart(ast),
|
|
85
|
+
end: input.end,
|
|
86
|
+
text:
|
|
87
|
+
'(' +
|
|
88
|
+
eligible +
|
|
89
|
+
' ? (0, react_jsx_runtime.jsx)(ContextWindowPreset, {' +
|
|
90
|
+
'inputProps: ' +
|
|
91
|
+
input.arguments[1].getText(ast) +
|
|
92
|
+
',' +
|
|
93
|
+
'tokens: Number.isNaN(model[field]) ? NaN : parseCapacity(props[field].value),' +
|
|
94
|
+
'onValueChange: props[field].onChange,' +
|
|
95
|
+
'onCustomValueChange: (text) => {' +
|
|
96
|
+
'props[field].onChange(text);' +
|
|
97
|
+
'if (!validContextWindow(parseCapacity(text))) props.onFieldChange(field, NaN);' +
|
|
98
|
+
'}' +
|
|
99
|
+
'}) : ' +
|
|
100
|
+
input.getText(ast) +
|
|
101
|
+
')',
|
|
102
|
+
},
|
|
103
|
+
{
|
|
104
|
+
start: label.arguments[0].getStart(ast),
|
|
105
|
+
end: label.arguments[0].end,
|
|
106
|
+
text: '(' + eligible + ' ? "div" : "label")',
|
|
107
|
+
},
|
|
108
|
+
]
|
|
109
|
+
for (const statement of factory.body.statements) {
|
|
110
|
+
if (
|
|
111
|
+
ts.isExpressionStatement(statement) &&
|
|
112
|
+
ts.isBinaryExpression(statement.expression) &&
|
|
113
|
+
statement.expression.left.getText(ast).startsWith('exports.')
|
|
114
|
+
)
|
|
115
|
+
edits.push({
|
|
116
|
+
start: statement.getStart(ast),
|
|
117
|
+
end: statement.end,
|
|
118
|
+
text: '',
|
|
119
|
+
})
|
|
120
|
+
}
|
|
121
|
+
const returns = factory.body.statements.filter(ts.isReturnStatement)
|
|
122
|
+
const result = one(returns, 'factory return')
|
|
123
|
+
edits.push({
|
|
124
|
+
start: result.getStart(ast),
|
|
125
|
+
end: result.end,
|
|
126
|
+
text: 'return { ModelsSection, ModelListEditor, ProviderEditor, validateDeepSeekModels };',
|
|
127
|
+
})
|
|
128
|
+
const start = factory.body.getStart(ast) + 1
|
|
129
|
+
let body = source.slice(start, factory.body.end - 1)
|
|
130
|
+
for (const edit of edits.sort((a, b) => b.start - a.start)) {
|
|
131
|
+
if (edit.start < start || edit.end > factory.body.end)
|
|
132
|
+
throw new Error('Native Models edit is outside the verified factory')
|
|
133
|
+
body =
|
|
134
|
+
body.slice(0, edit.start - start) +
|
|
135
|
+
edit.text +
|
|
136
|
+
body.slice(edit.end - start)
|
|
137
|
+
}
|
|
138
|
+
return { source, body, expectedModelsSectionSource: models.getText(ast) }
|
|
139
|
+
}
|