Merge latest aligned knowledge updates from Agent conversation
Electron E2E / Electron E2E (macos-latest) (push) Waiting to run
Electron E2E / Electron E2E (ubuntu-latest) (push) Waiting to run
Electron E2E / Electron E2E (windows-latest) (push) Waiting to run

This commit is contained in:
鲨鱼辣椒 committed 2026-10-13 15:59:24 +08:00
commit 57b6bbd97e
8 files changed
+19 -14

No files matched your search

@@ -59,3 +59,7 @@
- Concurrent / Planning Gates Passed on same-task resume with exact owner/task/branch/worktree/base; current record and source task Scope/Intent/Promotion/latest outcome read-only, retained unchanged required project context. Main is already published at 37272af. Source delta against it is seven product/test/README paths: three knowledge CSS/copy files, three regression files and README. No Main/shared/resources/package/auth/account/Settings change or semantic conflict; unknown draft-conflict work stays outside this exact committed-source scope.
- Product intent: top knowledge cards stretch to equal height; remove full fee-help disclosure and two normal explanatory paragraphs while preserving the 100-library limit and actual selection/save/processing behavior. Actual running Renderer 2899009 already has this result; do not refresh it again or reuse another task's once-only input-clear authorization.
- Plan: merge exact source08 parent, preserve current main project-doc tree plus only this owned record, verify all product/test/config blobs against source08, run the affected knowledge units/UI scenarios and build/typecheck, then normally push main after a fresh parent check. Finish final handoff and only then clean this generated merge checkout as previously authorized.
- Latest named-source resolution/verification complete: six conflict hunks were exactly the explicitly requested equal-height/removal delta; retained complete tested source08 blobs, not a timestamp/side preference. All product/tests/configuration/README match source08; independent review confirms latest main, shared account/Settings/auth/Main/billing contracts remain intact. Origin canonical/peer docs unchanged; source records stay in their source branches and merge parents.
- Fresh follow-up checks passed: 4 knowledge/page unit suites / 70 tests, 5 knowledge UI scenarios (21s) including equal heights at empty/creation/document states and removed prose, typecheck, scoped lint and full production build. All 133 Renderer files, 8 Main/preload/utility files, 57 resources and package exactly match the active latest 2899009 snapshot. Prior first-phase 154 units and other UI/source proofs retained; no extra runtime refresh, business-data operation or once-only authorization reuse.
- Latest source branch independently remains at exact 08c9b9af before publication; cleanup is deferred until this final additional merge is published and checked. Main publication for this follow-up is pending.
+1 -1
View File
@@ -16,7 +16,7 @@ Makelore 是一个面向软件、视觉创作、智能机器人与个人云智
历史待确认记录收起在智能体列表标题区的「创建记录/待处理记录」入口,只有点击后才打开记录窗口;配置、聊天和创建页不再置顶这些旧提醒。记录保留智能体名称和原请求身份,用户可明确「再试一次」或「不再提醒」,不会自动重试或清除。当前创建失败继续在创建表单内提示;关闭记录窗口保留已收到的结果和密钥,切换配置、聊天或创建页后可返回列表继续查看。密钥须明确关闭结果后,才可处理其他记录。
高级配置的知识库支持下拉多选,分为「MakeLore知识」和「我的知识库」,已选项可单独移除。MakeLore知识来自当前账号有权读取的 Yuxi 共享目录,只显示名称与简介;移除仅取消当前智能体选用,不删除原库。知识库区域上方左右分区:左侧「上传自己的文件」仅放「新建知识库」入口及展开的创建表单,右侧「查看我的知识库」通过下拉框查看本人知识库、从电脑追加资料和管理文件;下方独立「选择知识库」,选择智能体使用的「MakeLore知识」和「我的知识库」。小窗口按新建、查看、选用顺序纵向排列。创建成功后在右侧打开新库;新建和查看均不会自动加入智能体配置,选用上限不影响管理与新建。仅提供「从电脑上传」作为添加文件入口,未选择管理目标时上传按钮置灰;聊天文件导入入口已移除。上传后自动解析、建立索引并持续显示真实处理状态;失败可重试且保留已有可用内容。使用说明与费用以折叠说明呈现。暂不可选用的个人库仍可管理文件,已有绑定保留并提示不可用;未确认请求在当前库保留同一操作身份供重试。知识库选择只改草稿,显式保存/应用后生效;个人云端执行已自动接入所选知识库的检索,无需另外勾选 knowledge-base Skill。此交互复用现有接口,无需新增后端补丁。
高级配置的知识库支持下拉多选,分为「MakeLore知识」和「我的知识库」,已选项可单独移除。MakeLore知识来自当前账号有权读取的 Yuxi 共享目录,只显示名称与简介;移除仅取消当前智能体选用,不删除原库。知识库区域上方左右分区,两张卡片在并排时保持等高:左侧「上传自己的文件」仅放「新建知识库」入口及展开的创建表单,右侧「查看我的知识库」通过下拉框查看本人知识库、从电脑追加资料和管理文件;下方独立「选择知识库」,选择智能体使用的「MakeLore知识」和「我的知识库」。小窗口按新建、查看、选用顺序纵向排列。创建成功后在右侧打开新库;新建和查看均不会自动加入智能体配置,选用上限不影响管理与新建。仅提供「从电脑上传」作为添加文件入口,未选择管理目标时上传按钮置灰;聊天文件导入入口已移除。上传后自动解析、建立索引并持续显示真实处理状态;失败可重试且保留已有可用内容。暂不可选用的个人库仍可管理文件,已有绑定保留并提示不可用;未确认请求在当前库保留同一操作身份供重试。知识库选择只改草稿,显式保存/应用后生效;个人云端执行已自动接入所选知识库的检索,无需另外勾选 knowledge-base Skill。此交互复用现有接口,无需新增后端补丁。
云知识库的 embedding 模型只由平台管理员在 Yuxi 后台维护:在「智能体管理 → 模型供应商」启用供应商,按供应商要求填写有效的服务地址和 API Key,添加并启用 embedding 模型并填写实际向量维度;embedding 向量化费用由平台承担,不计入用户用量、词元点数或智能体费用上限;one-api 不参与 embedding 配置,Works Square 只负责其他应计费模型调用的创建者词元点数账本。客户端区分目录加载中、加载失败与无可用模型,空状态提供管理员配置说明;「刷新知识库与模型」保留未提交名称,未确认的创建请求沿用原操作身份。
-4
View File
@@ -120,10 +120,6 @@ export function CloudKnowledgePanel({ slug, onCreated, onDeleted, onCatalog, ref
<Button type="button" variant="ghost" disabled={disabled || busy || catalogLoading} onClick={() => setRefresh(v => v + 1)}>刷新知识库与模型</Button>
</div>
{documentPending && selectedKnowledge && <p role="status" className="text-xs leading-5 text-amber-800">有未确认的文件操作,请先在当前知识库重试或确认状态,再切换知识库。</p>}
<details className="agent-knowledge-help">
<summary>使用说明与费用</summary>
<p className="mt-2 text-xs leading-5 text-muted-foreground">上传到知识库的文档可供获准使用此智能体的人检索。解析并建立索引后才会生效;embedding 向量化由平台承担,不计入用户用量、词元点数或智能体费用上限。知识处理如触发对话模型调用,仍按原模型实际用量计费。</p>
</details>
{!catalogLoading && !catalogError && !manageable.length && <p className="text-xs leading-5 text-muted-foreground">还没有可管理的知识库,可以新建一个保存自己的文件。MakeLore知识仅供检索。</p>}
{selectedKnowledge && selectableIds !== undefined && !bindable(selectedKnowledge.kb_id) && <p role="status" className="text-xs leading-5 text-amber-800">
{selectableIds === null ? '知识库选用状态待确认。' : '这个知识库当前暂不可选用。'}你仍可管理自己的文件,刷新目录后再试。
@@ -34,7 +34,7 @@ export function CloudKnowledgeSelector({ slug, options, selected, disabled, load
</select>
<Button type="button" variant="ghost" size="sm" disabled={disabled || loading || owned.loading} onClick={onRefresh}>刷新知识库</Button>
</div>
<p className="text-xs leading-5 text-muted-foreground">{selectionFull ? '已选满100个知识库,请先移除一个再选择。' : '可多选,每次选择一个知识库加入配置。'}</p>
{selectionFull && <p className="text-xs leading-5 text-muted-foreground">已选满100个知识库,请先移除一个再选择。</p>}
{error ? <p role="alert" className="text-sm text-destructive">知识库目录读取失败,请刷新重试。</p>
: !loading && ownedIds !== null && options.every(option => ownedIds.includes(option.key)) && <p className="text-xs leading-5 text-muted-foreground">暂无可选的MakeLore知识。平台开放给你读取的知识库会出现在这里。</p>}
{owned.error && <p className="text-xs leading-5 text-muted-foreground">我的知识库目录暂不可用,仍可选用可读取的知识;上传文件请刷新重试。</p>}
@@ -56,7 +56,6 @@ export function CloudKnowledgeSelector({ slug, options, selected, disabled, load
</li>;
})}
</ul> : <p className="agent-resource-empty">还没有选择知识库</p>}
<p className="text-xs leading-5 text-muted-foreground">选择后保存并应用配置,智能体即可使用这些知识。MakeLore知识只可检索,无法在这里修改。</p>
</section>
</div>;
}
+1 -4
View File
@@ -43,16 +43,13 @@
.agent-config-resource-manager > details { border-radius: 14px; background: #ffffffa8; }
.agent-resource-card:has(.agent-knowledge-workspace) { container-type: inline-size; }
.agent-knowledge-workspace { display: grid; gap: 18px; min-width: 0; }
.agent-knowledge-owned-workspace { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr); align-items: start; gap: 18px; min-width: 0; }
.agent-knowledge-owned-workspace { display: grid; grid-template-columns: minmax(0, 1fr) minmax(0, 1.2fr); align-items: stretch; gap: 18px; min-width: 0; }
.agent-knowledge-upload, .agent-knowledge-management, .agent-knowledge-selection { min-width: 0; padding: 18px; border: 1px solid #dce5e0; border-radius: 17px; background: #fffdfb; overflow-wrap: anywhere; }
.agent-knowledge-upload { border-color: #dce5f3; }
.agent-knowledge-panel-heading { display: flex; align-items: center; gap: 9px; color: #33485c; }
.agent-knowledge-panel-heading h3 { font-size: 16px; font-weight: 650; line-height: 1.5; }
.agent-knowledge-panel-heading svg { flex-shrink: 0; color: #607d72; }
.agent-knowledge-upload .agent-knowledge-panel-heading svg { color: #4a6e9c; }
.agent-knowledge-help { border-top: 1px solid #e8e6e1; padding-top: 12px; }
.agent-knowledge-help summary { min-height: 28px; width: fit-content; cursor: pointer; color: #606c7e; font-size: 12px; line-height: 1.7; }
.agent-knowledge-help summary:focus-visible { outline: 2px solid #9a7bb5; outline-offset: 3px; border-radius: 4px; }
.agent-knowledge-selection ul { max-height: 480px; overflow: auto; overscroll-behavior: contain; }
.agent-knowledge-selection button { flex-shrink: 0; }
@container (max-width: 620px) { .agent-knowledge-owned-workspace { grid-template-columns: minmax(0, 1fr); } }
+5
View File
@@ -190,7 +190,11 @@ async function expectKnowledgeLayout(page: Page) {
await expect(management.getByRole('combobox', { name: '管理的知识库', exact: true })).toBeVisible();
await expect(management.getByRole('button', { name: '从电脑上传', exact: true })).toBeVisible();
await expect(management.getByRole('button', { name: '新建知识库', exact: true })).toHaveCount(0);
await expect(management.locator('summary').filter({ hasText: '使用说明与费用' })).toHaveCount(0);
await expect(management.getByText('上传到知识库的文档可供获准使用此智能体的人检索。解析并建立索引后才会生效;embedding 向量化由平台承担,不计入用户用量、词元点数或智能体费用上限。知识处理如触发对话模型调用,仍按原模型实际用量计费。', { exact: true })).toHaveCount(0);
await expect(selection.getByRole('combobox', { name: '选择知识库', exact: true })).toBeVisible();
await expect(selection.getByText('可多选,每次选择一个知识库加入配置。', { exact: true })).toHaveCount(0);
await expect(selection.getByText('选择后保存并应用配置,智能体即可使用这些知识。MakeLore知识只可检索,无法在这里修改。', { exact: true })).toHaveCount(0);
await expect(knowledge.getByText('添加到我的知识库', { exact: true })).toHaveCount(0);
await expect(knowledge.getByText('选择或新建自己的知识库,再从电脑上传资料。选用会加入右侧配置,保存并应用后生效。', { exact: true })).toHaveCount(0);
const creationBounds = await creation.boundingBox();
@@ -202,6 +206,7 @@ async function expectKnowledgeLayout(page: Page) {
if (ownedBounds!.width > 620) {
expect(creationBounds!.x + creationBounds!.width).toBeLessThanOrEqual(managementBounds!.x + 1);
expect(Math.abs(creationBounds!.y - managementBounds!.y)).toBeLessThanOrEqual(1);
expect(Math.abs(creationBounds!.height - managementBounds!.height)).toBeLessThanOrEqual(1);
expect(selectionBounds!.y).toBeGreaterThanOrEqual(Math.max(creationBounds!.y + creationBounds!.height, managementBounds!.y + managementBounds!.height));
expect(Math.abs(selectionBounds!.x + selectionBounds!.width - managementBounds!.x - managementBounds!.width)).toBeLessThanOrEqual(1);
} else {
+3 -2
View File
@@ -22,8 +22,9 @@ it('explains who configures an empty embedding catalog and refreshes without los
expect(within(screen.getByRole('region', { name: '查看我的知识库' })).getByRole('button', { name: '从电脑上传', exact: true })).toBeDisabled();
expect(await screen.findByText('暂时没有可用的向量模型。Embedding 只在 Yuxi 配置,请联系平台管理员启用后刷新;向量化费用由平台承担,不计入用户用量或智能体费用上限。')).toBeVisible();
expect(screen.getByRole('combobox', { name: '向量模型' })).toBeDisabled();
expect(screen.getByText(/上传到知识库的文档可供/)).toHaveTextContent('embedding 向量化由平台承担,不计入用户用量、词元点数或智能体费用上限');
expect(screen.getByText(/上传到知识库的文档可供/)).toHaveTextContent('知识处理如触发对话模型调用,仍按原模型实际用量计费');
const management = within(screen.getByRole('region', { name: '查看我的知识库' }));
expect(management.queryByText('使用说明与费用', { exact: true })).not.toBeInTheDocument();
expect(management.queryByText(/上传到知识库的文档可供/)).not.toBeInTheDocument();
fireEvent.click(screen.getByText('管理员配置说明'));
expect(screen.getByText(/Yuxi 后台/)).toHaveTextContent('智能体管理 → 模型供应商');
expect(screen.getByText(/Yuxi 后台/)).toHaveTextContent('服务地址和 API Key');
+4 -1
View File
@@ -59,7 +59,10 @@ it('joins readable IDs to the owned-only catalog and selects multiple libraries
expect(management.compareDocumentPosition(selection) & Node.DOCUMENT_POSITION_FOLLOWING).toBeTruthy();
expect(screen.queryByText('添加到我的知识库', { exact: true })).not.toBeInTheDocument();
expect(screen.queryByText('选择或新建自己的知识库,再从电脑上传资料。选用会加入右侧配置,保存并应用后生效。', { exact: true })).not.toBeInTheDocument();
expect(screen.getByText('可多选,每次选择一个知识库加入配置。')).toBeVisible();
expect(within(management).queryByText('使用说明与费用', { exact: true })).not.toBeInTheDocument();
expect(within(management).queryByText(/上传到知识库的文档可供/)).not.toBeInTheDocument();
expect(within(selection).queryByText('可多选,每次选择一个知识库加入配置。', { exact: true })).not.toBeInTheDocument();
expect(within(selection).queryByText('选择后保存并应用配置,智能体即可使用这些知识。MakeLore知识只可检索,无法在这里修改。', { exact: true })).not.toBeInTheDocument();
choose('shared'); choose(own.kb_id); choose('other-shared');
expect(within(screen.getByRole('list', { name: '已选知识库' })).getAllByRole('listitem')).toHaveLength(3);
expect(screen.getAllByText('MakeLore知识 · 只读')).toHaveLength(2);