@lemoncat7/dsh-knowledge 1.0.13 → 1.1.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/lib/api.d.ts +9 -2
- package/lib/api.d.ts.map +1 -1
- package/lib/api.js +15 -51
- package/lib/api.js.map +1 -1
- package/lib/extraction.d.ts +5 -1
- package/lib/extraction.d.ts.map +1 -1
- package/lib/extraction.js +8 -11
- package/lib/extraction.js.map +1 -1
- package/lib/index.d.ts.map +1 -1
- package/lib/index.js +52 -23
- package/lib/index.js.map +1 -1
- package/lib/management-proxy.d.ts +13 -1
- package/lib/management-proxy.d.ts.map +1 -1
- package/lib/management-proxy.js +31 -4
- package/lib/management-proxy.js.map +1 -1
- package/lib/service-settings.d.ts +2 -0
- package/lib/service-settings.d.ts.map +1 -1
- package/lib/service-settings.js +7 -2
- package/lib/service-settings.js.map +1 -1
- package/lib/tools.js +0 -26
- package/lib/tools.js.map +1 -1
- package/package.json +1 -1
- package/web/app.js +23 -42
package/web/app.js
CHANGED
|
@@ -349,16 +349,17 @@ async function ensureKnowledgeBases(force = false) {
|
|
|
349
349
|
}
|
|
350
350
|
|
|
351
351
|
async function loadKnowledgeBasesPage() {
|
|
352
|
-
const requests = [api('knowledge-bases'), api('mounts'), api('settings')]
|
|
352
|
+
const requests = [api('knowledge-bases'), api('mounts'), api('settings'), api('service')]
|
|
353
353
|
if (state.mountContext.sessionId) {
|
|
354
354
|
const params = new URLSearchParams({ sessionId: state.mountContext.sessionId })
|
|
355
355
|
if (state.mountContext.projectId) params.set('projectId', state.mountContext.projectId)
|
|
356
356
|
requests.push(api(`mounts/resolve?${params}`))
|
|
357
357
|
}
|
|
358
|
-
const [bases, mounts, settings, resolved = []] = await Promise.all(requests)
|
|
358
|
+
const [bases, mounts, settings, service, resolved = []] = await Promise.all(requests)
|
|
359
359
|
state.knowledgeBases = bases
|
|
360
360
|
state.mounts = mounts
|
|
361
361
|
state.settings = settings
|
|
362
|
+
state.service = service
|
|
362
363
|
state.resolvedMounts = resolved
|
|
363
364
|
await refreshStats()
|
|
364
365
|
}
|
|
@@ -752,7 +753,7 @@ function renderKnowledgeBases() {
|
|
|
752
753
|
const archivedBases = state.knowledgeBases.filter(base => base.status === 'archived')
|
|
753
754
|
const contextAvailable = Boolean(state.mountContext.projectId || state.mountContext.sessionId)
|
|
754
755
|
const query = state.knowledgeBaseQuery.trim().toLocaleLowerCase()
|
|
755
|
-
const matchesQuery = base => !query || [base.name, base.description, base.defaultTags.join(' ')
|
|
756
|
+
const matchesQuery = base => !query || [base.name, base.description, base.defaultTags.join(' ')]
|
|
756
757
|
.some(value => String(value || '').toLocaleLowerCase().includes(query))
|
|
757
758
|
const visibleActiveBases = activeBases.filter(matchesQuery)
|
|
758
759
|
const visibleArchivedBases = archivedBases.filter(matchesQuery)
|
|
@@ -765,11 +766,11 @@ function renderKnowledgeBases() {
|
|
|
765
766
|
type: 'button', role: 'tab', class: 'tab', 'aria-selected': String(state.knowledgeBaseView === id),
|
|
766
767
|
onClick: () => { state.knowledgeBaseView = id; renderShell() },
|
|
767
768
|
}, element('span', {}, label), element('span', { class: 'tab-count' }, count)))),
|
|
768
|
-
actionButton('
|
|
769
|
+
actionButton('本机回写模型', () => openGlobalWritebackModelEditor(), 'ghost small'),
|
|
769
770
|
),
|
|
770
|
-
element('p', {}, state.
|
|
771
|
-
?
|
|
772
|
-
: '
|
|
771
|
+
element('p', {}, state.service.writebackProvider && state.service.writebackModel
|
|
772
|
+
? `仅当前客户端使用 ${state.service.writebackProvider} / ${state.service.writebackModel} 回写。`
|
|
773
|
+
: '当前客户端跟随每轮会话模型回写。'),
|
|
773
774
|
)
|
|
774
775
|
return element('div', { class: 'bases-page' },
|
|
775
776
|
switcher,
|
|
@@ -781,7 +782,7 @@ function renderKnowledgeBases() {
|
|
|
781
782
|
element('div', { class: 'knowledge-base-toolbar' },
|
|
782
783
|
element('div', { class: 'search-box base-search' }, interfaceIcon('search', 'search-symbol'), element('input', {
|
|
783
784
|
class: 'input', type: 'search', value: state.knowledgeBaseQuery,
|
|
784
|
-
placeholder: '
|
|
785
|
+
placeholder: '搜索名称、描述或标签', 'aria-label': '搜索知识库',
|
|
785
786
|
onInput: event => {
|
|
786
787
|
state.knowledgeBaseQuery = event.target.value
|
|
787
788
|
renderShell()
|
|
@@ -795,7 +796,7 @@ function renderKnowledgeBases() {
|
|
|
795
796
|
visibleActiveBases.length
|
|
796
797
|
? element('div', { class: 'base-grid' }, visibleActiveBases.map(renderKnowledgeBaseCard))
|
|
797
798
|
: query && visibleArchivedBases.length === 0
|
|
798
|
-
? emptyState('没有匹配的知识库', '
|
|
799
|
+
? emptyState('没有匹配的知识库', '尝试搜索名称、描述或标签。')
|
|
799
800
|
: !query ? emptyState('还没有可用知识库', '使用右上角按钮创建第一个知识库。') : null,
|
|
800
801
|
visibleArchivedBases.length ? element('details', { class: 'archived-bases', open: Boolean(query) },
|
|
801
802
|
element('summary', {}, element('span', {}, '已归档知识库'), element('span', { class: 'summary-count' }, visibleArchivedBases.length)),
|
|
@@ -821,20 +822,20 @@ function renderKnowledgeBases() {
|
|
|
821
822
|
|
|
822
823
|
async function openGlobalWritebackModelEditor() {
|
|
823
824
|
await loadModelCatalog()
|
|
824
|
-
const custom = element('input', { type: 'checkbox', checked: Boolean(state.
|
|
825
|
-
const route = modelRouteFields(state.
|
|
825
|
+
const custom = element('input', { type: 'checkbox', checked: Boolean(state.service.writebackProvider && state.service.writebackModel) })
|
|
826
|
+
const route = modelRouteFields(state.service.writebackProvider || '', state.service.writebackModel || '')
|
|
826
827
|
const form = element('form', { class: 'form-grid' },
|
|
827
|
-
element('label', { class: 'check-option span-2' }, custom, element('span', {}, element('strong', {}, '
|
|
828
|
+
element('label', { class: 'check-option span-2' }, custom, element('span', {}, element('strong', {}, '当前客户端使用专用模型'), element('small', {}, '关闭后,跟随当前客户端每轮会话实际使用的模型。'))),
|
|
828
829
|
route.provider.wrapper, route.model.wrapper,
|
|
829
830
|
)
|
|
830
831
|
const sync = () => { route.provider.input.disabled = route.model.input.disabled = !custom.checked; route.provider.input.required = route.model.input.required = custom.checked }
|
|
831
832
|
custom.addEventListener('change', sync); sync()
|
|
832
|
-
openSheet({ title: '
|
|
833
|
+
openSheet({ title: '本机回写模型', description: '此设置只保存在当前 DSH 客户端,不会写入中央知识库或影响其他设备。', body: form, primaryLabel: '保存', onPrimary: async () => {
|
|
833
834
|
if (!form.reportValidity()) return false
|
|
834
|
-
state.
|
|
835
|
+
state.service = await api('service', { method: 'PUT', body: custom.checked
|
|
835
836
|
? { writebackProvider: route.provider.input.value, writebackModel: route.model.input.value }
|
|
836
|
-
: { writebackProvider: null, writebackModel: null } }
|
|
837
|
-
showToast('
|
|
837
|
+
: { writebackProvider: null, writebackModel: null } })
|
|
838
|
+
showToast('当前客户端的回写模型已更新。'); renderShell(); return true
|
|
838
839
|
} })
|
|
839
840
|
}
|
|
840
841
|
|
|
@@ -861,7 +862,7 @@ function renderKnowledgeBaseCard(base) {
|
|
|
861
862
|
hiddenTagCount ? element('span', { class: 'tag' }, `+${hiddenTagCount}`) : null),
|
|
862
863
|
element('div', { class: 'base-card-meta' },
|
|
863
864
|
element('span', {}, element('strong', {}, '回写策略'), base.writebackPolicy === 'proactive' ? '主动' : '严谨'),
|
|
864
|
-
element('span', {}, element('strong', {}, '回写模型'),
|
|
865
|
+
element('span', {}, element('strong', {}, '回写模型'), state.service.writebackProvider && state.service.writebackModel ? `本机 · ${state.service.writebackProvider} / ${state.service.writebackModel}` : '跟随当前会话'),
|
|
865
866
|
base.extractionInstructions ? element('span', {}, element('strong', {}, '提取规则'), '已设置') : null,
|
|
866
867
|
),
|
|
867
868
|
element('div', { class: 'base-card-actions' },
|
|
@@ -921,15 +922,14 @@ function renderMountManager(activeBases) {
|
|
|
921
922
|
const query = manager.query.trim().toLowerCase()
|
|
922
923
|
const rows = activeBases.map(base => ({ base, view: mountView(base, manager.targetKind, targetId) }))
|
|
923
924
|
const visibleRows = rows.filter(({ base, view }) => {
|
|
924
|
-
const
|
|
925
|
-
const searchable = `${base.name} ${base.description} ${base.defaultTags.join(' ')} ${model}`.toLowerCase()
|
|
925
|
+
const searchable = `${base.name} ${base.description} ${base.defaultTags.join(' ')}`.toLowerCase()
|
|
926
926
|
return (!query || searchable.includes(query)) && (manager.filter === 'all' || manager.filter === view.statusKey)
|
|
927
927
|
})
|
|
928
928
|
const visibleIds = visibleRows.map(({ base }) => base.id)
|
|
929
929
|
const selectedCount = manager.selectedIds.size
|
|
930
930
|
const searchInput = element('input', {
|
|
931
931
|
class: 'input', type: 'search', value: manager.query,
|
|
932
|
-
placeholder: '
|
|
932
|
+
placeholder: '搜索名称、描述或标签', 'aria-label': '搜索可挂载知识库',
|
|
933
933
|
onInput: (event) => { manager.query = event.target.value; renderShell() },
|
|
934
934
|
})
|
|
935
935
|
const filter = selectControl('筛选挂载状态', [
|
|
@@ -983,8 +983,8 @@ function renderMountListRow(base, view, targetKind, targetId) {
|
|
|
983
983
|
renderShell()
|
|
984
984
|
},
|
|
985
985
|
})
|
|
986
|
-
const modelLabel =
|
|
987
|
-
?
|
|
986
|
+
const modelLabel = state.service.writebackProvider && state.service.writebackModel
|
|
987
|
+
? `本机 · ${state.service.writebackProvider} / ${state.service.writebackModel}`
|
|
988
988
|
: '跟随当前会话模型'
|
|
989
989
|
return element('article', { class: `mount-list-row${selected ? ' is-selected' : ''}`, role: 'listitem' },
|
|
990
990
|
element('label', { class: 'mount-select' }, checkbox, element('span', { class: 'visually-hidden' }, `选择 ${base.name}`)),
|
|
@@ -1400,8 +1400,7 @@ function parseTags(value) {
|
|
|
1400
1400
|
return [...new Set(value.split(/[,,]/).map(tag => tag.trim().toLowerCase()).filter(Boolean))]
|
|
1401
1401
|
}
|
|
1402
1402
|
|
|
1403
|
-
|
|
1404
|
-
await loadModelCatalog()
|
|
1403
|
+
function openKnowledgeBaseEditor(base) {
|
|
1405
1404
|
const source = base || { name: '', description: '', defaultTags: [], extractionInstructions: '', writebackPolicy: 'conservative' }
|
|
1406
1405
|
const form = element('form', { class: 'form-grid' })
|
|
1407
1406
|
const name = formField('名称', 'input', source.name, { required: true, maxlength: 100, placeholder: '例如:项目规范' })
|
|
@@ -1412,25 +1411,9 @@ async function openKnowledgeBaseEditor(base) {
|
|
|
1412
1411
|
{ value: 'conservative', label: '严谨(高置信度直写)' },
|
|
1413
1412
|
{ value: 'proactive', label: '主动(更积极沉淀)' },
|
|
1414
1413
|
], source.writebackPolicy || 'conservative')
|
|
1415
|
-
const customModel = element('input', { type: 'checkbox', checked: Boolean(source.writebackProvider && source.writebackModel) })
|
|
1416
|
-
const route = modelRouteFields(source.writebackProvider || '', source.writebackModel || '')
|
|
1417
|
-
const modelHint = element('div', { class: 'field-hint span-2' }, '默认跟随当前会话模型。指定后,仅这个知识库使用专用模型回写。')
|
|
1418
|
-
const updateModelFields = () => {
|
|
1419
|
-
route.provider.input.disabled = !customModel.checked
|
|
1420
|
-
route.model.input.disabled = !customModel.checked
|
|
1421
|
-
route.provider.input.required = customModel.checked
|
|
1422
|
-
route.model.input.required = customModel.checked
|
|
1423
|
-
}
|
|
1424
|
-
customModel.addEventListener('change', updateModelFields)
|
|
1425
|
-
updateModelFields()
|
|
1426
1414
|
for (const field of [name, description, tags, instructions]) field.wrapper.classList.add('span-2')
|
|
1427
1415
|
form.append(
|
|
1428
1416
|
name.wrapper, description.wrapper, tags.wrapper, instructions.wrapper, policy.wrapper,
|
|
1429
|
-
element('label', { class: 'check-option span-2' }, customModel, element('span', {},
|
|
1430
|
-
element('strong', {}, '为这个知识库指定回写模型'),
|
|
1431
|
-
element('small', {}, '关闭时自动使用当前会话正在使用的模型。'),
|
|
1432
|
-
)),
|
|
1433
|
-
route.provider.wrapper, route.model.wrapper, modelHint,
|
|
1434
1417
|
)
|
|
1435
1418
|
openSheet({
|
|
1436
1419
|
title: base ? '编辑知识库' : '创建知识库',
|
|
@@ -1445,8 +1428,6 @@ async function openKnowledgeBaseEditor(base) {
|
|
|
1445
1428
|
defaultTags: parseTags(tags.input.value),
|
|
1446
1429
|
extractionInstructions: instructions.input.value.trim(),
|
|
1447
1430
|
writebackPolicy: policy.input.value,
|
|
1448
|
-
writebackProvider: customModel.checked ? route.provider.input.value : '',
|
|
1449
|
-
writebackModel: customModel.checked ? route.model.input.value : '',
|
|
1450
1431
|
}
|
|
1451
1432
|
if (base) await api(`knowledge-bases/${encodeURIComponent(base.id)}`, { method: 'PUT', body: { draft } })
|
|
1452
1433
|
else await api('knowledge-bases', { method: 'POST', body: { draft } })
|