hiwork-knowledge 0.1.1 → 0.2.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/README.md +133 -39
- package/cordis.patch.yml +19 -2
- package/lib/client.js +1599 -45
- package/lib/index.js +27793 -6
- package/lib/prompt.js +31 -0
- package/lib/protocol.js +139 -0
- package/lib/rpc.js +103 -0
- package/lib/service.js +344 -0
- package/lib/tool-names.js +15 -0
- package/lib/tools.js +244 -0
- package/lib/types/client/KnowledgeView.d.ts +19 -5
- package/lib/types/client/SettingsSection.d.ts +42 -0
- package/lib/types/client/ToolCards.d.ts +26 -0
- package/lib/types/client/composer.d.ts +98 -0
- package/lib/types/client/contracts.d.ts +100 -2
- package/lib/types/client/focus.d.ts +19 -0
- package/lib/types/client/format.d.ts +74 -0
- package/lib/types/client/icons.d.ts +26 -0
- package/lib/types/client/index.d.ts +31 -2
- package/lib/types/client/locales.d.ts +213 -6
- package/lib/types/client/runtime.d.ts +66 -0
- package/lib/types/client/tool-result.d.ts +90 -0
- package/lib/types/index.d.ts +49 -10
- package/lib/types/prompt.d.ts +21 -0
- package/lib/types/protocol.d.ts +200 -0
- package/lib/types/rpc.d.ts +18 -0
- package/lib/types/service.d.ts +142 -0
- package/lib/types/tool-names.d.ts +11 -0
- package/lib/types/tools.d.ts +21 -0
- package/lib/types/types.d.ts +109 -0
- package/lib/types/weknora.d.ts +112 -0
- package/lib/types.js +112 -0
- package/lib/weknora.js +366 -0
- package/package.json +25 -5
package/lib/client.js
CHANGED
|
@@ -21,39 +21,1142 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
|
|
|
21
21
|
// src/client/index.ts
|
|
22
22
|
var index_exports = {};
|
|
23
23
|
__export(index_exports, {
|
|
24
|
+
KNOWLEDGE_CLIENT_REGISTRATION: () => KNOWLEDGE_CLIENT_REGISTRATION,
|
|
25
|
+
KnowledgeSettings: () => KnowledgeSettings,
|
|
26
|
+
KnowledgeView: () => KnowledgeView,
|
|
27
|
+
__createElement: () => import_react5.createElement,
|
|
24
28
|
apply: () => apply,
|
|
25
29
|
inject: () => inject,
|
|
26
30
|
name: () => name
|
|
27
31
|
});
|
|
28
32
|
module.exports = __toCommonJS(index_exports);
|
|
29
|
-
var
|
|
33
|
+
var import_react5 = require("react");
|
|
30
34
|
|
|
31
35
|
// src/client/KnowledgeView.tsx
|
|
36
|
+
var import_react2 = require("react");
|
|
37
|
+
|
|
38
|
+
// src/client/format.ts
|
|
39
|
+
function statusTone(status) {
|
|
40
|
+
switch (status) {
|
|
41
|
+
case "processing":
|
|
42
|
+
case "finalizing":
|
|
43
|
+
return "info";
|
|
44
|
+
case "pending":
|
|
45
|
+
return "warning";
|
|
46
|
+
case "failed":
|
|
47
|
+
return "danger";
|
|
48
|
+
default:
|
|
49
|
+
return "neutral";
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
var PARSE_STATUSES = ["pending", "processing", "finalizing", "completed", "failed", "cancelled"];
|
|
53
|
+
function parseStatusKey(status) {
|
|
54
|
+
return PARSE_STATUSES.includes(status) ? `docs.parse.${status}` : null;
|
|
55
|
+
}
|
|
56
|
+
function formatSize(bytes) {
|
|
57
|
+
if (bytes === null || bytes === void 0) return "";
|
|
58
|
+
if (!Number.isFinite(bytes) || bytes <= 0) return "";
|
|
59
|
+
if (bytes < 1024) return `${bytes} B`;
|
|
60
|
+
if (bytes < 1024 * 1024) return `${(bytes / 1024).toFixed(1)} KB`;
|
|
61
|
+
if (bytes < 1024 * 1024 * 1024) return `${(bytes / 1024 / 1024).toFixed(1)} MB`;
|
|
62
|
+
return `${(bytes / 1024 / 1024 / 1024).toFixed(1)} GB`;
|
|
63
|
+
}
|
|
64
|
+
function formatDate(iso) {
|
|
65
|
+
if (iso === null || iso === void 0 || iso === "") return "";
|
|
66
|
+
const parsed = new Date(iso);
|
|
67
|
+
if (Number.isNaN(parsed.getTime())) return "";
|
|
68
|
+
const pad = (value) => String(value).padStart(2, "0");
|
|
69
|
+
return `${parsed.getFullYear()}-${pad(parsed.getMonth() + 1)}-${pad(parsed.getDate())}`;
|
|
70
|
+
}
|
|
71
|
+
function fileTypeLabel(fileType, fileName) {
|
|
72
|
+
const declared = fileType.trim();
|
|
73
|
+
const fallback = fileName.includes(".") ? fileName.split(".").pop() ?? "" : "";
|
|
74
|
+
const cleaned = (declared !== "" ? declared : fallback).replace(/^\.+/, "").trim().toUpperCase();
|
|
75
|
+
return cleaned.slice(0, 4);
|
|
76
|
+
}
|
|
77
|
+
var ICON_TONES = {
|
|
78
|
+
PDF: "red",
|
|
79
|
+
DOC: "blue",
|
|
80
|
+
DOCX: "blue",
|
|
81
|
+
RTF: "blue",
|
|
82
|
+
ODT: "blue",
|
|
83
|
+
XLS: "green",
|
|
84
|
+
XLSX: "green",
|
|
85
|
+
CSV: "green",
|
|
86
|
+
PPT: "amber",
|
|
87
|
+
PPTX: "amber",
|
|
88
|
+
ODP: "amber",
|
|
89
|
+
MD: "neutral",
|
|
90
|
+
MARK: "neutral",
|
|
91
|
+
TXT: "neutral"
|
|
92
|
+
};
|
|
93
|
+
function fileTypeTone(fileType, fileName) {
|
|
94
|
+
return ICON_TONES[fileTypeLabel(fileType, fileName)] ?? "neutral";
|
|
95
|
+
}
|
|
96
|
+
function joinMeta(parts) {
|
|
97
|
+
return parts.filter((part) => part !== null && part !== void 0 && part !== "").join(" \xB7 ");
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// src/client/focus.ts
|
|
101
|
+
var pending = null;
|
|
102
|
+
function requestDocumentFocus(knowledgeId) {
|
|
103
|
+
pending = knowledgeId === "" ? null : knowledgeId;
|
|
104
|
+
}
|
|
105
|
+
function consumeDocumentFocus() {
|
|
106
|
+
const value = pending;
|
|
107
|
+
pending = null;
|
|
108
|
+
return value;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
// src/client/icons.tsx
|
|
32
112
|
var import_react = require("react");
|
|
33
|
-
|
|
34
|
-
|
|
113
|
+
var BASE = {
|
|
114
|
+
viewBox: "0 0 16 16",
|
|
115
|
+
width: 14,
|
|
116
|
+
height: 14,
|
|
117
|
+
fill: "none",
|
|
118
|
+
stroke: "currentColor",
|
|
119
|
+
strokeWidth: 1.5,
|
|
120
|
+
strokeLinecap: "round",
|
|
121
|
+
strokeLinejoin: "round",
|
|
122
|
+
"aria-hidden": true,
|
|
123
|
+
focusable: false
|
|
124
|
+
};
|
|
125
|
+
function IconRefresh() {
|
|
126
|
+
return (0, import_react.createElement)(
|
|
127
|
+
"svg",
|
|
128
|
+
BASE,
|
|
129
|
+
(0, import_react.createElement)("path", { d: "M13.4 7.2a5.4 5.4 0 1 0-.6 3.5" }),
|
|
130
|
+
(0, import_react.createElement)("path", { d: "M13.6 3.2v3.6h-3.6" })
|
|
131
|
+
);
|
|
132
|
+
}
|
|
133
|
+
function IconSearch() {
|
|
35
134
|
return (0, import_react.createElement)(
|
|
135
|
+
"svg",
|
|
136
|
+
BASE,
|
|
137
|
+
(0, import_react.createElement)("circle", { cx: 7, cy: 7, r: 4.3 }),
|
|
138
|
+
(0, import_react.createElement)("path", { d: "M10.3 10.3 13.8 13.8" })
|
|
139
|
+
);
|
|
140
|
+
}
|
|
141
|
+
function IconFile() {
|
|
142
|
+
return (0, import_react.createElement)(
|
|
143
|
+
"svg",
|
|
144
|
+
BASE,
|
|
145
|
+
(0, import_react.createElement)("path", { d: "M9.2 2H5a1.2 1.2 0 0 0-1.2 1.2v9.6A1.2 1.2 0 0 0 5 14h6a1.2 1.2 0 0 0 1.2-1.2V5z" }),
|
|
146
|
+
(0, import_react.createElement)("path", { d: "M9.2 2v3h3" })
|
|
147
|
+
);
|
|
148
|
+
}
|
|
149
|
+
function IconAlert() {
|
|
150
|
+
return (0, import_react.createElement)(
|
|
151
|
+
"svg",
|
|
152
|
+
BASE,
|
|
153
|
+
(0, import_react.createElement)("circle", { cx: 8, cy: 8, r: 6 }),
|
|
154
|
+
(0, import_react.createElement)("path", { d: "M8 5.2v3.4" }),
|
|
155
|
+
(0, import_react.createElement)("path", { d: "M8 11.1h.01" })
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
function IconInbox() {
|
|
159
|
+
return (0, import_react.createElement)(
|
|
160
|
+
"svg",
|
|
161
|
+
{ ...BASE, width: 22, height: 22, strokeWidth: 1.2 },
|
|
162
|
+
(0, import_react.createElement)("path", { d: "M2.2 9.4 4 3.6A1.4 1.4 0 0 1 5.3 2.6h5.4A1.4 1.4 0 0 1 12 3.6l1.8 5.8" }),
|
|
163
|
+
(0, import_react.createElement)("path", { d: "M2.2 9.4h3l.9 1.7h3.8l.9-1.7h3v3.4a1.4 1.4 0 0 1-1.4 1.4H3.6a1.4 1.4 0 0 1-1.4-1.4z" })
|
|
164
|
+
);
|
|
165
|
+
}
|
|
166
|
+
function IconCheck() {
|
|
167
|
+
return (0, import_react.createElement)("svg", BASE, (0, import_react.createElement)("path", { d: "M3.4 8.4 6.5 11.5 12.6 5" }));
|
|
168
|
+
}
|
|
169
|
+
function IconExternal() {
|
|
170
|
+
return (0, import_react.createElement)(
|
|
171
|
+
"svg",
|
|
172
|
+
BASE,
|
|
173
|
+
(0, import_react.createElement)("path", { d: "M9.4 3.2h3.4v3.4" }),
|
|
174
|
+
(0, import_react.createElement)("path", { d: "M12.8 3.2 7.4 8.6" }),
|
|
175
|
+
(0, import_react.createElement)("path", { d: "M12 9.6v2.6a1.2 1.2 0 0 1-1.2 1.2H4.3a1.2 1.2 0 0 1-1.2-1.2V5.7a1.2 1.2 0 0 1 1.2-1.2h2.6" })
|
|
176
|
+
);
|
|
177
|
+
}
|
|
178
|
+
function IconMessage() {
|
|
179
|
+
return (0, import_react.createElement)(
|
|
180
|
+
"svg",
|
|
181
|
+
BASE,
|
|
182
|
+
(0, import_react.createElement)("path", { d: "M13.4 7.8c0 2.6-2.4 4.7-5.4 4.7-.7 0-1.4-.1-2-.3L3 13.4l.9-2.4A4.4 4.4 0 0 1 2.6 7.8C2.6 5.2 5 3.2 8 3.2s5.4 2 5.4 4.6Z" })
|
|
183
|
+
);
|
|
184
|
+
}
|
|
185
|
+
|
|
186
|
+
// src/client/KnowledgeView.tsx
|
|
187
|
+
function notice(key, className, content, action) {
|
|
188
|
+
return (0, import_react2.createElement)(
|
|
189
|
+
"div",
|
|
190
|
+
{ key, className, role: "status" },
|
|
191
|
+
(0, import_react2.createElement)("span", { className: "hiwork-knowledge-notice-icon" }, (0, import_react2.createElement)(IconAlert)),
|
|
192
|
+
(0, import_react2.createElement)("span", { className: "hiwork-knowledge-notice-text" }, content),
|
|
193
|
+
action ?? null
|
|
194
|
+
);
|
|
195
|
+
}
|
|
196
|
+
function emptyState(key, message) {
|
|
197
|
+
return (0, import_react2.createElement)(
|
|
198
|
+
"div",
|
|
199
|
+
{ key, className: "hiwork-knowledge-empty" },
|
|
200
|
+
(0, import_react2.createElement)("span", { className: "hiwork-knowledge-empty-icon" }, (0, import_react2.createElement)(IconInbox)),
|
|
201
|
+
(0, import_react2.createElement)("span", null, message)
|
|
202
|
+
);
|
|
203
|
+
}
|
|
204
|
+
function bringToChat(t, paste, prompt, className, label) {
|
|
205
|
+
if (paste === void 0) return null;
|
|
206
|
+
return (0, import_react2.createElement)(
|
|
207
|
+
"button",
|
|
208
|
+
{
|
|
209
|
+
type: "button",
|
|
210
|
+
className,
|
|
211
|
+
title: label,
|
|
212
|
+
onClick: () => {
|
|
213
|
+
paste(prompt());
|
|
214
|
+
}
|
|
215
|
+
},
|
|
216
|
+
(0, import_react2.createElement)(IconMessage),
|
|
217
|
+
label
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
function KnowledgeView(props) {
|
|
221
|
+
const { t, runtime, closeSettings, putInComposer } = props;
|
|
222
|
+
const state = (0, import_react2.useSyncExternalStore)(
|
|
223
|
+
runtime.source.subscribe,
|
|
224
|
+
runtime.source.getSnapshot,
|
|
225
|
+
runtime.source.getServerSnapshot ?? runtime.source.getSnapshot
|
|
226
|
+
);
|
|
227
|
+
const snapshot = state.snapshot;
|
|
228
|
+
const bases = (0, import_react2.useMemo)(() => snapshot?.bases ?? [], [snapshot]);
|
|
229
|
+
const [selectedBaseId, setSelectedBaseId] = (0, import_react2.useState)("");
|
|
230
|
+
const [docs, setDocs] = (0, import_react2.useState)([]);
|
|
231
|
+
const [docsLoading, setDocsLoading] = (0, import_react2.useState)(false);
|
|
232
|
+
const [docsError, setDocsError] = (0, import_react2.useState)("");
|
|
233
|
+
const [query, setQuery] = (0, import_react2.useState)("");
|
|
234
|
+
const [hits, setHits] = (0, import_react2.useState)(null);
|
|
235
|
+
const [searching, setSearching] = (0, import_react2.useState)(false);
|
|
236
|
+
const [doc, setDoc] = (0, import_react2.useState)(null);
|
|
237
|
+
const [docLoading, setDocLoading] = (0, import_react2.useState)(false);
|
|
238
|
+
const [docError, setDocError] = (0, import_react2.useState)("");
|
|
239
|
+
const [insertResult, setInsertResult] = (0, import_react2.useState)(null);
|
|
240
|
+
(0, import_react2.useEffect)(() => {
|
|
241
|
+
if (selectedBaseId !== "" && bases.some((base) => base.id === selectedBaseId)) return;
|
|
242
|
+
setSelectedBaseId(bases[0]?.id ?? "");
|
|
243
|
+
}, [bases, selectedBaseId]);
|
|
244
|
+
(0, import_react2.useEffect)(() => {
|
|
245
|
+
if (selectedBaseId === "") {
|
|
246
|
+
setDocs([]);
|
|
247
|
+
return;
|
|
248
|
+
}
|
|
249
|
+
let cancelled = false;
|
|
250
|
+
setDocsLoading(true);
|
|
251
|
+
setDocsError("");
|
|
252
|
+
runtime.loadDocs(selectedBaseId).then((next) => {
|
|
253
|
+
if (!cancelled) setDocs(next);
|
|
254
|
+
}).catch((error) => {
|
|
255
|
+
if (!cancelled) setDocsError(error instanceof Error ? error.message : String(error));
|
|
256
|
+
}).finally(() => {
|
|
257
|
+
if (!cancelled) setDocsLoading(false);
|
|
258
|
+
});
|
|
259
|
+
return () => {
|
|
260
|
+
cancelled = true;
|
|
261
|
+
};
|
|
262
|
+
}, [selectedBaseId, runtime]);
|
|
263
|
+
const openDocument = (0, import_react2.useCallback)(
|
|
264
|
+
(knowledgeId, page) => {
|
|
265
|
+
setDocLoading(true);
|
|
266
|
+
setDocError("");
|
|
267
|
+
runtime.loadDocument(knowledgeId, page).then(setDoc).catch((error) => setDocError(error instanceof Error ? error.message : String(error))).finally(() => setDocLoading(false));
|
|
268
|
+
},
|
|
269
|
+
[runtime]
|
|
270
|
+
);
|
|
271
|
+
(0, import_react2.useEffect)(() => {
|
|
272
|
+
const knowledgeId = consumeDocumentFocus();
|
|
273
|
+
if (knowledgeId === null) return;
|
|
274
|
+
openDocument(knowledgeId);
|
|
275
|
+
}, [openDocument]);
|
|
276
|
+
const runSearch = (0, import_react2.useCallback)(() => {
|
|
277
|
+
const trimmed = query.trim();
|
|
278
|
+
if (trimmed === "") return;
|
|
279
|
+
setSearching(true);
|
|
280
|
+
setDoc(null);
|
|
281
|
+
runtime.search(trimmed, selectedBaseId === "" ? void 0 : selectedBaseId).then(setHits).catch((error) => setDocsError(error instanceof Error ? error.message : String(error))).finally(() => setSearching(false));
|
|
282
|
+
}, [query, selectedBaseId, runtime]);
|
|
283
|
+
const warnings = (0, import_react2.useMemo)(
|
|
284
|
+
() => (snapshot?.selfCheck?.items ?? []).filter((item) => !item.ok && item.level !== "info"),
|
|
285
|
+
[snapshot]
|
|
286
|
+
);
|
|
287
|
+
const send = (0, import_react2.useCallback)(
|
|
288
|
+
(text) => {
|
|
289
|
+
const result = putInComposer?.(text);
|
|
290
|
+
if (result === void 0) return;
|
|
291
|
+
setInsertResult(result);
|
|
292
|
+
},
|
|
293
|
+
[putInComposer]
|
|
294
|
+
);
|
|
295
|
+
const selectedBase = bases.find((base) => base.id === selectedBaseId);
|
|
296
|
+
const showingHits = hits !== null;
|
|
297
|
+
const showingDoc = doc !== null;
|
|
298
|
+
const pageCount = doc === null ? 1 : Math.max(1, Math.ceil(doc.chunkTotal / Math.max(1, doc.pageSize)));
|
|
299
|
+
return (0, import_react2.createElement)(
|
|
36
300
|
"section",
|
|
37
301
|
{ className: "hiwork-knowledge-view", "aria-label": t("view.title") },
|
|
38
|
-
(0,
|
|
302
|
+
(0, import_react2.createElement)(
|
|
39
303
|
"header",
|
|
40
304
|
{ className: "hiwork-knowledge-header" },
|
|
41
|
-
(0,
|
|
305
|
+
(0, import_react2.createElement)(
|
|
42
306
|
"div",
|
|
43
307
|
{ className: "hiwork-knowledge-heading" },
|
|
44
|
-
(0,
|
|
45
|
-
(0,
|
|
308
|
+
(0, import_react2.createElement)("h1", { className: "hiwork-knowledge-title" }, t("view.title")),
|
|
309
|
+
(0, import_react2.createElement)("p", { className: "hiwork-knowledge-subtitle" }, t("view.subtitle"))
|
|
310
|
+
),
|
|
311
|
+
(0, import_react2.createElement)(
|
|
312
|
+
"div",
|
|
313
|
+
{ className: "hiwork-knowledge-toolbar" },
|
|
314
|
+
insertResult === null || putInComposer === void 0 ? null : insertResult.ok ? (0, import_react2.createElement)("span", { className: "hiwork-knowledge-sent" }, t("doc.chatSent")) : (0, import_react2.createElement)(
|
|
315
|
+
"span",
|
|
316
|
+
{ className: "hiwork-knowledge-send-failed", role: "status" },
|
|
317
|
+
t("doc.chatFailed", { reason: t(`doc.chatFailed.${insertResult.reason}`) })
|
|
318
|
+
),
|
|
319
|
+
(0, import_react2.createElement)(
|
|
320
|
+
"button",
|
|
321
|
+
{
|
|
322
|
+
type: "button",
|
|
323
|
+
className: "hiwork-knowledge-button",
|
|
324
|
+
onClick: () => {
|
|
325
|
+
void runtime.refresh();
|
|
326
|
+
}
|
|
327
|
+
},
|
|
328
|
+
(0, import_react2.createElement)("span", { className: "hiwork-knowledge-button-icon" }, (0, import_react2.createElement)(IconRefresh)),
|
|
329
|
+
t("view.refresh")
|
|
330
|
+
),
|
|
331
|
+
closeSettings === void 0 ? null : (0, import_react2.createElement)("button", { type: "button", className: "hiwork-knowledge-button", onClick: closeSettings }, t("view.close"))
|
|
332
|
+
)
|
|
333
|
+
),
|
|
334
|
+
state.phase === "loading" && snapshot === void 0 ? (0, import_react2.createElement)("div", { className: "hiwork-knowledge-notice" }, t("state.loading")) : null,
|
|
335
|
+
snapshot?.lastError == null ? null : notice(
|
|
336
|
+
"last-error",
|
|
337
|
+
"hiwork-knowledge-notice is-error",
|
|
338
|
+
`${t("state.error")}\uFF1A${snapshot.lastError}`,
|
|
339
|
+
(0, import_react2.createElement)(
|
|
340
|
+
"button",
|
|
341
|
+
{
|
|
342
|
+
type: "button",
|
|
343
|
+
className: "hiwork-knowledge-button",
|
|
344
|
+
onClick: () => {
|
|
345
|
+
void runtime.refresh();
|
|
346
|
+
}
|
|
347
|
+
},
|
|
348
|
+
t("state.retry")
|
|
349
|
+
)
|
|
350
|
+
),
|
|
351
|
+
...warnings.map((item) => notice(item.code, "hiwork-knowledge-notice is-warn", item.message)),
|
|
352
|
+
(0, import_react2.createElement)(
|
|
353
|
+
"div",
|
|
354
|
+
{ className: "hiwork-knowledge-columns" },
|
|
355
|
+
(0, import_react2.createElement)(
|
|
356
|
+
"section",
|
|
357
|
+
{ className: "hiwork-knowledge-panel is-bases" },
|
|
358
|
+
(0, import_react2.createElement)(
|
|
359
|
+
"div",
|
|
360
|
+
{ className: "hiwork-knowledge-panel-head" },
|
|
361
|
+
(0, import_react2.createElement)("h2", { className: "hiwork-knowledge-panel-title" }, t("bases.title")),
|
|
362
|
+
(0, import_react2.createElement)("span", { className: "hiwork-knowledge-count" }, String(bases.length))
|
|
363
|
+
),
|
|
364
|
+
(0, import_react2.createElement)(
|
|
365
|
+
"div",
|
|
366
|
+
{ className: "hiwork-knowledge-scroll" },
|
|
367
|
+
bases.length === 0 ? emptyState("bases-empty", t("bases.empty")) : (0, import_react2.createElement)(
|
|
368
|
+
"ul",
|
|
369
|
+
{ className: "hiwork-knowledge-list" },
|
|
370
|
+
...bases.map((base) => {
|
|
371
|
+
const active = base.id === selectedBaseId;
|
|
372
|
+
const meta = joinMeta([
|
|
373
|
+
base.documentCount === null ? "" : t("bases.meta.docs", { count: base.documentCount }),
|
|
374
|
+
formatDate(base.updatedAt) === "" ? "" : t("bases.meta.updated", { value: formatDate(base.updatedAt) })
|
|
375
|
+
]);
|
|
376
|
+
const itemProps = {
|
|
377
|
+
key: base.id,
|
|
378
|
+
type: "button",
|
|
379
|
+
className: active ? "hiwork-knowledge-base is-active" : "hiwork-knowledge-base",
|
|
380
|
+
"aria-label": t("bases.select", { name: base.name }),
|
|
381
|
+
onClick: () => {
|
|
382
|
+
setSelectedBaseId(base.id);
|
|
383
|
+
setDoc(null);
|
|
384
|
+
setHits(null);
|
|
385
|
+
}
|
|
386
|
+
};
|
|
387
|
+
if (active) itemProps["aria-current"] = "true";
|
|
388
|
+
return (0, import_react2.createElement)(
|
|
389
|
+
"li",
|
|
390
|
+
{ key: base.id },
|
|
391
|
+
(0, import_react2.createElement)(
|
|
392
|
+
"button",
|
|
393
|
+
itemProps,
|
|
394
|
+
(0, import_react2.createElement)("span", { className: "hiwork-knowledge-base-name", title: base.name }, base.name),
|
|
395
|
+
base.description === "" ? null : (0, import_react2.createElement)("span", { className: "hiwork-knowledge-base-desc", title: base.description }, base.description),
|
|
396
|
+
meta === "" ? null : (0, import_react2.createElement)("span", { className: "hiwork-knowledge-base-meta" }, meta)
|
|
397
|
+
)
|
|
398
|
+
);
|
|
399
|
+
})
|
|
400
|
+
)
|
|
401
|
+
)
|
|
402
|
+
),
|
|
403
|
+
(0, import_react2.createElement)(
|
|
404
|
+
"section",
|
|
405
|
+
{ className: "hiwork-knowledge-panel is-detail" },
|
|
406
|
+
// 正文态:检索行让位给「返回列表 + 文档信息 + 翻页」。
|
|
407
|
+
showingDoc ? (0, import_react2.createElement)(
|
|
408
|
+
"div",
|
|
409
|
+
{ className: "hiwork-knowledge-panel-head" },
|
|
410
|
+
(0, import_react2.createElement)(
|
|
411
|
+
"button",
|
|
412
|
+
{
|
|
413
|
+
type: "button",
|
|
414
|
+
className: "hiwork-knowledge-button hiwork-knowledge-doc-back",
|
|
415
|
+
onClick: () => setDoc(null)
|
|
416
|
+
},
|
|
417
|
+
t("doc.back")
|
|
418
|
+
),
|
|
419
|
+
(0, import_react2.createElement)("h2", { className: "hiwork-knowledge-panel-title", title: doc.title }, doc.title),
|
|
420
|
+
(0, import_react2.createElement)("span", { className: "hiwork-knowledge-count" }, t("doc.chunkTotal", { count: doc.chunkTotal })),
|
|
421
|
+
(0, import_react2.createElement)(
|
|
422
|
+
"span",
|
|
423
|
+
{ className: "hiwork-knowledge-pager" },
|
|
424
|
+
(0, import_react2.createElement)("span", { className: "hiwork-knowledge-pager-info" }, t("doc.page", { page: doc.page, total: pageCount })),
|
|
425
|
+
(0, import_react2.createElement)(
|
|
426
|
+
"button",
|
|
427
|
+
{
|
|
428
|
+
type: "button",
|
|
429
|
+
className: "hiwork-knowledge-button",
|
|
430
|
+
disabled: doc.page <= 1,
|
|
431
|
+
onClick: () => openDocument(doc.knowledgeId, doc.page - 1)
|
|
432
|
+
},
|
|
433
|
+
t("doc.prev")
|
|
434
|
+
),
|
|
435
|
+
(0, import_react2.createElement)(
|
|
436
|
+
"button",
|
|
437
|
+
{
|
|
438
|
+
type: "button",
|
|
439
|
+
className: "hiwork-knowledge-button",
|
|
440
|
+
disabled: doc.page >= pageCount,
|
|
441
|
+
onClick: () => openDocument(doc.knowledgeId, doc.page + 1)
|
|
442
|
+
},
|
|
443
|
+
t("doc.next")
|
|
444
|
+
)
|
|
445
|
+
),
|
|
446
|
+
bringToChat(
|
|
447
|
+
t,
|
|
448
|
+
send,
|
|
449
|
+
() => t("doc.chatPrompt", { title: doc.title }),
|
|
450
|
+
"hiwork-knowledge-button is-primary",
|
|
451
|
+
t("doc.bringToChat")
|
|
452
|
+
)
|
|
453
|
+
) : (0, import_react2.createElement)(
|
|
454
|
+
"div",
|
|
455
|
+
{ className: "hiwork-knowledge-search" },
|
|
456
|
+
(0, import_react2.createElement)(
|
|
457
|
+
"span",
|
|
458
|
+
{ className: "hiwork-knowledge-search-field" },
|
|
459
|
+
(0, import_react2.createElement)("span", { className: "hiwork-knowledge-search-icon" }, (0, import_react2.createElement)(IconSearch)),
|
|
460
|
+
(0, import_react2.createElement)("input", {
|
|
461
|
+
className: "hiwork-knowledge-input",
|
|
462
|
+
value: query,
|
|
463
|
+
placeholder: t("search.placeholder"),
|
|
464
|
+
"aria-label": t("search.placeholder"),
|
|
465
|
+
onChange: (event) => setQuery(event.target.value),
|
|
466
|
+
onKeyDown: (event) => {
|
|
467
|
+
if (event.key === "Enter") runSearch();
|
|
468
|
+
}
|
|
469
|
+
})
|
|
470
|
+
),
|
|
471
|
+
(0, import_react2.createElement)(
|
|
472
|
+
"button",
|
|
473
|
+
{ type: "button", className: "hiwork-knowledge-button is-primary", disabled: searching, onClick: runSearch },
|
|
474
|
+
searching ? t("search.running") : t("search.button")
|
|
475
|
+
)
|
|
476
|
+
),
|
|
477
|
+
showingDoc ? null : (0, import_react2.createElement)(
|
|
478
|
+
"div",
|
|
479
|
+
{ className: "hiwork-knowledge-panel-head" },
|
|
480
|
+
(0, import_react2.createElement)("h2", { className: "hiwork-knowledge-panel-title" }, showingHits ? t("search.hitCount") : t("docs.title")),
|
|
481
|
+
(0, import_react2.createElement)(
|
|
482
|
+
"span",
|
|
483
|
+
{ className: "hiwork-knowledge-scope", title: selectedBase?.name ?? t("docs.scope.all") },
|
|
484
|
+
selectedBase?.name ?? t("docs.scope.all")
|
|
485
|
+
),
|
|
486
|
+
(0, import_react2.createElement)("span", { className: "hiwork-knowledge-count" }, showingHits ? String(hits.length) : String(docs.length)),
|
|
487
|
+
showingHits ? (0, import_react2.createElement)(
|
|
488
|
+
"button",
|
|
489
|
+
{ type: "button", className: "hiwork-knowledge-button", onClick: () => setHits(null) },
|
|
490
|
+
t("search.clear")
|
|
491
|
+
) : null
|
|
492
|
+
),
|
|
493
|
+
docsError === "" ? null : (0, import_react2.createElement)("div", { className: "hiwork-knowledge-notice is-error" }, docsError),
|
|
494
|
+
docError === "" ? null : (0, import_react2.createElement)("div", { className: "hiwork-knowledge-notice is-error" }, docError),
|
|
495
|
+
(0, import_react2.createElement)(
|
|
496
|
+
"div",
|
|
497
|
+
{ className: "hiwork-knowledge-scroll" },
|
|
498
|
+
showingDoc ? docLoading ? (0, import_react2.createElement)("div", { className: "hiwork-knowledge-status" }, t("doc.loading")) : doc.chunks.length === 0 ? emptyState("doc-empty", t("doc.empty")) : (0, import_react2.createElement)(
|
|
499
|
+
"ul",
|
|
500
|
+
{ className: "hiwork-knowledge-list" },
|
|
501
|
+
...doc.chunks.map(
|
|
502
|
+
(chunk, index) => (0, import_react2.createElement)(
|
|
503
|
+
"li",
|
|
504
|
+
{ key: `${chunk.index ?? index}`, className: "hiwork-knowledge-chunk" },
|
|
505
|
+
(0, import_react2.createElement)(
|
|
506
|
+
"div",
|
|
507
|
+
{ className: "hiwork-knowledge-chunk-head" },
|
|
508
|
+
chunk.index === null ? null : (0, import_react2.createElement)("span", { className: "hiwork-knowledge-chunk-index" }, `#${chunk.index}`),
|
|
509
|
+
chunk.truncated ? (0, import_react2.createElement)("span", { className: "hiwork-knowledge-tag is-warning" }, t("search.truncated")) : null,
|
|
510
|
+
bringToChat(
|
|
511
|
+
t,
|
|
512
|
+
send,
|
|
513
|
+
() => t("doc.chunkChatPrompt", {
|
|
514
|
+
title: doc.title,
|
|
515
|
+
segment: chunk.index === null ? "" : t("card.segment", { index: chunk.index })
|
|
516
|
+
}),
|
|
517
|
+
"hiwork-knowledge-tool-action",
|
|
518
|
+
t("doc.bringChunkToChat")
|
|
519
|
+
)
|
|
520
|
+
),
|
|
521
|
+
(0, import_react2.createElement)("p", { className: "hiwork-knowledge-chunk-body" }, chunk.content)
|
|
522
|
+
)
|
|
523
|
+
)
|
|
524
|
+
) : showingHits ? hits.length === 0 ? emptyState("hits-empty", t("search.empty")) : (0, import_react2.createElement)(
|
|
525
|
+
"ul",
|
|
526
|
+
{ className: "hiwork-knowledge-list" },
|
|
527
|
+
...hits.map(
|
|
528
|
+
(hit) => (0, import_react2.createElement)(
|
|
529
|
+
"li",
|
|
530
|
+
{ key: hit.chunkId, className: "hiwork-knowledge-hit" },
|
|
531
|
+
(0, import_react2.createElement)(
|
|
532
|
+
"div",
|
|
533
|
+
{ className: "hiwork-knowledge-hit-head" },
|
|
534
|
+
(0, import_react2.createElement)("span", { className: "hiwork-knowledge-hit-title", title: hit.knowledgeTitle }, hit.knowledgeTitle),
|
|
535
|
+
hit.chunkIndex === null ? null : (0, import_react2.createElement)("span", { className: "hiwork-knowledge-tag is-neutral" }, `#${hit.chunkIndex}`),
|
|
536
|
+
hit.truncated ? (0, import_react2.createElement)("span", { className: "hiwork-knowledge-tag is-warning" }, t("search.truncated")) : null,
|
|
537
|
+
hit.fileName !== "" && hit.fileName !== hit.knowledgeTitle ? (0, import_react2.createElement)("span", { className: "hiwork-knowledge-hit-source", title: hit.fileName }, hit.fileName) : null,
|
|
538
|
+
(0, import_react2.createElement)(
|
|
539
|
+
"span",
|
|
540
|
+
{ className: "hiwork-knowledge-tool-hit-actions" },
|
|
541
|
+
(0, import_react2.createElement)(
|
|
542
|
+
"button",
|
|
543
|
+
{
|
|
544
|
+
type: "button",
|
|
545
|
+
className: "hiwork-knowledge-tool-action",
|
|
546
|
+
title: t("doc.read"),
|
|
547
|
+
onClick: () => openDocument(hit.knowledgeId)
|
|
548
|
+
},
|
|
549
|
+
(0, import_react2.createElement)(IconExternal),
|
|
550
|
+
t("doc.read")
|
|
551
|
+
),
|
|
552
|
+
bringToChat(
|
|
553
|
+
t,
|
|
554
|
+
send,
|
|
555
|
+
() => t("doc.chunkChatPrompt", {
|
|
556
|
+
title: hit.knowledgeTitle,
|
|
557
|
+
segment: hit.chunkIndex === null ? "" : t("card.segment", { index: hit.chunkIndex })
|
|
558
|
+
}),
|
|
559
|
+
"hiwork-knowledge-tool-action",
|
|
560
|
+
t("doc.bringChunkToChat")
|
|
561
|
+
)
|
|
562
|
+
)
|
|
563
|
+
),
|
|
564
|
+
(0, import_react2.createElement)("p", { className: "hiwork-knowledge-hit-body" }, hit.content)
|
|
565
|
+
)
|
|
566
|
+
)
|
|
567
|
+
) : docsLoading ? (0, import_react2.createElement)("div", { className: "hiwork-knowledge-status" }, t("docs.loading")) : docs.length === 0 ? emptyState("docs-empty", t("docs.empty")) : (0, import_react2.createElement)(
|
|
568
|
+
"ul",
|
|
569
|
+
{ className: "hiwork-knowledge-list" },
|
|
570
|
+
...docs.map((item) => {
|
|
571
|
+
const statusKey = parseStatusKey(item.parseStatus);
|
|
572
|
+
const ext = fileTypeLabel(item.fileType, item.fileName);
|
|
573
|
+
return (0, import_react2.createElement)(
|
|
574
|
+
"li",
|
|
575
|
+
{ key: item.id, className: "hiwork-knowledge-doc" },
|
|
576
|
+
(0, import_react2.createElement)(
|
|
577
|
+
"span",
|
|
578
|
+
{
|
|
579
|
+
className: `hiwork-knowledge-doc-icon is-${fileTypeTone(item.fileType, item.fileName)}`,
|
|
580
|
+
"aria-hidden": true
|
|
581
|
+
},
|
|
582
|
+
ext === "" ? (0, import_react2.createElement)(IconFile) : ext
|
|
583
|
+
),
|
|
584
|
+
(0, import_react2.createElement)(
|
|
585
|
+
"button",
|
|
586
|
+
{
|
|
587
|
+
type: "button",
|
|
588
|
+
className: "hiwork-knowledge-doc-main is-button",
|
|
589
|
+
title: t("doc.read"),
|
|
590
|
+
onClick: () => openDocument(item.id)
|
|
591
|
+
},
|
|
592
|
+
(0, import_react2.createElement)("span", { className: "hiwork-knowledge-doc-title", title: item.title }, item.title),
|
|
593
|
+
(0, import_react2.createElement)(
|
|
594
|
+
"span",
|
|
595
|
+
{ className: "hiwork-knowledge-doc-meta" },
|
|
596
|
+
// 扩展名不重复放进 meta:左侧徽标已经写了类型,16px 内说两遍
|
|
597
|
+
// 同一件事只会把这一行撑长、把真正有用的体积/时间挤到后面。
|
|
598
|
+
joinMeta([formatSize(item.fileSize), formatDate(item.createdAt)])
|
|
599
|
+
)
|
|
600
|
+
),
|
|
601
|
+
(0, import_react2.createElement)(
|
|
602
|
+
"span",
|
|
603
|
+
{ className: `hiwork-knowledge-tag is-${statusTone(item.parseStatus)}` },
|
|
604
|
+
statusKey === null ? item.parseStatus : t(statusKey)
|
|
605
|
+
)
|
|
606
|
+
);
|
|
607
|
+
})
|
|
608
|
+
)
|
|
609
|
+
)
|
|
610
|
+
)
|
|
611
|
+
)
|
|
612
|
+
);
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
// src/client/SettingsSection.tsx
|
|
616
|
+
var import_react3 = require("react");
|
|
617
|
+
function parseBaseIds(raw) {
|
|
618
|
+
return raw.split(/[,,\n]/).map((item) => item.trim()).filter((item) => item !== "");
|
|
619
|
+
}
|
|
620
|
+
function formFromSnapshot(config) {
|
|
621
|
+
return {
|
|
622
|
+
baseUrl: config.baseUrl,
|
|
623
|
+
apiKey: "",
|
|
624
|
+
tenantId: config.tenantId,
|
|
625
|
+
defaultBases: config.defaultBaseIds.join(", "),
|
|
626
|
+
maxResults: String(config.maxResults),
|
|
627
|
+
maxChunkChars: String(config.maxChunkChars),
|
|
628
|
+
agentId: config.agentId,
|
|
629
|
+
chatModelId: config.chatModelId
|
|
630
|
+
};
|
|
631
|
+
}
|
|
632
|
+
function patchFromForm(form, initial) {
|
|
633
|
+
const patch = {};
|
|
634
|
+
if (form.baseUrl !== initial.baseUrl) patch["baseUrl"] = form.baseUrl;
|
|
635
|
+
if (form.apiKey !== "") patch["apiKey"] = form.apiKey;
|
|
636
|
+
if (form.tenantId !== initial.tenantId) patch["tenantId"] = form.tenantId;
|
|
637
|
+
if (form.defaultBases !== initial.defaultBases) patch["defaultBaseIds"] = parseBaseIds(form.defaultBases);
|
|
638
|
+
if (form.maxResults !== initial.maxResults) patch["maxResults"] = Number(form.maxResults);
|
|
639
|
+
if (form.maxChunkChars !== initial.maxChunkChars) patch["maxChunkChars"] = Number(form.maxChunkChars);
|
|
640
|
+
if (form.agentId !== initial.agentId) patch["agentId"] = form.agentId;
|
|
641
|
+
if (form.chatModelId !== initial.chatModelId) patch["chatModelId"] = form.chatModelId;
|
|
642
|
+
return patch;
|
|
643
|
+
}
|
|
644
|
+
function KnowledgeSettings(props) {
|
|
645
|
+
const { t, runtime } = props;
|
|
646
|
+
const close = props.close ?? props.closeSettings;
|
|
647
|
+
const state = (0, import_react3.useSyncExternalStore)(
|
|
648
|
+
runtime.source.subscribe,
|
|
649
|
+
runtime.source.getSnapshot,
|
|
650
|
+
runtime.source.getServerSnapshot ?? runtime.source.getSnapshot
|
|
651
|
+
);
|
|
652
|
+
const config = state.snapshot?.config;
|
|
653
|
+
const [form, setForm] = (0, import_react3.useState)(null);
|
|
654
|
+
const [initial, setInitial] = (0, import_react3.useState)(null);
|
|
655
|
+
const [status, setStatus] = (0, import_react3.useState)("idle");
|
|
656
|
+
const [message, setMessage] = (0, import_react3.useState)("");
|
|
657
|
+
(0, import_react3.useEffect)(() => {
|
|
658
|
+
if (config === void 0) return;
|
|
659
|
+
if (form !== null) return;
|
|
660
|
+
const next = formFromSnapshot(config);
|
|
661
|
+
setForm(next);
|
|
662
|
+
setInitial(next);
|
|
663
|
+
}, [config, form]);
|
|
664
|
+
const save = (0, import_react3.useCallback)(() => {
|
|
665
|
+
if (form === null || initial === null) return;
|
|
666
|
+
setStatus("saving");
|
|
667
|
+
setMessage("");
|
|
668
|
+
runtime.saveConfig(patchFromForm(form, initial)).then(() => {
|
|
669
|
+
setStatus("saved");
|
|
670
|
+
const next = formFromSnapshot(config ?? {
|
|
671
|
+
baseUrl: form.baseUrl,
|
|
672
|
+
tenantId: form.tenantId,
|
|
673
|
+
defaultBaseIds: parseBaseIds(form.defaultBases),
|
|
674
|
+
maxResults: Number(form.maxResults),
|
|
675
|
+
maxChunkChars: Number(form.maxChunkChars),
|
|
676
|
+
agentId: form.agentId,
|
|
677
|
+
chatModelId: form.chatModelId
|
|
678
|
+
});
|
|
679
|
+
setForm(next);
|
|
680
|
+
setInitial(next);
|
|
681
|
+
}).catch((error) => {
|
|
682
|
+
setStatus("error");
|
|
683
|
+
setMessage(error instanceof Error ? error.message : String(error));
|
|
684
|
+
});
|
|
685
|
+
}, [form, initial, runtime, config]);
|
|
686
|
+
const test = (0, import_react3.useCallback)(() => {
|
|
687
|
+
setStatus("testing");
|
|
688
|
+
setMessage("");
|
|
689
|
+
runtime.testConnection().then((result) => {
|
|
690
|
+
setStatus(result.level === "error" ? "error" : "idle");
|
|
691
|
+
}).catch((error) => {
|
|
692
|
+
setStatus("error");
|
|
693
|
+
setMessage(error instanceof Error ? error.message : String(error));
|
|
694
|
+
});
|
|
695
|
+
}, [runtime]);
|
|
696
|
+
if (form === null) {
|
|
697
|
+
return (0, import_react3.createElement)(
|
|
698
|
+
"section",
|
|
699
|
+
{ className: "hiwork-knowledge-view", "aria-label": t("settings.title") },
|
|
700
|
+
(0, import_react3.createElement)("p", { className: "hiwork-knowledge-muted" }, t("state.loading")),
|
|
701
|
+
state.error === void 0 ? null : (0, import_react3.createElement)(
|
|
702
|
+
"div",
|
|
703
|
+
{ className: "hiwork-knowledge-notice is-error" },
|
|
704
|
+
state.error,
|
|
705
|
+
(0, import_react3.createElement)(
|
|
706
|
+
"button",
|
|
707
|
+
{
|
|
708
|
+
type: "button",
|
|
709
|
+
className: "hiwork-knowledge-button",
|
|
710
|
+
onClick: () => {
|
|
711
|
+
void runtime.refresh();
|
|
712
|
+
}
|
|
713
|
+
},
|
|
714
|
+
t("state.retry")
|
|
715
|
+
)
|
|
716
|
+
)
|
|
717
|
+
);
|
|
718
|
+
}
|
|
719
|
+
const field = (label, value, onChange, placeholder, hint, type, wide = false) => (0, import_react3.createElement)(
|
|
720
|
+
"label",
|
|
721
|
+
{ className: wide ? "hiwork-knowledge-field is-wide" : "hiwork-knowledge-field" },
|
|
722
|
+
(0, import_react3.createElement)("span", { className: "hiwork-knowledge-field-label" }, label),
|
|
723
|
+
(0, import_react3.createElement)("input", {
|
|
724
|
+
className: "hiwork-knowledge-input",
|
|
725
|
+
value,
|
|
726
|
+
type: type ?? "text",
|
|
727
|
+
...placeholder === void 0 ? {} : { placeholder },
|
|
728
|
+
onChange: (event) => onChange(event.target.value)
|
|
729
|
+
}),
|
|
730
|
+
hint === void 0 ? null : (0, import_react3.createElement)("span", { className: "hiwork-knowledge-field-hint" }, hint)
|
|
731
|
+
);
|
|
732
|
+
const selfCheck = state.snapshot?.selfCheck ?? null;
|
|
733
|
+
return (0, import_react3.createElement)(
|
|
734
|
+
"section",
|
|
735
|
+
{ className: "hiwork-knowledge-view", "aria-label": t("settings.title") },
|
|
736
|
+
(0, import_react3.createElement)(
|
|
737
|
+
"header",
|
|
738
|
+
{ className: "hiwork-knowledge-header" },
|
|
739
|
+
(0, import_react3.createElement)(
|
|
740
|
+
"div",
|
|
741
|
+
{ className: "hiwork-knowledge-heading" },
|
|
742
|
+
(0, import_react3.createElement)("h2", { className: "hiwork-knowledge-title" }, t("settings.title")),
|
|
743
|
+
(0, import_react3.createElement)("p", { className: "hiwork-knowledge-subtitle" }, t("settings.subtitle"))
|
|
744
|
+
),
|
|
745
|
+
close === void 0 ? null : (0, import_react3.createElement)("button", { type: "button", className: "hiwork-knowledge-button", onClick: close }, t("view.close"))
|
|
746
|
+
),
|
|
747
|
+
(0, import_react3.createElement)(
|
|
748
|
+
"div",
|
|
749
|
+
{ className: "hiwork-knowledge-form" },
|
|
750
|
+
field(t("settings.baseUrl"), form.baseUrl, (value) => setForm({ ...form, baseUrl: value }), void 0, t("settings.baseUrlHint"), "text", true),
|
|
751
|
+
field(
|
|
752
|
+
t("settings.apiKey"),
|
|
753
|
+
form.apiKey,
|
|
754
|
+
(value) => setForm({ ...form, apiKey: value }),
|
|
755
|
+
t("settings.apiKeyPlaceholder"),
|
|
756
|
+
// 凭据来源并进这一行提示:它原本是一个独立的 <p>,而栅格容器会把每个直接子元素
|
|
757
|
+
// 当成一个格子,于是它自己占掉半行,把右侧那一列的整体顺位挤歪了(截图里
|
|
758
|
+
// 「空间 ID」看起来悬空、与左侧任何字段都对不上,就是这么来的)。
|
|
759
|
+
`${config?.hasApiKey === true ? t("settings.apiKeyConfigured") : t("settings.apiKeyMissing")} \xB7 ${t("settings.apiKeySource")}\uFF1A${t(
|
|
760
|
+
`settings.apiKeySource.${config?.apiKeySource ?? "none"}`
|
|
761
|
+
)} \xB7 ${t("settings.apiKeyKeep")}`,
|
|
762
|
+
"password"
|
|
763
|
+
),
|
|
764
|
+
field(t("settings.tenantId"), form.tenantId, (value) => setForm({ ...form, tenantId: value })),
|
|
765
|
+
field(
|
|
766
|
+
t("settings.defaultBases"),
|
|
767
|
+
form.defaultBases,
|
|
768
|
+
(value) => setForm({ ...form, defaultBases: value }),
|
|
769
|
+
void 0,
|
|
770
|
+
t("settings.defaultBasesHint")
|
|
46
771
|
),
|
|
47
|
-
|
|
772
|
+
field(t("settings.maxResults"), form.maxResults, (value) => setForm({ ...form, maxResults: value })),
|
|
773
|
+
field(t("settings.maxChunkChars"), form.maxChunkChars, (value) => setForm({ ...form, maxChunkChars: value })),
|
|
774
|
+
field(t("settings.agentId"), form.agentId, (value) => setForm({ ...form, agentId: value }), void 0, t("settings.agentIdHint")),
|
|
775
|
+
// 最后一项也跨整行:7 个普通字段排下来,末尾那个会孤零零占半栏,
|
|
776
|
+
// 首尾都是整行字段之后,这张表的宽度节奏才像是有意排的。
|
|
777
|
+
field(t("settings.chatModelId"), form.chatModelId, (value) => setForm({ ...form, chatModelId: value }), void 0, t("settings.chatModelIdHint"), "text", true)
|
|
778
|
+
),
|
|
779
|
+
(0, import_react3.createElement)(
|
|
780
|
+
"div",
|
|
781
|
+
{ className: "hiwork-knowledge-actions" },
|
|
782
|
+
(0, import_react3.createElement)(
|
|
48
783
|
"button",
|
|
49
|
-
{ type: "button", className: "hiwork-knowledge-button", onClick:
|
|
50
|
-
t("
|
|
784
|
+
{ type: "button", className: "hiwork-knowledge-button", disabled: status === "saving", onClick: save },
|
|
785
|
+
status === "saving" ? t("settings.saving") : t("settings.save")
|
|
786
|
+
),
|
|
787
|
+
(0, import_react3.createElement)(
|
|
788
|
+
"button",
|
|
789
|
+
{ type: "button", className: "hiwork-knowledge-button", disabled: status === "testing", onClick: test },
|
|
790
|
+
status === "testing" ? t("settings.testing") : t("settings.test")
|
|
791
|
+
),
|
|
792
|
+
status === "saved" ? (0, import_react3.createElement)("span", { className: "hiwork-knowledge-muted" }, t("settings.saved")) : null
|
|
793
|
+
),
|
|
794
|
+
(0, import_react3.createElement)("p", { className: "hiwork-knowledge-field-hint" }, t("settings.testNote")),
|
|
795
|
+
message === "" ? null : (0, import_react3.createElement)("div", { className: "hiwork-knowledge-notice is-error" }, message),
|
|
796
|
+
selfCheck === null ? null : (0, import_react3.createElement)(
|
|
797
|
+
"div",
|
|
798
|
+
{ className: "hiwork-knowledge-hits" },
|
|
799
|
+
(0, import_react3.createElement)(
|
|
800
|
+
"h3",
|
|
801
|
+
{ className: "hiwork-knowledge-panel-subtitle" },
|
|
802
|
+
`${t(`selfCheck.${selfCheck.level}`)} \xB7 ${t("selfCheck.baseCount")}\uFF1A${selfCheck.baseCount}`
|
|
803
|
+
),
|
|
804
|
+
(0, import_react3.createElement)(
|
|
805
|
+
"ul",
|
|
806
|
+
{ className: "hiwork-knowledge-list" },
|
|
807
|
+
...selfCheck.items.map(
|
|
808
|
+
(item) => (0, import_react3.createElement)(
|
|
809
|
+
"li",
|
|
810
|
+
{
|
|
811
|
+
key: item.code,
|
|
812
|
+
className: item.level === "error" ? "hiwork-knowledge-notice is-error" : item.level === "warn" ? "hiwork-knowledge-notice is-warn" : "hiwork-knowledge-muted"
|
|
813
|
+
},
|
|
814
|
+
`${item.ok ? "\u2713" : "!"} ${item.message}`
|
|
815
|
+
)
|
|
816
|
+
)
|
|
817
|
+
)
|
|
818
|
+
)
|
|
819
|
+
);
|
|
820
|
+
}
|
|
821
|
+
|
|
822
|
+
// src/client/ToolCards.tsx
|
|
823
|
+
var import_react4 = require("react");
|
|
824
|
+
|
|
825
|
+
// src/client/tool-result.ts
|
|
826
|
+
var CARD_HIT_PREVIEW = 3;
|
|
827
|
+
function asRecord(value) {
|
|
828
|
+
if (typeof value !== "object" || value === null || Array.isArray(value)) return {};
|
|
829
|
+
return value;
|
|
830
|
+
}
|
|
831
|
+
function str(value) {
|
|
832
|
+
return typeof value === "string" ? value : "";
|
|
833
|
+
}
|
|
834
|
+
function num(value) {
|
|
835
|
+
if (typeof value === "number" && Number.isFinite(value)) return value;
|
|
836
|
+
return null;
|
|
837
|
+
}
|
|
838
|
+
function bool(value) {
|
|
839
|
+
return value === true;
|
|
840
|
+
}
|
|
841
|
+
function parseArgs(argsRaw) {
|
|
842
|
+
if (argsRaw === "") return {};
|
|
843
|
+
try {
|
|
844
|
+
return asRecord(JSON.parse(argsRaw));
|
|
845
|
+
} catch {
|
|
846
|
+
return {};
|
|
847
|
+
}
|
|
848
|
+
}
|
|
849
|
+
function parseResult(content) {
|
|
850
|
+
if (!Array.isArray(content)) return null;
|
|
851
|
+
for (const part of content) {
|
|
852
|
+
const block = asRecord(part);
|
|
853
|
+
if (block["type"] !== "text") continue;
|
|
854
|
+
const text = str(block["text"]);
|
|
855
|
+
if (text === "") continue;
|
|
856
|
+
try {
|
|
857
|
+
return asRecord(JSON.parse(text));
|
|
858
|
+
} catch {
|
|
859
|
+
return null;
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
return null;
|
|
863
|
+
}
|
|
864
|
+
function hitRows(value) {
|
|
865
|
+
if (!Array.isArray(value)) return [];
|
|
866
|
+
const rows = [];
|
|
867
|
+
for (const item of value) {
|
|
868
|
+
const row = asRecord(item);
|
|
869
|
+
const knowledgeId = str(row["knowledgeId"]);
|
|
870
|
+
const content = str(row["content"]);
|
|
871
|
+
if (knowledgeId === "" && content === "") continue;
|
|
872
|
+
rows.push({
|
|
873
|
+
knowledgeId,
|
|
874
|
+
chunkId: str(row["chunkId"]),
|
|
875
|
+
knowledgeTitle: str(row["knowledgeTitle"]),
|
|
876
|
+
fileName: str(row["fileName"]),
|
|
877
|
+
chunkIndex: num(row["chunkIndex"]),
|
|
878
|
+
chunkType: str(row["chunkType"]),
|
|
879
|
+
content,
|
|
880
|
+
truncated: bool(row["truncated"])
|
|
881
|
+
});
|
|
882
|
+
}
|
|
883
|
+
return rows;
|
|
884
|
+
}
|
|
885
|
+
function stateOf(settled, errorCode, isError) {
|
|
886
|
+
if (!settled) return "running";
|
|
887
|
+
if (errorCode === "interrupted") return "stopped";
|
|
888
|
+
return isError ? "error" : "ok";
|
|
889
|
+
}
|
|
890
|
+
function toToolCardModel(toolName, block) {
|
|
891
|
+
const settled = block.kind === "tool-result";
|
|
892
|
+
const argsRaw = settled ? str(block.call?.argsRaw) : str(block.argsRaw);
|
|
893
|
+
const args = parseArgs(argsRaw);
|
|
894
|
+
const error = asRecord(block.error);
|
|
895
|
+
const state = stateOf(settled, str(error["code"]), block.isError === true);
|
|
896
|
+
const payload = settled ? parseResult(block.content) : null;
|
|
897
|
+
const payloadFailed = payload !== null && payload["ok"] === false;
|
|
898
|
+
const payloadMessage = payloadFailed ? str(payload["message"]) : "";
|
|
899
|
+
const failure = payloadFailed ? payloadMessage === "" ? str(error["code"]) || "\u77E5\u8BC6\u5E93\u8C03\u7528\u5931\u8D25\u3002" : payloadMessage : state === "error" || state === "stopped" ? str(error["code"]) || "\u77E5\u8BC6\u5E93\u8C03\u7528\u5931\u8D25\u3002" : null;
|
|
900
|
+
const common = {
|
|
901
|
+
state,
|
|
902
|
+
error: failure
|
|
903
|
+
};
|
|
904
|
+
switch (toolName) {
|
|
905
|
+
case "knowledge_search": {
|
|
906
|
+
const hits = hitRows(payload?.["hits"]);
|
|
907
|
+
return {
|
|
908
|
+
kind: "search",
|
|
909
|
+
...common,
|
|
910
|
+
subject: str(args["query"]),
|
|
911
|
+
hitCount: num(payload?.["hitCount"]) ?? hits.length,
|
|
912
|
+
hits,
|
|
913
|
+
hint: str(payload?.["hint"]) === "" ? null : str(payload?.["hint"])
|
|
914
|
+
};
|
|
915
|
+
}
|
|
916
|
+
case "knowledge_ask": {
|
|
917
|
+
return {
|
|
918
|
+
kind: "ask",
|
|
919
|
+
...common,
|
|
920
|
+
subject: str(args["query"]),
|
|
921
|
+
answer: str(payload?.["answer"]),
|
|
922
|
+
references: hitRows(payload?.["references"]),
|
|
923
|
+
elapsedMs: num(payload?.["elapsedMs"])
|
|
924
|
+
};
|
|
925
|
+
}
|
|
926
|
+
case "knowledge_read_document": {
|
|
927
|
+
const document2 = asRecord(payload?.["document"]);
|
|
928
|
+
const title = str(document2["title"]);
|
|
929
|
+
const chunks = [];
|
|
930
|
+
if (Array.isArray(document2["chunks"])) {
|
|
931
|
+
for (const item of document2["chunks"]) {
|
|
932
|
+
const row = asRecord(item);
|
|
933
|
+
chunks.push({
|
|
934
|
+
index: num(row["index"]),
|
|
935
|
+
chunkType: str(row["type"]),
|
|
936
|
+
content: str(row["content"]),
|
|
937
|
+
truncated: bool(row["truncated"])
|
|
938
|
+
});
|
|
939
|
+
}
|
|
940
|
+
}
|
|
941
|
+
return {
|
|
942
|
+
kind: "read",
|
|
943
|
+
...common,
|
|
944
|
+
// `subject` 是卡片头行的主标签:**不能用 `knowledge_id`**——那是个 UUID,
|
|
945
|
+
// 真机上会渲染成「读取文档 | 442e10fc-cc95-…」这种看不懂的标题。
|
|
946
|
+
// 有结果就用标题;只有运行中(拿不到标题)时才退回 id,且由卡片改成「正在读取…」。
|
|
947
|
+
subject: title !== "" ? title : str(args["knowledge_id"]),
|
|
948
|
+
title,
|
|
949
|
+
chunkTotal: num(document2["chunkTotal"]),
|
|
950
|
+
page: num(document2["page"]),
|
|
951
|
+
chunks
|
|
952
|
+
};
|
|
953
|
+
}
|
|
954
|
+
case "knowledge_list_bases": {
|
|
955
|
+
const bases = [];
|
|
956
|
+
if (Array.isArray(payload?.["bases"])) {
|
|
957
|
+
for (const item of payload["bases"]) {
|
|
958
|
+
const row = asRecord(item);
|
|
959
|
+
bases.push({
|
|
960
|
+
id: str(row["id"]),
|
|
961
|
+
name: str(row["name"]),
|
|
962
|
+
description: str(row["description"]),
|
|
963
|
+
documentCount: num(row["documentCount"])
|
|
964
|
+
});
|
|
965
|
+
}
|
|
966
|
+
}
|
|
967
|
+
return { kind: "bases", ...common, subject: "", bases };
|
|
968
|
+
}
|
|
969
|
+
default:
|
|
970
|
+
return { kind: "unknown", ...common, subject: "" };
|
|
971
|
+
}
|
|
972
|
+
}
|
|
973
|
+
|
|
974
|
+
// src/client/ToolCards.tsx
|
|
975
|
+
var TITLE_KEYS = {
|
|
976
|
+
knowledge_search: "card.search.title",
|
|
977
|
+
knowledge_ask: "card.ask.title",
|
|
978
|
+
knowledge_read_document: "card.read.title",
|
|
979
|
+
knowledge_list_bases: "card.bases.title"
|
|
980
|
+
};
|
|
981
|
+
function StateMark({ state }) {
|
|
982
|
+
if (state === "error" || state === "stopped") {
|
|
983
|
+
return (0, import_react4.createElement)("span", { className: "hiwork-knowledge-tool-mark is-error" }, (0, import_react4.createElement)(IconAlert));
|
|
984
|
+
}
|
|
985
|
+
if (state === "ok") {
|
|
986
|
+
return (0, import_react4.createElement)("span", { className: "hiwork-knowledge-tool-mark is-ok" }, (0, import_react4.createElement)(IconCheck));
|
|
987
|
+
}
|
|
988
|
+
return (0, import_react4.createElement)("span", { className: "hiwork-knowledge-tool-mark is-running" }, (0, import_react4.createElement)(IconSearch));
|
|
989
|
+
}
|
|
990
|
+
function HitLine({
|
|
991
|
+
hit,
|
|
992
|
+
t,
|
|
993
|
+
followUp,
|
|
994
|
+
openDocument
|
|
995
|
+
}) {
|
|
996
|
+
const segment = hit.chunkIndex === null ? "" : t("card.segment", { index: hit.chunkIndex });
|
|
997
|
+
const title = hit.knowledgeTitle === "" ? t("card.untitled") : hit.knowledgeTitle;
|
|
998
|
+
const prompt = () => t("card.followUpPrompt", { title, segment });
|
|
999
|
+
const [failure, setFailure] = (0, import_react4.useState)(null);
|
|
1000
|
+
const send = (0, import_react4.useCallback)(() => {
|
|
1001
|
+
if (followUp === void 0) return;
|
|
1002
|
+
const result = followUp(prompt());
|
|
1003
|
+
setFailure(result.ok ? null : t("card.actionFailed", { reason: t(`card.insertFailed.${result.reason}`) }));
|
|
1004
|
+
}, [followUp, t, title, segment]);
|
|
1005
|
+
return (0, import_react4.createElement)(
|
|
1006
|
+
"li",
|
|
1007
|
+
{ className: "hiwork-knowledge-tool-hit" },
|
|
1008
|
+
(0, import_react4.createElement)(
|
|
1009
|
+
"div",
|
|
1010
|
+
{ className: "hiwork-knowledge-tool-hit-head" },
|
|
1011
|
+
(0, import_react4.createElement)("span", { className: "hiwork-knowledge-tool-hit-title", title }, title),
|
|
1012
|
+
segment === "" ? null : (0, import_react4.createElement)("span", { className: "hiwork-knowledge-tool-hit-seg" }, segment),
|
|
1013
|
+
hit.truncated ? (0, import_react4.createElement)("span", { className: "hiwork-knowledge-tag is-warning" }, t("card.clipped")) : null,
|
|
1014
|
+
(0, import_react4.createElement)(
|
|
1015
|
+
"span",
|
|
1016
|
+
{ className: "hiwork-knowledge-tool-hit-actions" },
|
|
1017
|
+
openDocument === void 0 || hit.knowledgeId === "" ? null : (0, import_react4.createElement)(
|
|
1018
|
+
"button",
|
|
1019
|
+
{
|
|
1020
|
+
type: "button",
|
|
1021
|
+
className: "hiwork-knowledge-tool-action",
|
|
1022
|
+
title: t("card.open"),
|
|
1023
|
+
onClick: () => openDocument(hit.knowledgeId)
|
|
1024
|
+
},
|
|
1025
|
+
(0, import_react4.createElement)(IconExternal),
|
|
1026
|
+
t("card.open")
|
|
1027
|
+
),
|
|
1028
|
+
followUp === void 0 ? null : (0, import_react4.createElement)(
|
|
1029
|
+
"button",
|
|
1030
|
+
{
|
|
1031
|
+
type: "button",
|
|
1032
|
+
className: "hiwork-knowledge-tool-action",
|
|
1033
|
+
title: t("card.followUp"),
|
|
1034
|
+
onClick: send
|
|
1035
|
+
},
|
|
1036
|
+
(0, import_react4.createElement)(IconMessage),
|
|
1037
|
+
t("card.followUp")
|
|
1038
|
+
)
|
|
51
1039
|
)
|
|
52
1040
|
),
|
|
53
|
-
(0,
|
|
1041
|
+
(0, import_react4.createElement)("p", { className: "hiwork-knowledge-tool-hit-body" }, hit.content),
|
|
1042
|
+
failure === null ? null : (0, import_react4.createElement)("p", { className: "hiwork-knowledge-tool-failure" }, failure)
|
|
1043
|
+
);
|
|
1044
|
+
}
|
|
1045
|
+
function KnowledgeToolRow(props) {
|
|
1046
|
+
const { t, block, toolName = "", inspect, followUp, openDocument } = props;
|
|
1047
|
+
const model = toToolCardModel(toolName, block);
|
|
1048
|
+
const [expanded, setExpanded] = (0, import_react4.useState)(false);
|
|
1049
|
+
const hits = model.kind === "search" ? model.hits : model.kind === "ask" ? model.references : [];
|
|
1050
|
+
const hidden = Math.max(0, hits.length - CARD_HIT_PREVIEW);
|
|
1051
|
+
const shown = expanded ? hits : hits.slice(0, CARD_HIT_PREVIEW);
|
|
1052
|
+
const canExpand = hidden > 0;
|
|
1053
|
+
const toggle = (0, import_react4.useCallback)(() => setExpanded((value) => !value), []);
|
|
1054
|
+
const summary = () => {
|
|
1055
|
+
if (model.error !== null) return model.error;
|
|
1056
|
+
if (model.state === "running") {
|
|
1057
|
+
return model.subject === "" ? t("card.running") : t("card.runningWith", { subject: model.subject });
|
|
1058
|
+
}
|
|
1059
|
+
switch (model.kind) {
|
|
1060
|
+
case "search":
|
|
1061
|
+
return model.hitCount === 0 ? t("card.noHit") : t("card.hitCount", { count: model.hitCount });
|
|
1062
|
+
case "ask":
|
|
1063
|
+
return model.references.length === 0 ? t("card.answered") : t("card.answeredWith", { count: model.references.length });
|
|
1064
|
+
case "read":
|
|
1065
|
+
return model.chunkTotal === null ? t("card.read.done") : t("card.read.doneWith", { count: model.chunkTotal });
|
|
1066
|
+
case "bases":
|
|
1067
|
+
return t("card.bases.count", { count: model.bases.length });
|
|
1068
|
+
default:
|
|
1069
|
+
return t("card.done");
|
|
1070
|
+
}
|
|
1071
|
+
};
|
|
1072
|
+
return (0, import_react4.createElement)(
|
|
1073
|
+
"div",
|
|
1074
|
+
{ className: "hiwork-knowledge-tool", "data-tool": toolName, "data-state": model.state },
|
|
1075
|
+
(0, import_react4.createElement)(
|
|
1076
|
+
"div",
|
|
1077
|
+
{
|
|
1078
|
+
className: "hiwork-knowledge-tool-row",
|
|
1079
|
+
...canExpand ? {
|
|
1080
|
+
role: "button",
|
|
1081
|
+
tabIndex: 0,
|
|
1082
|
+
"aria-expanded": expanded,
|
|
1083
|
+
onClick: toggle,
|
|
1084
|
+
onKeyDown: (event) => {
|
|
1085
|
+
if (event.key !== "Enter" && event.key !== " ") return;
|
|
1086
|
+
event.preventDefault();
|
|
1087
|
+
toggle();
|
|
1088
|
+
}
|
|
1089
|
+
} : {}
|
|
1090
|
+
},
|
|
1091
|
+
(0, import_react4.createElement)(StateMark, { state: model.state }),
|
|
1092
|
+
(0, import_react4.createElement)("span", { className: "hiwork-knowledge-tool-title" }, t(TITLE_KEYS[toolName] ?? "card.title")),
|
|
1093
|
+
model.subject === "" ? null : (0, import_react4.createElement)("span", { className: "hiwork-knowledge-tool-subject", title: model.subject }, model.subject),
|
|
1094
|
+
(0, import_react4.createElement)("span", { className: "hiwork-knowledge-tool-summary" }, summary())
|
|
1095
|
+
),
|
|
1096
|
+
// 结果区:命中/引用/分块/库列表都在这里;出错时显示原因。
|
|
1097
|
+
(0, import_react4.createElement)(
|
|
54
1098
|
"div",
|
|
55
|
-
{ className: "hiwork-knowledge-
|
|
56
|
-
|
|
1099
|
+
{ className: "hiwork-knowledge-tool-body" },
|
|
1100
|
+
model.kind === "ask" && model.answer !== "" ? (0, import_react4.createElement)("p", { className: "hiwork-knowledge-tool-answer" }, model.answer) : null,
|
|
1101
|
+
model.kind === "bases" ? (0, import_react4.createElement)(
|
|
1102
|
+
"ul",
|
|
1103
|
+
{ className: "hiwork-knowledge-tool-list" },
|
|
1104
|
+
...model.bases.slice(0, expanded ? model.bases.length : CARD_HIT_PREVIEW).map(
|
|
1105
|
+
(base) => (0, import_react4.createElement)(
|
|
1106
|
+
"li",
|
|
1107
|
+
{ key: base.id, className: "hiwork-knowledge-tool-base" },
|
|
1108
|
+
(0, import_react4.createElement)("span", { className: "hiwork-knowledge-tool-hit-title" }, base.name),
|
|
1109
|
+
base.documentCount === null ? null : (0, import_react4.createElement)("span", { className: "hiwork-knowledge-tool-hit-seg" }, t("bases.meta.docs", { count: base.documentCount })),
|
|
1110
|
+
base.description === "" ? null : (0, import_react4.createElement)("span", { className: "hiwork-knowledge-tool-base-desc" }, base.description)
|
|
1111
|
+
)
|
|
1112
|
+
)
|
|
1113
|
+
) : null,
|
|
1114
|
+
model.kind === "read" ? (0, import_react4.createElement)(
|
|
1115
|
+
"ul",
|
|
1116
|
+
{ className: "hiwork-knowledge-tool-list" },
|
|
1117
|
+
...model.chunks.slice(0, expanded ? model.chunks.length : CARD_HIT_PREVIEW).map(
|
|
1118
|
+
(chunk, index) => (0, import_react4.createElement)(
|
|
1119
|
+
"li",
|
|
1120
|
+
{ key: `${chunk.index ?? index}`, className: "hiwork-knowledge-tool-hit" },
|
|
1121
|
+
(0, import_react4.createElement)(
|
|
1122
|
+
"div",
|
|
1123
|
+
{ className: "hiwork-knowledge-tool-hit-head" },
|
|
1124
|
+
(0, import_react4.createElement)("span", { className: "hiwork-knowledge-tool-hit-title" }, model.title === "" ? model.subject : model.title),
|
|
1125
|
+
chunk.index === null ? null : (0, import_react4.createElement)("span", { className: "hiwork-knowledge-tool-hit-seg" }, `#${chunk.index}`),
|
|
1126
|
+
chunk.truncated ? (0, import_react4.createElement)("span", { className: "hiwork-knowledge-tag is-warning" }, t("card.clipped")) : null
|
|
1127
|
+
),
|
|
1128
|
+
(0, import_react4.createElement)("p", { className: "hiwork-knowledge-tool-hit-body" }, chunk.content)
|
|
1129
|
+
)
|
|
1130
|
+
)
|
|
1131
|
+
) : null,
|
|
1132
|
+
hits.length > 0 ? (0, import_react4.createElement)(
|
|
1133
|
+
"ul",
|
|
1134
|
+
{ className: "hiwork-knowledge-tool-list" },
|
|
1135
|
+
...shown.map(
|
|
1136
|
+
(hit) => (0, import_react4.createElement)(HitLine, {
|
|
1137
|
+
key: hit.chunkId === "" ? `${hit.knowledgeId}-${hit.chunkIndex ?? "x"}` : hit.chunkId,
|
|
1138
|
+
hit,
|
|
1139
|
+
t,
|
|
1140
|
+
followUp,
|
|
1141
|
+
openDocument
|
|
1142
|
+
})
|
|
1143
|
+
)
|
|
1144
|
+
) : null,
|
|
1145
|
+
// 0 条命中且工具给了 hint(配置类原因):这类提示才是「查不到」的正解,
|
|
1146
|
+
// 不能只显示「无结果」让用户以为公司没这个资料。
|
|
1147
|
+
model.kind === "search" && model.state === "ok" && model.hits.length === 0 && model.hint !== null ? (0, import_react4.createElement)("p", { className: "hiwork-knowledge-tool-hint" }, model.hint) : null,
|
|
1148
|
+
hidden > 0 || model.kind === "read" && model.chunks.length > CARD_HIT_PREVIEW ? (0, import_react4.createElement)(
|
|
1149
|
+
"button",
|
|
1150
|
+
{ type: "button", className: "hiwork-knowledge-tool-more", onClick: toggle },
|
|
1151
|
+
expanded ? t("card.collapse") : t("card.more", { count: hidden })
|
|
1152
|
+
) : null,
|
|
1153
|
+
model.error === null ? null : (0, import_react4.createElement)(
|
|
1154
|
+
"p",
|
|
1155
|
+
{ className: "hiwork-knowledge-tool-error" },
|
|
1156
|
+
(0, import_react4.createElement)("span", { className: "hiwork-knowledge-tool-error-icon" }, (0, import_react4.createElement)(IconAlert)),
|
|
1157
|
+
model.error
|
|
1158
|
+
),
|
|
1159
|
+
inspect === void 0 ? null : (0, import_react4.createElement)("button", { type: "button", className: "hiwork-knowledge-tool-action is-inspect", onClick: inspect }, t("card.inspect"))
|
|
57
1160
|
)
|
|
58
1161
|
);
|
|
59
1162
|
}
|
|
@@ -62,19 +1165,376 @@ function KnowledgeView(props) {
|
|
|
62
1165
|
var NS = "hiwork-knowledge";
|
|
63
1166
|
var zh = {
|
|
64
1167
|
"view.title": "\u77E5\u8BC6\u5E93",
|
|
65
|
-
"view.subtitle": "\
|
|
66
|
-
"view.
|
|
67
|
-
"view.
|
|
1168
|
+
"view.subtitle": "\u4F01\u4E1A\u77E5\u8BC6\u68C0\u7D22\u4E0E\u95EE\u7B54\uFF08WeKnora\uFF09",
|
|
1169
|
+
"view.close": "\u5173\u95ED\u8BBE\u7F6E",
|
|
1170
|
+
"view.refresh": "\u5237\u65B0",
|
|
1171
|
+
"state.loading": "\u6B63\u5728\u8BFB\u53D6\u77E5\u8BC6\u5E93\u2026",
|
|
1172
|
+
"state.error": "\u77E5\u8BC6\u5E93\u8BFB\u53D6\u5931\u8D25",
|
|
1173
|
+
"state.retry": "\u91CD\u8BD5",
|
|
1174
|
+
"settings.title": "\u77E5\u8BC6\u5E93\u8BBE\u7F6E",
|
|
1175
|
+
"settings.subtitle": "\u51ED\u636E\u4FDD\u5B58\u5728\u672C\u673A\uFF08Host \u534A\u8FB9\uFF09\uFF0C\u4E0D\u4E0B\u53D1\u7ED9\u5176\u5B83\u63D2\u4EF6\u6216\u7F51\u9875",
|
|
1176
|
+
"settings.baseUrl": "\u540E\u7AEF\u5730\u5740",
|
|
1177
|
+
"settings.baseUrlHint": "\u7F3A /api/v1 \u65F6\u4F1A\u81EA\u52A8\u8865\u9F50\uFF1B\u9ED8\u8BA4\u6307\u5411\u516C\u53F8\u5185\u7F51\u90E8\u7F72",
|
|
1178
|
+
"settings.apiKey": "API Key",
|
|
1179
|
+
"settings.apiKeyPlaceholder": "\u7C98\u8D34\u7A7A\u95F4 API Key\uFF08\u5F62\u5982 sk-\u2026\uFF09",
|
|
1180
|
+
"settings.apiKeyKeep": "\u7559\u7A7A\u5219\u4E0D\u4FEE\u6539",
|
|
1181
|
+
"settings.apiKeyConfigured": "\u5DF2\u914D\u7F6E",
|
|
1182
|
+
"settings.apiKeyMissing": "\u672A\u914D\u7F6E",
|
|
1183
|
+
"settings.apiKeySource": "\u51ED\u636E\u6765\u6E90",
|
|
1184
|
+
"settings.apiKeySource.settings": "\u672C\u673A\u8BBE\u7F6E",
|
|
1185
|
+
"settings.apiKeySource.env": "\u73AF\u5883\u53D8\u91CF",
|
|
1186
|
+
"settings.apiKeySource.none": "\u65E0",
|
|
1187
|
+
"settings.tenantId": "\u7A7A\u95F4 ID\uFF08\u5E73\u53F0 Key \u624D\u9700\u8981\uFF09",
|
|
1188
|
+
"settings.defaultBases": "\u9ED8\u8BA4\u68C0\u7D22\u8303\u56F4\uFF08\u77E5\u8BC6\u5E93 ID\uFF0C\u9017\u53F7\u5206\u9694\uFF09",
|
|
1189
|
+
"settings.defaultBasesHint": "\u7559\u7A7A\u8868\u793A\u4F7F\u7528\u51ED\u636E\u53EF\u89C1\u7684\u5168\u90E8\u77E5\u8BC6\u5E93",
|
|
1190
|
+
"settings.maxResults": "\u6BCF\u6B21\u68C0\u7D22\u6761\u6570\u4E0A\u9650",
|
|
1191
|
+
"settings.maxChunkChars": "\u5355\u6761\u7247\u6BB5\u5B57\u7B26\u4E0A\u9650",
|
|
1192
|
+
"settings.agentId": "\u95EE\u7B54 Agent ID",
|
|
1193
|
+
"settings.agentIdHint": "\u5FC5\u987B\u662F\u81EA\u5EFA Agent\uFF08\u5185\u7F6E Agent \u7F3A\u5C11\u6A21\u578B\u914D\u7F6E\uFF0C\u540E\u7AEF\u4F1A\u76F4\u63A5\u62D2\u7EDD\uFF09",
|
|
1194
|
+
"settings.chatModelId": "\u95EE\u7B54\u6A21\u578B ID",
|
|
1195
|
+
"settings.chatModelIdHint": "\u8BF7\u6C42\u4F53\u91CC\u7684 summary_model_id\uFF1B\u7559\u7A7A\u5219\u7528\u540E\u7AEF\u9ED8\u8BA4",
|
|
1196
|
+
"settings.save": "\u4FDD\u5B58",
|
|
1197
|
+
"settings.saving": "\u4FDD\u5B58\u4E2D\u2026",
|
|
1198
|
+
"settings.saved": "\u5DF2\u4FDD\u5B58",
|
|
1199
|
+
"settings.test": "\u6D4B\u8BD5\u8FDE\u63A5",
|
|
1200
|
+
"settings.testing": "\u6B63\u5728\u81EA\u68C0\u2026",
|
|
1201
|
+
"settings.testNote": "\u81EA\u68C0\u4F1A\u771F\u5B9E\u8C03\u7528\u540E\u7AEF\uFF1A\u5217\u5E93 + \u7528\u6587\u6863\u6807\u9898\u505A\u4E00\u6B21\u63A2\u9488\u68C0\u7D22\uFF08\u7528\u4E8E\u53D1\u73B0\u300C\u68C0\u7D22\u672A\u7ED1 rerank\u300D\u8FD9\u7C7B\u9759\u9ED8\u9519\u8BEF\uFF09",
|
|
1202
|
+
"selfCheck.ok": "\u81EA\u68C0\u901A\u8FC7",
|
|
1203
|
+
"selfCheck.warn": "\u81EA\u68C0\u6709\u544A\u8B66",
|
|
1204
|
+
"selfCheck.error": "\u81EA\u68C0\u5931\u8D25",
|
|
1205
|
+
"selfCheck.baseCount": "\u53EF\u89C1\u77E5\u8BC6\u5E93",
|
|
1206
|
+
"bases.title": "\u77E5\u8BC6\u5E93",
|
|
1207
|
+
"bases.empty": "\u5F53\u524D\u51ED\u636E\u770B\u4E0D\u5230\u4EFB\u4F55\u77E5\u8BC6\u5E93",
|
|
1208
|
+
"bases.meta.docs": "{count} \u7BC7\u6587\u6863",
|
|
1209
|
+
"bases.meta.updated": "{value} \u66F4\u65B0",
|
|
1210
|
+
"bases.select": "\u67E5\u770B\u300C{name}\u300D\u7684\u6587\u6863",
|
|
1211
|
+
"docs.title": "\u6587\u6863",
|
|
1212
|
+
"docs.empty": "\u8FD9\u4E2A\u77E5\u8BC6\u5E93\u91CC\u8FD8\u6CA1\u6709\u6587\u6863",
|
|
1213
|
+
"docs.loading": "\u6B63\u5728\u8BFB\u53D6\u6587\u6863\u2026",
|
|
1214
|
+
"docs.parseStatus": "\u89E3\u6790\u72B6\u6001",
|
|
1215
|
+
"docs.scope.all": "\u5168\u90E8\u77E5\u8BC6\u5E93",
|
|
1216
|
+
"docs.parse.pending": "\u6392\u961F\u4E2D",
|
|
1217
|
+
"docs.parse.processing": "\u89E3\u6790\u4E2D",
|
|
1218
|
+
"docs.parse.finalizing": "\u751F\u6210\u6458\u8981\u4E2D",
|
|
1219
|
+
"docs.parse.completed": "\u5DF2\u5C31\u7EEA",
|
|
1220
|
+
"docs.parse.failed": "\u89E3\u6790\u5931\u8D25",
|
|
1221
|
+
"docs.parse.cancelled": "\u5DF2\u53D6\u6D88",
|
|
1222
|
+
// ---- 聊天里的工具卡片(tool.call.toolview) ----
|
|
1223
|
+
"card.title": "\u77E5\u8BC6\u5E93",
|
|
1224
|
+
"card.search.title": "\u68C0\u7D22\u77E5\u8BC6\u5E93",
|
|
1225
|
+
"card.ask.title": "\u95EE\u77E5\u8BC6\u5E93",
|
|
1226
|
+
"card.read.title": "\u8BFB\u53D6\u6587\u6863",
|
|
1227
|
+
"card.bases.title": "\u77E5\u8BC6\u5E93\u5217\u8868",
|
|
1228
|
+
"card.running": "\u8FDB\u884C\u4E2D\u2026",
|
|
1229
|
+
"card.runningWith": "\u6B63\u5728\u68C0\u7D22\u300C{subject}\u300D\u2026",
|
|
1230
|
+
"card.done": "\u5DF2\u5B8C\u6210",
|
|
1231
|
+
"card.hitCount": "{count} \u6BB5\u547D\u4E2D",
|
|
1232
|
+
"card.noHit": "\u65E0\u547D\u4E2D",
|
|
1233
|
+
"card.answered": "\u5DF2\u7ED9\u51FA\u7B54\u6848",
|
|
1234
|
+
"card.answeredWith": "\u7B54\u6848 \xB7 {count} \u6761\u5F15\u7528",
|
|
1235
|
+
"card.read.done": "\u5DF2\u8BFB\u53D6",
|
|
1236
|
+
"card.read.doneWith": "\u5168\u6587 {count} \u6BB5",
|
|
1237
|
+
"card.bases.count": "{count} \u4E2A\u77E5\u8BC6\u5E93",
|
|
1238
|
+
"card.segment": "\u7B2C {index} \u6BB5",
|
|
1239
|
+
"card.actionFailed": "\u6CA1\u80FD\u653E\u8FDB\u8F93\u5165\u6846\uFF1A{reason}",
|
|
1240
|
+
"card.insertFailed.no-target": "\u5F53\u524D\u6CA1\u6709\u6253\u5F00\u7684\u4F1A\u8BDD",
|
|
1241
|
+
"card.insertFailed.busy": "\u8F93\u5165\u6846\u6B63\u5FD9\uFF08\u6B63\u5728\u5904\u7406\u4E0A\u4E00\u8F6E\uFF09",
|
|
1242
|
+
"card.insertFailed.rejected": "\u8F93\u5165\u6846\u62D2\u7EDD\u4E86\u8FD9\u6B21\u63D2\u5165",
|
|
1243
|
+
"card.untitled": "\u672A\u547D\u540D\u6587\u6863",
|
|
1244
|
+
"card.clipped": "\u5DF2\u622A\u65AD",
|
|
1245
|
+
"card.open": "\u5728\u77E5\u8BC6\u5E93\u9875\u6253\u5F00",
|
|
1246
|
+
"card.followUp": "\u8FFD\u95EE",
|
|
1247
|
+
"card.followUpPrompt": "\u8BF7\u57FA\u4E8E\u4F01\u4E1A\u77E5\u8BC6\u5E93\u300A{title}\u300B{segment}\u7EE7\u7EED\u56DE\u7B54\uFF0C\u5E76\u6CE8\u660E\u51FA\u5904\u3002",
|
|
1248
|
+
"card.more": "\u5C55\u5F00\u5176\u4F59 {count} \u6BB5",
|
|
1249
|
+
"card.collapse": "\u6536\u8D77",
|
|
1250
|
+
"card.inspect": "\u5728\u8F68\u8FF9\u4E2D\u67E5\u770B",
|
|
1251
|
+
// ---- 文档正文(中央页) ----
|
|
1252
|
+
"doc.read": "\u8BFB\u5168\u6587",
|
|
1253
|
+
"doc.back": "\u8FD4\u56DE\u5217\u8868",
|
|
1254
|
+
"doc.loading": "\u6B63\u5728\u8BFB\u53D6\u6B63\u6587\u2026",
|
|
1255
|
+
"doc.empty": "\u8FD9\u7BC7\u6587\u6863\u8FD8\u6CA1\u6709\u53EF\u8BFB\u7684\u5206\u5757",
|
|
1256
|
+
"doc.chunkTotal": "\u5171 {count} \u6BB5",
|
|
1257
|
+
"doc.page": "\u7B2C {page} / {total} \u9875",
|
|
1258
|
+
"doc.prev": "\u4E0A\u4E00\u9875",
|
|
1259
|
+
"doc.next": "\u4E0B\u4E00\u9875",
|
|
1260
|
+
"doc.bringToChat": "\u5E26\u8FDB\u804A\u5929",
|
|
1261
|
+
"doc.chatPrompt": "\u8BF7\u57FA\u4E8E\u4F01\u4E1A\u77E5\u8BC6\u5E93\u6587\u6863\u300A{title}\u300B\u56DE\u7B54\uFF0C\u5E76\u6CE8\u660E\u51FA\u5904\u3002",
|
|
1262
|
+
"doc.chatSent": "\u5DF2\u653E\u8FDB\u8F93\u5165\u6846",
|
|
1263
|
+
"doc.chatFailed": "\u6CA1\u80FD\u653E\u8FDB\u8F93\u5165\u6846\uFF1A{reason}",
|
|
1264
|
+
"doc.chatFailed.no-target": "\u5F53\u524D\u6CA1\u6709\u6253\u5F00\u7684\u4F1A\u8BDD",
|
|
1265
|
+
"doc.chatFailed.busy": "\u8F93\u5165\u6846\u6B63\u5FD9\uFF08\u6B63\u5728\u5904\u7406\u4E0A\u4E00\u8F6E\uFF09",
|
|
1266
|
+
"doc.chatFailed.rejected": "\u8F93\u5165\u6846\u62D2\u7EDD\u4E86\u8FD9\u6B21\u63D2\u5165",
|
|
1267
|
+
"doc.chatUnavailable": "\u5F53\u524D\u6CA1\u6709\u6253\u5F00\u7684\u4F1A\u8BDD",
|
|
1268
|
+
"doc.bringChunkToChat": "\u5E26\u8FDB\u804A\u5929",
|
|
1269
|
+
"doc.chunkChatPrompt": "\u8BF7\u57FA\u4E8E\u4F01\u4E1A\u77E5\u8BC6\u5E93\u300A{title}\u300B{segment}\u7EE7\u7EED\u56DE\u7B54\uFF0C\u5E76\u6CE8\u660E\u51FA\u5904\u3002",
|
|
1270
|
+
"search.placeholder": "\u5728\u77E5\u8BC6\u5E93\u91CC\u68C0\u7D22\u2026",
|
|
1271
|
+
"search.button": "\u68C0\u7D22",
|
|
1272
|
+
"search.running": "\u68C0\u7D22\u4E2D\u2026",
|
|
1273
|
+
"search.empty": "\u6CA1\u6709\u547D\u4E2D\u3002\u82E5\u786E\u8BA4\u5E93\u91CC\u6709\u76F8\u5173\u5185\u5BB9\uFF0C\u8BF7\u68C0\u67E5\u540E\u7AEF\u68C0\u7D22\u914D\u7F6E\uFF1A\u91CD\u6392\u6A21\u578B\u662F\u5426\u7ED1\u5B9A\uFF0C\u4EE5\u53CA\u91CD\u6392\u9608\u503C\uFF08rerank_threshold\uFF09\u662F\u5426\u8FC7\u9AD8\u2014\u2014\u9608\u503C\u4F1A\u628A\u76F8\u5173\u4F46\u5206\u6570\u504F\u4F4E\u7684\u7247\u6BB5\u6574\u4F53\u6EE4\u6389\u3002",
|
|
1274
|
+
"search.hitCount": "\u547D\u4E2D\u7247\u6BB5",
|
|
1275
|
+
"search.truncated": "\u5DF2\u622A\u65AD",
|
|
1276
|
+
"search.clear": "\u8FD4\u56DE\u6587\u6863\u5217\u8868"
|
|
68
1277
|
};
|
|
69
1278
|
var en = {
|
|
70
1279
|
"view.title": "Knowledge Base",
|
|
71
|
-
"view.subtitle": "
|
|
72
|
-
"view.
|
|
73
|
-
"view.
|
|
1280
|
+
"view.subtitle": "Enterprise knowledge retrieval and Q&A (WeKnora)",
|
|
1281
|
+
"view.close": "Close settings",
|
|
1282
|
+
"view.refresh": "Refresh",
|
|
1283
|
+
"state.loading": "Loading knowledge bases\u2026",
|
|
1284
|
+
"state.error": "Failed to read knowledge bases",
|
|
1285
|
+
"state.retry": "Retry",
|
|
1286
|
+
"settings.title": "Knowledge settings",
|
|
1287
|
+
"settings.subtitle": "Credentials stay on this machine (host half) and are never exposed to other plugins or pages",
|
|
1288
|
+
"settings.baseUrl": "Backend URL",
|
|
1289
|
+
"settings.baseUrlHint": "`/api/v1` is appended when missing; defaults to the internal deployment",
|
|
1290
|
+
"settings.apiKey": "API key",
|
|
1291
|
+
"settings.apiKeyPlaceholder": "Paste the space API key (sk-\u2026)",
|
|
1292
|
+
"settings.apiKeyKeep": "leave empty to keep",
|
|
1293
|
+
"settings.apiKeyConfigured": "Configured",
|
|
1294
|
+
"settings.apiKeyMissing": "Not configured",
|
|
1295
|
+
"settings.apiKeySource": "Credential source",
|
|
1296
|
+
"settings.apiKeySource.settings": "Local settings",
|
|
1297
|
+
"settings.apiKeySource.env": "Environment",
|
|
1298
|
+
"settings.apiKeySource.none": "None",
|
|
1299
|
+
"settings.tenantId": "Tenant ID (platform keys only)",
|
|
1300
|
+
"settings.defaultBases": "Default scope (knowledge base IDs, comma separated)",
|
|
1301
|
+
"settings.defaultBasesHint": "Empty means every knowledge base the credential can see",
|
|
1302
|
+
"settings.maxResults": "Max results per search",
|
|
1303
|
+
"settings.maxChunkChars": "Max characters per passage",
|
|
1304
|
+
"settings.agentId": "Q&A agent ID",
|
|
1305
|
+
"settings.agentIdHint": "Must be a custom agent \u2014 built-in agents lack model config and are rejected by the backend",
|
|
1306
|
+
"settings.chatModelId": "Q&A model ID",
|
|
1307
|
+
"settings.chatModelIdHint": "Sent as summary_model_id; empty uses the backend default",
|
|
1308
|
+
"settings.save": "Save",
|
|
1309
|
+
"settings.saving": "Saving\u2026",
|
|
1310
|
+
"settings.saved": "Saved",
|
|
1311
|
+
"settings.test": "Test connection",
|
|
1312
|
+
"settings.testing": "Running self-check\u2026",
|
|
1313
|
+
"settings.testNote": 'The self-check really calls the backend: list bases, then probe-search a document title (this is how "rerank not bound" style silent failures surface)',
|
|
1314
|
+
"selfCheck.ok": "Self-check passed",
|
|
1315
|
+
"selfCheck.warn": "Self-check has warnings",
|
|
1316
|
+
"selfCheck.error": "Self-check failed",
|
|
1317
|
+
"selfCheck.baseCount": "Visible knowledge bases",
|
|
1318
|
+
"bases.title": "Knowledge bases",
|
|
1319
|
+
"bases.empty": "This credential cannot see any knowledge base",
|
|
1320
|
+
"bases.meta.docs": "{count} documents",
|
|
1321
|
+
"bases.meta.updated": "Updated {value}",
|
|
1322
|
+
"bases.select": "Show documents in {name}",
|
|
1323
|
+
"docs.title": "Documents",
|
|
1324
|
+
"docs.empty": "No documents in this knowledge base yet",
|
|
1325
|
+
"docs.loading": "Loading documents\u2026",
|
|
1326
|
+
"docs.parseStatus": "Parse status",
|
|
1327
|
+
"docs.scope.all": "All knowledge bases",
|
|
1328
|
+
"docs.parse.pending": "Queued",
|
|
1329
|
+
"docs.parse.processing": "Parsing",
|
|
1330
|
+
"docs.parse.finalizing": "Summarising",
|
|
1331
|
+
"docs.parse.completed": "Ready",
|
|
1332
|
+
"docs.parse.failed": "Failed",
|
|
1333
|
+
"docs.parse.cancelled": "Cancelled",
|
|
1334
|
+
// ---- tool cards inside the chat (tool.call.toolview) ----
|
|
1335
|
+
"card.title": "Knowledge",
|
|
1336
|
+
"card.search.title": "Searched knowledge",
|
|
1337
|
+
"card.ask.title": "Asked knowledge",
|
|
1338
|
+
"card.read.title": "Read document",
|
|
1339
|
+
"card.bases.title": "Knowledge bases",
|
|
1340
|
+
"card.running": "Running\u2026",
|
|
1341
|
+
"card.runningWith": 'Searching "{subject}"\u2026',
|
|
1342
|
+
"card.done": "Done",
|
|
1343
|
+
"card.hitCount": "{count} passages",
|
|
1344
|
+
"card.noHit": "No hits",
|
|
1345
|
+
"card.answered": "Answered",
|
|
1346
|
+
"card.answeredWith": "Answer \xB7 {count} citations",
|
|
1347
|
+
"card.read.done": "Read",
|
|
1348
|
+
"card.read.doneWith": "{count} passages",
|
|
1349
|
+
"card.bases.count": "{count} bases",
|
|
1350
|
+
"card.segment": "passage {index}",
|
|
1351
|
+
"card.actionFailed": "Could not add to the composer: {reason}",
|
|
1352
|
+
"card.insertFailed.no-target": "no session is open",
|
|
1353
|
+
"card.insertFailed.busy": "the composer is busy (still handling the previous turn)",
|
|
1354
|
+
"card.insertFailed.rejected": "the composer rejected the insertion",
|
|
1355
|
+
"card.untitled": "Untitled document",
|
|
1356
|
+
"card.clipped": "truncated",
|
|
1357
|
+
"card.open": "Open in knowledge page",
|
|
1358
|
+
"card.followUp": "Ask about this",
|
|
1359
|
+
"card.followUpPrompt": "Continue answering from \u300A{title}\u300B{segment} in the enterprise knowledge base and cite the source.",
|
|
1360
|
+
"card.more": "Show {count} more",
|
|
1361
|
+
"card.collapse": "Collapse",
|
|
1362
|
+
"card.inspect": "Inspect in trajectory",
|
|
1363
|
+
// ---- document body (central page) ----
|
|
1364
|
+
"doc.read": "Read",
|
|
1365
|
+
"doc.back": "Back to list",
|
|
1366
|
+
"doc.loading": "Loading document\u2026",
|
|
1367
|
+
"doc.empty": "This document has no readable passages yet",
|
|
1368
|
+
"doc.chunkTotal": "{count} passages",
|
|
1369
|
+
"doc.page": "Page {page} / {total}",
|
|
1370
|
+
"doc.prev": "Previous",
|
|
1371
|
+
"doc.next": "Next",
|
|
1372
|
+
"doc.bringToChat": "Take into chat",
|
|
1373
|
+
"doc.chatPrompt": "Answer from the enterprise knowledge base document \u300A{title}\u300B and cite the source.",
|
|
1374
|
+
"doc.chatSent": "Added to the composer",
|
|
1375
|
+
"doc.chatFailed": "Could not add to the composer: {reason}",
|
|
1376
|
+
"doc.chatFailed.no-target": "no session is open",
|
|
1377
|
+
"doc.chatFailed.busy": "the composer is busy (still handling the previous turn)",
|
|
1378
|
+
"doc.chatFailed.rejected": "the composer rejected the insertion",
|
|
1379
|
+
"doc.chatUnavailable": "No open session",
|
|
1380
|
+
"doc.bringChunkToChat": "Take into chat",
|
|
1381
|
+
"doc.chunkChatPrompt": "Continue answering from \u300A{title}\u300B{segment} in the enterprise knowledge base and cite the source.",
|
|
1382
|
+
"search.placeholder": "Search the knowledge bases\u2026",
|
|
1383
|
+
"search.button": "Search",
|
|
1384
|
+
"search.running": "Searching\u2026",
|
|
1385
|
+
"search.empty": "No hits. If the content should be there, check the backend retrieval config: whether a rerank model is bound, and whether the rerank threshold is too high \u2014 an over-high threshold filters out relevant passages whose scores are merely low.",
|
|
1386
|
+
"search.hitCount": "Matched passages",
|
|
1387
|
+
"search.truncated": "truncated",
|
|
1388
|
+
"search.clear": "Back to documents"
|
|
74
1389
|
};
|
|
75
1390
|
|
|
1391
|
+
// src/client/runtime.ts
|
|
1392
|
+
var KNOWLEDGE_CHANNEL = "/hiwork-knowledge";
|
|
1393
|
+
var SETTINGS_SCOPE_SESSION_ID = "settings";
|
|
1394
|
+
var RPC_INVALID_RESPONSE = "hiwork-knowledge:invalid-response";
|
|
1395
|
+
var RPC_REQUEST_FAILED = "hiwork-knowledge:request-failed";
|
|
1396
|
+
var TRANSPORT_ERROR_PATTERNS = [
|
|
1397
|
+
"failed to fetch",
|
|
1398
|
+
"networkerror",
|
|
1399
|
+
"network error",
|
|
1400
|
+
"load failed",
|
|
1401
|
+
"network request failed",
|
|
1402
|
+
"connection reset",
|
|
1403
|
+
"socket hang up",
|
|
1404
|
+
"network connection was lost"
|
|
1405
|
+
];
|
|
1406
|
+
function isTransportError(error) {
|
|
1407
|
+
if (error === void 0 || error === null) return false;
|
|
1408
|
+
const name2 = typeof error === "object" && "name" in error ? String(error.name) : "";
|
|
1409
|
+
if (name2 === "AbortError") return false;
|
|
1410
|
+
const message = error instanceof Error ? error.message : typeof error === "string" ? error : String(error);
|
|
1411
|
+
const text = `${name2} ${message}`.toLowerCase();
|
|
1412
|
+
return TRANSPORT_ERROR_PATTERNS.some((pattern) => text.includes(pattern));
|
|
1413
|
+
}
|
|
1414
|
+
function messageOf(error) {
|
|
1415
|
+
if (error instanceof Error) return error.message === "" ? RPC_REQUEST_FAILED : error.message;
|
|
1416
|
+
const text = String(error);
|
|
1417
|
+
return text === "" ? RPC_REQUEST_FAILED : text;
|
|
1418
|
+
}
|
|
1419
|
+
function makeState(phase, snapshot, error, refreshedAt) {
|
|
1420
|
+
return {
|
|
1421
|
+
phase,
|
|
1422
|
+
...snapshot === void 0 ? {} : { snapshot },
|
|
1423
|
+
...error === void 0 ? {} : { error },
|
|
1424
|
+
...refreshedAt === void 0 ? {} : { refreshedAt }
|
|
1425
|
+
};
|
|
1426
|
+
}
|
|
1427
|
+
function unwrap(value) {
|
|
1428
|
+
if (typeof value !== "object" || value === null || !("ok" in value)) {
|
|
1429
|
+
throw new Error(RPC_INVALID_RESPONSE);
|
|
1430
|
+
}
|
|
1431
|
+
const envelope = value;
|
|
1432
|
+
if (envelope.ok === true) return envelope.value;
|
|
1433
|
+
if (envelope.ok === false) {
|
|
1434
|
+
const error = envelope.error;
|
|
1435
|
+
throw new Error(typeof error?.message === "string" && error.message !== "" ? error.message : RPC_REQUEST_FAILED);
|
|
1436
|
+
}
|
|
1437
|
+
throw new Error(RPC_INVALID_RESPONSE);
|
|
1438
|
+
}
|
|
1439
|
+
function createKnowledgeRuntime(rpc) {
|
|
1440
|
+
let state = { phase: "idle" };
|
|
1441
|
+
const subscribers = /* @__PURE__ */ new Set();
|
|
1442
|
+
let inFlight;
|
|
1443
|
+
const publish = (next) => {
|
|
1444
|
+
state = next;
|
|
1445
|
+
for (const listener of [...subscribers]) listener();
|
|
1446
|
+
};
|
|
1447
|
+
const call = async (endpoint, payload) => {
|
|
1448
|
+
try {
|
|
1449
|
+
return unwrap(await rpc.call(KNOWLEDGE_CHANNEL, endpoint, payload));
|
|
1450
|
+
} catch (error) {
|
|
1451
|
+
if (!isTransportError(error)) throw error;
|
|
1452
|
+
return unwrap(await rpc.call(KNOWLEDGE_CHANNEL, endpoint, payload));
|
|
1453
|
+
}
|
|
1454
|
+
};
|
|
1455
|
+
const runLoad = async () => {
|
|
1456
|
+
if (state.snapshot === void 0 && state.phase !== "loading") {
|
|
1457
|
+
publish(makeState("loading", void 0, void 0, void 0));
|
|
1458
|
+
}
|
|
1459
|
+
try {
|
|
1460
|
+
const snapshot = await call("snapshot", { sessionId: SETTINGS_SCOPE_SESSION_ID });
|
|
1461
|
+
publish(makeState("ready", snapshot, void 0, Date.now()));
|
|
1462
|
+
} catch (error) {
|
|
1463
|
+
publish(makeState("error", state.snapshot, messageOf(error), state.refreshedAt));
|
|
1464
|
+
}
|
|
1465
|
+
};
|
|
1466
|
+
const load = () => {
|
|
1467
|
+
if (inFlight !== void 0) return inFlight;
|
|
1468
|
+
const promise = runLoad().finally(() => {
|
|
1469
|
+
if (inFlight === promise) inFlight = void 0;
|
|
1470
|
+
});
|
|
1471
|
+
inFlight = promise;
|
|
1472
|
+
return promise;
|
|
1473
|
+
};
|
|
1474
|
+
return {
|
|
1475
|
+
source: {
|
|
1476
|
+
getSnapshot: () => state,
|
|
1477
|
+
subscribe: (listener) => {
|
|
1478
|
+
subscribers.add(listener);
|
|
1479
|
+
if (subscribers.size === 1 && (state.phase === "idle" || state.phase === "error")) void load();
|
|
1480
|
+
return () => {
|
|
1481
|
+
subscribers.delete(listener);
|
|
1482
|
+
};
|
|
1483
|
+
}
|
|
1484
|
+
},
|
|
1485
|
+
refresh: () => load(),
|
|
1486
|
+
saveConfig: async (patch) => {
|
|
1487
|
+
try {
|
|
1488
|
+
const response = await call("config-save", {
|
|
1489
|
+
sessionId: SETTINGS_SCOPE_SESSION_ID,
|
|
1490
|
+
patch
|
|
1491
|
+
});
|
|
1492
|
+
await load();
|
|
1493
|
+
return response.config;
|
|
1494
|
+
} catch (error) {
|
|
1495
|
+
publish(makeState("error", state.snapshot, messageOf(error), state.refreshedAt));
|
|
1496
|
+
throw error;
|
|
1497
|
+
}
|
|
1498
|
+
},
|
|
1499
|
+
testConnection: async () => {
|
|
1500
|
+
const response = await call("config-test", {
|
|
1501
|
+
sessionId: SETTINGS_SCOPE_SESSION_ID
|
|
1502
|
+
});
|
|
1503
|
+
await load();
|
|
1504
|
+
const snapshot = state.snapshot;
|
|
1505
|
+
if (snapshot !== void 0) {
|
|
1506
|
+
publish(makeState(state.phase, { ...snapshot, selfCheck: response.selfCheck }, state.error, Date.now()));
|
|
1507
|
+
}
|
|
1508
|
+
return response.selfCheck;
|
|
1509
|
+
},
|
|
1510
|
+
loadDocs: async (baseId) => {
|
|
1511
|
+
const response = await call("docs", {
|
|
1512
|
+
sessionId: SETTINGS_SCOPE_SESSION_ID,
|
|
1513
|
+
baseId
|
|
1514
|
+
});
|
|
1515
|
+
return response.docs;
|
|
1516
|
+
},
|
|
1517
|
+
loadDocument: async (knowledgeId, page) => {
|
|
1518
|
+
const response = await call("document", {
|
|
1519
|
+
sessionId: SETTINGS_SCOPE_SESSION_ID,
|
|
1520
|
+
knowledgeId,
|
|
1521
|
+
...page === void 0 ? {} : { page }
|
|
1522
|
+
});
|
|
1523
|
+
return response.document;
|
|
1524
|
+
},
|
|
1525
|
+
search: async (query, baseId) => {
|
|
1526
|
+
const response = await call("search", {
|
|
1527
|
+
sessionId: SETTINGS_SCOPE_SESSION_ID,
|
|
1528
|
+
query,
|
|
1529
|
+
...baseId === void 0 ? {} : { baseId }
|
|
1530
|
+
});
|
|
1531
|
+
return response.hits;
|
|
1532
|
+
}
|
|
1533
|
+
};
|
|
1534
|
+
}
|
|
1535
|
+
|
|
76
1536
|
// src/client/styles.css
|
|
77
|
-
var styles_default = "/*\n * hiwork-knowledge \u9875\u9762\u6837\u5F0F\u3002\n *\n * \u4E2D\u592E\u533A\u63A5\u7BA1\u65F6\uFF08`[data-hiwork-feature-root]`\uFF09\u9875\u9762\u6839\u8981\u81EA\u5DF1\u5360\u6EE1\u5269\u4F59\u9AD8\u5EA6\u5E76\u6EDA\u52A8\uFF1B\n * \u964D\u7EA7\u5230\u8BBE\u7F6E\u9875\u5206\u533A\u65F6\uFF08\u6CA1\u6709\u8BE5\u5C5E\u6027\uFF09\u6309\u666E\u901A\u8BBE\u7F6E\u9875\u5185\u5BB9\u6392\u7248\u3002\n */\n.hiwork-knowledge-view {\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 4px 0 24px;\n color: var(--dsw-alias-label-primary, #0f1115);\n}\n[data-hiwork-feature-root] .hiwork-knowledge-view {\n flex: 1;\n min-height: 0;\n padding: 20px 24px 32px;\n overflow-y: auto;\n}\n.hiwork-knowledge-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 12px;\n}\n.hiwork-knowledge-heading {\n display: flex;\n flex-direction: column;\n gap: 4px;\n}\n.hiwork-knowledge-title {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n line-height: 24px;\n}\n.hiwork-knowledge-subtitle {\n margin: 0;\n color: var(--dsw-alias-label-secondary, #61666b);\n font-size: 12px;\n line-height: 18px;\n}\n.hiwork-knowledge-button {\n padding: 6px 12px;\n border: 1px solid var(--dsw-alias-border-l2, rgba(15, 17, 21, 0.1));\n border-radius: 8px;\n background: transparent;\n color: var(--dsw-alias-label-primary, #0f1115);\n font-size: 13px;\n cursor: pointer;\n}\n.hiwork-knowledge-button:hover {\n background: var(--dsw-alias-interactive-bg-hover, rgba(15, 17, 21, 0.06));\n}\n.hiwork-knowledge-placeholder {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 240px;\n padding: 24px;\n border: 1px dashed var(--dsw-alias-border-l2, rgba(15, 17, 21, 0.15));\n border-radius: 12px;\n color: var(--dsw-alias-label-secondary, #61666b);\n font-size: 14px;\n line-height: 22px;\n text-align: center;\n}\n";
|
|
1537
|
+
var styles_default = "/*\n * hiwork-knowledge \u9875\u9762\u6837\u5F0F\uFF08\u7EAF CSS\uFF0C\u8FD0\u884C\u65F6\u7531 installStyles() \u6CE8\u5165 <style>\uFF09\u3002\n *\n * \u5168\u90E8\u989C\u8272\u8D70 DSH \u4E3B\u9898\u53D8\u91CF\u5E76\u5E26\u4EAE\u8272\u964D\u7EA7\u503C\uFF0C\u4EAE\u6697\u4E3B\u9898\u7531\u5BBF\u4E3B\u81EA\u52A8\u5207\u6362\uFF1B\u7C7B\u540D\u7EDF\u4E00\u4EE5\n * hiwork-knowledge- \u524D\u7F00\uFF0C\u907F\u514D\u6C61\u67D3\u5BBF\u4E3B\u6837\u5F0F\u3002\u8BCD\u8868\u4E0E hiwork-automation /\n * hiwork-capabilities \u5BF9\u9F50\uFF08view / header / heading / toolbar / button / tag /\n * count / card / panel / status / notice / muted\uFF09\uFF0C\u4E09\u4E2A\u63D2\u4EF6\u89C6\u89C9\u4E0A\u5C5E\u4E8E\u540C\u4E00\u5BB6\u65CF\u3002\n *\n * \u4E09\u6761\u8E29\u8FC7\u7684\u5751\uFF0C\u90FD\u662F\u5B9E\u6D4B\u51FA\u6765\u7684\uFF08\u6539\u8FD9\u4E2A\u6587\u4EF6\u524D\u5148\u8BFB\uFF0C\u522B\u51ED\u76F4\u89C9\u6539\u56DE\u53BB\uFF09\uFF1A\n *\n * 1. **\u4E3B\u9898\u91CC\u6CA1\u6709 `state-error-tertiary`**\u3002\u4EAE\u6697\u4E24\u5957\u90FD\u53EA\u5B9A\u4E49\u4E86 error-primary\n * \uFF08\u7EBF\u6761/\u6587\u5B57\u8272\uFF09\uFF0C\u6240\u4EE5\u8BED\u4E49\u6DE1\u5E95\u4E00\u5F8B\u5199\u6210\n * `color-mix(in srgb, <primary> 10%, transparent)`\u2014\u2014\u8FD9\u6837\u4EAE\u6697\u90FD\u8DDF\u7740\u4E3B\u9898\u7FFB\u3002\n * success/warn/business \u867D\u7136\u5404\u81EA\u6709 tertiary\uFF0C\u4E5F\u7EDF\u4E00\u7528\u540C\u4E00\u914D\u65B9\uFF0C\u514D\u5F97\u4E24\u5957\u5199\u6CD5\u6DF7\u7740\u957F\u3002\n * 2. **`bg-layer-1/2/3` \u5728\u4EAE\u8272\u4E0B\u5168\u662F `#fff`**\uFF08\u6697\u8272\u624D\u662F bluish-875/850/800\uFF09\u3002\u62FF\u5B83\u5F53\n * \u5361\u7247\u6216\u5FBD\u6807\u7684\u5E95\u7B49\u4E8E\u6CA1\u6709\u5E95\uFF0C\u6240\u4EE5\u5728\u767D\u5E95\u4E0A\u770B\u5F97\u89C1\u7684\u4E2D\u6027\u586B\u5145\u7528 `bg-module-platform`\n * \uFF08\u4EAE #f5f6f7 / \u6697 bluish-800\uFF09\u6216 `interactive-bg-hover`\uFF08\u4EAE #2631480f / \u6697 #ffffff14\uFF09\u3002\n * 3. **\u539F\u751F `<ul>` \u7684\u5706\u70B9\u548C 40px \u5DE6\u7F29\u8FDB\u5FC5\u987B\u663E\u5F0F\u6E05\u6389**\u3002\u4E0A\u4E00\u7248\u6F0F\u4E86 `.hiwork-knowledge-list`\n * \u7684\u89C4\u5219\uFF0C\u6D4F\u89C8\u5668\u9ED8\u8BA4\u6837\u5F0F\u539F\u6837\u751F\u6548\uFF0C\u5217\u8868\u5C31\u6210\u4E86\u300C\u5706\u70B9 + \u63CF\u8FB9\u65B9\u6846\u53E0\u52A0\u300D\u7684\u6837\u5B50\u2014\u2014\n * \u6574\u9875\u6700\u50CF\u300C\u6CA1\u5199\u5B8C\u300D\u7684\u4E00\u5904\u5C31\u662F\u5B83\u3002\n */\n\n.hiwork-knowledge-view {\n display: flex;\n flex-direction: column;\n gap: 12px;\n padding: 4px 0 24px;\n color: var(--dsw-alias-label-primary, #0f1115);\n font-size: 13px;\n line-height: 1.5;\n}\n\n/* \u4E2D\u592E\u533A\u63A5\u7BA1\uFF1A\u9875\u9762\u6839\u5360\u6EE1\u5269\u4F59\u9AD8\u5EA6\uFF0C\u4F46**\u5B83\u81EA\u5DF1\u4E0D\u6EDA**\u3002\n *\n * \u6574\u9875\u6EDA\u52A8\u4F1A\u628A\u9875\u5934\u548C\u68C0\u7D22\u884C\u4E00\u8D77\u5E26\u8D70\uFF1A\u7528\u6237\u5728\u51E0\u767E\u7BC7\u6587\u6863\u91CC\u6EDA\u5230\u4E00\u534A\u60F3\u6362\u4E2A\u77E5\u8BC6\u5E93\u6216\u6539\u68C0\u7D22\u8BCD\uFF0C\n * \u5F97\u5148\u628A\u9875\u9762\u6EDA\u56DE\u9876\u90E8\u2014\u2014\u800C\u8FD9\u4E24\u6837\u6070\u6070\u662F\u6EDA\u52A8\u65F6\u6700\u8BE5\u7559\u5728\u624B\u8FB9\u7684\u4E1C\u897F\u3002\u6EDA\u52A8\u56E0\u6B64\u6536\u8FDB\u5DE6\u53F3\u4E24\u680F\n * \u5404\u81EA\u7684 `.hiwork-knowledge-scroll`\uFF0C\u4E0A\u9762\u90A3\u4E9B\u9489\u4F4F\u4E0D\u52A8\u3002\n *\n * \u964D\u7EA7\u5230\u8BBE\u7F6E\u9875\u5206\u533A\u65F6\u4FDD\u6301\u7D27\u51D1\u5185\u8FB9\u8DDD\uFF1A\u90A3\u8FB9\u6CA1\u6709\u9AD8\u5EA6\u7EA6\u675F\uFF0C\u300C\u586B\u6EE1\u5269\u4F59\u9AD8\u5EA6\u518D\u88C1\u526A\u300D\u7684\u89C4\u5219\n * \u4E5F\u5C31\u65E0\u4ECE\u751F\u6548\uFF08`flex: 1` \u5206\u4E0D\u5230\u9AD8\u5EA6\u3001`overflow` \u6CA1\u6709\u6EA2\u51FA\u53EF\u88C1\uFF09\u3002 */\n[data-hiwork-feature-root] .hiwork-knowledge-view {\n flex: 1;\n min-height: 0;\n padding: 20px 24px 32px;\n overflow: hidden;\n}\n\n/* ---------- \u9875\u5934 ---------- */\n\n.hiwork-knowledge-header {\n display: flex;\n align-items: flex-start;\n justify-content: space-between;\n gap: 12px;\n flex: none;\n padding-bottom: 14px;\n border-bottom: 1px solid var(--dsw-alias-border-l2, rgba(15, 17, 21, 0.1));\n}\n\n.hiwork-knowledge-heading {\n display: flex;\n flex-direction: column;\n gap: 2px;\n min-width: 0;\n}\n\n.hiwork-knowledge-title {\n margin: 0;\n font-size: 16px;\n font-weight: 600;\n line-height: 24px;\n}\n\n.hiwork-knowledge-subtitle {\n margin: 0;\n color: var(--dsw-alias-label-tertiary, #81858c);\n font-size: 12px;\n line-height: 18px;\n}\n\n.hiwork-knowledge-toolbar {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: none;\n}\n\n/* ---------- \u6309\u94AE ----------\n \u4E0E hiwork-automation / hiwork-capabilities \u9010\u5B57\u5BF9\u9F50\uFF08\u540C\u4E00\u5BB6\u65CF\u7684\u552F\u4E00\u6309\u94AE\u6837\u5F0F\uFF09\uFF1A\n 12px \u5B57\u30018px \u5706\u89D2\u3001\u900F\u660E\u5E95 + l2 \u63CF\u8FB9\uFF0Chover \u624D\u51FA\u6D45\u5E95\u3002 */\n.hiwork-knowledge-button {\n display: inline-flex;\n align-items: center;\n gap: 5px;\n padding: 5px 12px;\n border: 1px solid var(--dsw-alias-border-l2, rgba(15, 17, 21, 0.1));\n border-radius: 8px;\n background: transparent;\n color: var(--dsw-alias-label-secondary, #61666b);\n font-family: inherit;\n font-size: 12px;\n line-height: 18px;\n cursor: pointer;\n}\n\n.hiwork-knowledge-button:hover:not(:disabled) {\n background: var(--dsw-alias-interactive-bg-hover, rgba(15, 17, 21, 0.06));\n color: var(--dsw-alias-label-primary, #0f1115);\n}\n\n.hiwork-knowledge-button:disabled {\n opacity: 0.45;\n cursor: not-allowed;\n}\n\n.hiwork-knowledge-button:focus-visible {\n outline: 2px solid var(--dsw-alias-state-business-primary, #4176e6);\n outline-offset: 1px;\n}\n\n.hiwork-knowledge-button.is-primary {\n border-color: transparent;\n background: var(--dsw-alias-state-business-primary, #4176e6);\n color: #ffffff;\n}\n\n.hiwork-knowledge-button.is-primary:hover:not(:disabled) {\n color: #ffffff;\n filter: brightness(1.08);\n}\n\n/* \u56FE\u6807\u968F\u6309\u94AE\u6587\u5B57\u8272\uFF0C\u5C3A\u5BF8\u4EA4\u7ED9 SVG \u81EA\u8EAB\u7684 width/height\u3002 */\n.hiwork-knowledge-button-icon {\n display: inline-flex;\n flex: none;\n}\n\n/* \u68C0\u7D22\u6309\u94AE\u4E0E\u7D27\u90BB\u7684\u8F93\u5165\u6846**\u7B49\u9AD8**\uFF1A\u8F93\u5165\u6846\u662F 13px \u884C\u9AD8 + 6px \u4E0A\u4E0B\u5185\u8FB9\u8DDD + 1px \u63CF\u8FB9 = 32px\uFF0C\n \u800C\u6309\u94AE\u9ED8\u8BA4 12px \u884C\u9AD8 + 5px = 30px\uFF0C\u5DEE\u8FD9 2px \u5E76\u6392\u65F6\u8089\u773C\u5C31\u80FD\u770B\u51FA\u6CA1\u5BF9\u9F50\u3002 */\n.hiwork-knowledge-search .hiwork-knowledge-button {\n padding: 6px 14px;\n font-size: 13px;\n}\n\n/* ---------- \u63D0\u793A\u6A2A\u5E45\uFF08\u9519\u8BEF / \u8B66\u544A / \u4E2D\u6027\uFF09 ---------- */\n\n.hiwork-knowledge-notice {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: none;\n padding: 8px 10px;\n border: 1px solid var(--dsw-alias-border-l2, rgba(15, 17, 21, 0.1));\n border-radius: 8px;\n background: var(--dsw-alias-bg-overlay, #e9ecf2);\n color: var(--dsw-alias-label-secondary, #61666b);\n font-size: 12px;\n line-height: 18px;\n}\n\n.hiwork-knowledge-notice.is-error {\n border-color: color-mix(in srgb, var(--dsw-alias-state-error-primary, #ec1313) 22%, transparent);\n background: color-mix(in srgb, var(--dsw-alias-state-error-primary, #ec1313) 8%, transparent);\n color: var(--dsw-alias-state-error-primary, #ec1313);\n}\n\n.hiwork-knowledge-notice.is-warn {\n border-color: color-mix(in srgb, var(--dsw-alias-state-warn-primary, #f59e0b) 26%, transparent);\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary, #f59e0b) 10%, transparent);\n color: var(--dsw-alias-state-warn-label, var(--dsw-alias-state-warn-primary, #dd8629));\n}\n\n.hiwork-knowledge-notice-icon {\n display: flex;\n flex: none;\n}\n\n/* \u6587\u6848\u5360\u6EE1\u5269\u4F59\u5BBD\u5EA6\uFF0C\u64CD\u4F5C\u6309\u94AE\u56E0\u6B64\u88AB\u63A8\u5230\u6700\u53F3\u3002 */\n.hiwork-knowledge-notice-text {\n flex: 1;\n min-width: 0;\n overflow-wrap: anywhere;\n}\n\n/* \u9519\u8BEF\u6A2A\u5E45\u91CC\u7684\u300C\u91CD\u8BD5\u300D\u522B\u7EE7\u627F\u9519\u8BEF\u8272\uFF0C\u5426\u5219\u6574\u6761\u6A2A\u5E45\u7EA2\u6210\u4E00\u7247\u3001\u6309\u94AE\u53CD\u800C\u770B\u4E0D\u51FA\u80FD\u70B9\u3002 */\n.hiwork-knowledge-notice.is-error .hiwork-knowledge-button {\n flex: none;\n border-color: color-mix(in srgb, var(--dsw-alias-state-error-primary, #ec1313) 40%, transparent);\n color: var(--dsw-alias-state-error-primary, #ec1313);\n}\n\n/* ---------- \u4E24\u680F\u9AA8\u67B6 ---------- */\n\n.hiwork-knowledge-columns {\n display: flex;\n flex-wrap: wrap;\n align-items: stretch;\n gap: 16px;\n min-height: 0;\n}\n\n[data-hiwork-feature-root] .hiwork-knowledge-columns {\n flex: 1;\n}\n\n.hiwork-knowledge-panel {\n display: flex;\n flex-direction: column;\n gap: 10px;\n min-width: 0;\n min-height: 0;\n}\n\n/* \u5DE6\u680F\u5B9A\u5BBD\uFF08\u77E5\u8BC6\u5E93\u662F\u9009\u62E9\u5668\uFF0C\u4E0D\u9700\u8981\u8DDF\u7740\u7A97\u53E3\u53D8\u5BBD\uFF09\uFF1B\u53F3\u680F\u5403\u6389\u5269\u4F59\u5BBD\u5EA6\u3002\n \u5BB9\u5668\u592A\u7A84\u65F6\uFF08\u8BBE\u7F6E\u9875\u5206\u533A\u964D\u7EA7\uFF09\u9760 flex-wrap \u81EA\u52A8\u6298\u884C\uFF0C\u4E0D\u9700\u8981\u5A92\u4F53\u67E5\u8BE2\u3002 */\n.hiwork-knowledge-panel.is-bases {\n flex: 0 0 272px;\n /* \u7ED9\u5BFC\u8F68\u94FA\u4E00\u5C42\u6D45\u5E95\uFF1A\u4E24\u680F\u4E4B\u95F4\u53EA\u9760 24px \u7A7A\u767D\u5206\u9694\u65F6\uFF0C\u5DE6\u680F\u770B\u8D77\u6765\u50CF\u300C\u6D6E\u5728\u767D\u7EB8\u4E0A\u300D\uFF0C\n \u94FA\u5E95\u4E4B\u540E\u4ECE\u5E93\u5230\u6587\u6863\u7684\u4E3B\u4ECE\u5173\u7CFB\u4E00\u773C\u53EF\u89C1\uFF0C\u6298\u884C\u5806\u53E0\u65F6\u4E5F\u4E0D\u4F1A\u663E\u5F97\u7A81\u5140\u3002 */\n padding: 10px;\n border-radius: 12px;\n background: var(--dsw-alias-bg-module-platform, #f5f6f7);\n}\n\n.hiwork-knowledge-panel.is-detail {\n flex: 1 1 380px;\n}\n\n[data-hiwork-feature-root] .hiwork-knowledge-panel {\n overflow: hidden;\n}\n\n/* \u4ECE\u9875\u9762\u6839\u5230\u5217\u8868\u4E4B\u95F4\u7684\u6BCF\u4E00\u5C42\u90FD\u8981\u80FD**\u628A\u9AD8\u5EA6\u4F20\u4E0B\u53BB**\uFF0C\u5426\u5219\u6700\u91CC\u9762\u90A3\u5C42\u62FF\u4E0D\u5230\u7EA6\u675F\u3002\n `min-height: 0` \u5C24\u5176\u4E0D\u80FD\u6F0F\uFF1Aflex \u5B50\u9879\u7684\u9ED8\u8BA4\u6700\u5C0F\u9AD8\u5EA6\u662F\u5185\u5BB9\u9AD8\u5EA6\uFF0C\u5C11\u4E86\u5B83\u8FD9\u6761\u94FE\n \u6BCF\u4E00\u5C42\u90FD\u4F1A\u88AB\u5185\u5BB9\u9876\u5F00\uFF0C`overflow: hidden` \u5C31\u6210\u4E86\u300C\u628A\u4E0B\u9762\u88C1\u6389\u300D\u800C\u4E0D\u662F\u300C\u8BA9\u4E0B\u9762\u6EDA\u300D\u3002 */\n[data-hiwork-feature-root] .hiwork-knowledge-scroll {\n display: flex;\n flex-direction: column;\n gap: 8px;\n flex: 1;\n min-height: 0;\n overflow-y: auto;\n /* \u5217\u8868\u6EDA\u5230\u5E95\u65F6\u4E0D\u8981\u987A\u5E26\u6EDA\u7236\u7EA7\uFF08\u5426\u5219\u6574\u9875\u4F1A\u8DDF\u7740\u5F39\u4E00\u4E0B\uFF09\u3002 */\n overscroll-behavior: contain;\n}\n\n.hiwork-knowledge-panel-head {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: none;\n min-width: 0;\n min-height: 22px;\n}\n\n/* \u5217\u8868\u5934**\u4E0D\u662F\u6807\u9898\uFF0C\u662F\u6807\u7B7E**\uFF1A12px/600 + \u6B21\u7EA7\u8272 + \u8F7B\u5FAE\u5B57\u8DDD\uFF0C\u6BD4\u5185\u5BB9\u6807\u9898\uFF0813px/600 \u4E3B\u8272\uFF09\n \u66F4\u5C0F\u66F4\u6DE1\u3002\u88F8 `<h2>` \u4F1A\u88AB\u6D4F\u89C8\u5668\u6E32\u67D3\u6210 1.5em \u7C97\u4F53\uFF08\u6BD4\u9875\u5934 16px \u8FD8\u5927\uFF09\uFF0C\u5C42\u7EA7\u76F4\u63A5\u53CD\u8FC7\u6765\u2014\u2014\n \u4E0A\u4E00\u7248\u300C\u77E5\u8BC6\u5E93 / \u6587\u6863\u300D\u4E24\u4E2A 24px \u5927\u6807\u9898\u5C31\u662F\u8FD9\u4E48\u6765\u7684\uFF1B\u800C\u5982\u679C\u628A\u5B83\u505A\u6210\u548C\u5185\u5BB9\u540C\u7EA7\u7684\u6807\u9898\n \uFF08\u5B9E\u6D4B 13~14px/600\uFF09\uFF0C\u4E00\u5C4F\u91CC\u5C31\u4F1A\u51FA\u73B0\u56DB\u4E2A\u4E92\u76F8\u7ADE\u4E89\u7684\u300C\u6807\u9898\u300D\uFF0C\u626B\u8BFB\u6293\u4E0D\u4F4F\u4E3B\u5E72\u3002\n \u8FD9\u4E5F\u662F hiwork-automation / hiwork-capabilities \u91CC\u5206\u7EC4\u6807\u7B7E\u7684\u65E2\u6709\u505A\u6CD5\u3002 */\n.hiwork-knowledge-panel-title {\n margin: 0;\n color: var(--dsw-alias-label-secondary, #61666b);\n font-size: 12px;\n font-weight: 600;\n letter-spacing: 0.02em;\n line-height: 18px;\n white-space: nowrap;\n}\n\n.hiwork-knowledge-panel-subtitle {\n margin: 0;\n color: var(--dsw-alias-label-secondary, #61666b);\n font-size: 12px;\n font-weight: 600;\n}\n\n/* \u8BA1\u6570\u5FBD\u6807\uFF1A\u53EA\u653E\u6570\u5B57\uFF08\u8BCD\u8868\u91CC\u4E0D\u9700\u8981\u4E3A\u5B83\u9020\u4E00\u4E2A\u5E26\u5355\u4F4D\u7684\u952E\uFF09\u3002\n *\n * **\u7528\u63CF\u8FB9\u800C\u4E0D\u662F\u586B\u5145**\uFF1A\u586B\u5145\u8272\uFF08`bg-module-platform`\uFF09\u4E0E\u5DE6\u680F\u5BFC\u8F68\u7684\u5E95\u8272\u662F\u540C\u4E00\u4E2A\u503C\uFF0C\n * \u5FBD\u6807\u94FA\u5728\u5BFC\u8F68\u4E0A\u4F1A\u76F4\u63A5\u9690\u5F62\uFF08\u5B9E\u6D4B\uFF1A\u622A\u56FE\u4E0A\u53EA\u5269\u4E00\u4E2A\u6CA1\u6709\u5BB9\u5668\u7684\u88F8\u6570\u5B57\uFF0C\u8BFB\u8D77\u6765\u50CF\u9519\u5B57\uFF09\u3002\n * \u63CF\u8FB9\u5F0F\u5728\u767D\u8272\u53F3\u680F\u548C\u6D45\u7070\u5BFC\u8F68\u4E0A\u90FD\u6210\u7ACB\uFF0C\u4E24\u680F\u7684\u8BA1\u6570\u56E0\u6B64\u80FD\u4FDD\u6301\u540C\u4E00\u79CD\u89C2\u611F\u3002 */\n.hiwork-knowledge-count {\n flex: none;\n padding: 0 6px;\n border-radius: 999px;\n box-shadow: inset 0 0 0 1px var(--dsw-alias-border-l2, rgba(15, 17, 21, 0.12));\n color: var(--dsw-alias-label-secondary, #61666b);\n font-size: 11px;\n font-weight: 500;\n line-height: 17px;\n}\n\n/* \u4E24\u680F\u7684\u8BA1\u6570\u4F4D\u7F6E\u5FC5\u987B\u4E00\u81F4\uFF1A\u90FD\u7D27\u8DDF\u5404\u81EA\u7684\u6807\u9898\uFF08\u8D34\u53F3\u7684\u8BDD\uFF0C\u540C\u4E00\u9875\u91CC\u4F1A\u51FA\u73B0\n \u300C\u5DE6\u680F\u7D27\u8DDF\u6807\u9898\u3001\u53F3\u680F\u63A8\u5230\u6700\u53F3\u300D\u4E24\u5957\u89C4\u5219\uFF09\u3002\u9700\u8981\u8D34\u53F3\u7684\u53EA\u6709\u64CD\u4F5C\u6309\u94AE\u3002 */\n.hiwork-knowledge-panel-head > .hiwork-knowledge-button {\n margin-left: auto;\n flex: none;\n}\n\n/* \u53F3\u680F\u7684\u5217\u8868\u5934\u505A\u6210\u4E00\u6761\u5206\u9694\u5E26\uFF1A\u68C0\u7D22\u884C \u2192 \u5217\u8868\u5934 \u2192 \u5361\u7247\u539F\u672C\u6324\u5728\u540C\u4E00\u6839\u7AD6\u8F74\u4E0A\uFF0C\n \u6CA1\u6709\u4EFB\u4F55\u5206\u7EC4\u624B\u6BB5\uFF0C\u7528\u6237\u770B\u4E0D\u51FA\u300C\u6587\u6863\u300D\u8FD9\u884C\u7BA1\u7740\u4E0B\u9762\u54EA\u4E9B\u5185\u5BB9\u3002 */\n.hiwork-knowledge-panel.is-detail .hiwork-knowledge-panel-head {\n padding-bottom: 8px;\n border-bottom: 1px solid var(--dsw-alias-border-l2, rgba(15, 17, 21, 0.1));\n}\n\n/* \u5F53\u524D\u77E5\u8BC6\u5E93\u540D\uFF1A\u957F\u540D\u5B57\u5FC5\u987B\u80FD\u7701\u7565\u53F7\u6536\u5C3E\uFF0C\u5426\u5219\u4F1A\u628A\u8BA1\u6570\u548C\u6309\u94AE\u6324\u51FA\u9762\u677F\u3002 */\n.hiwork-knowledge-scope {\n flex: 0 1 auto;\n min-width: 0;\n max-width: 260px;\n padding: 1px 8px;\n border-radius: 999px;\n background: var(--dsw-alias-bg-module-platform, #f5f6f7);\n color: var(--dsw-alias-label-secondary, #61666b);\n font-size: 11px;\n line-height: 17px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* ---------- \u68C0\u7D22\u884C ---------- */\n\n.hiwork-knowledge-search {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: none;\n}\n\n.hiwork-knowledge-search-field {\n position: relative;\n display: flex;\n align-items: center;\n flex: 1;\n min-width: 0;\n}\n\n.hiwork-knowledge-search-icon {\n position: absolute;\n left: 10px;\n display: flex;\n color: var(--dsw-alias-label-caption, #adb2b8);\n pointer-events: none;\n}\n\n/* \u8F93\u5165\u6846\u57FA\u7840\u6837\u5F0F\uFF1A\u8BBE\u7F6E\u9875\u7684\u666E\u901A\u5B57\u6BB5\u4E5F\u590D\u7528\u8FD9\u4E2A\u7C7B\uFF0C\u6240\u4EE5**\u4E0D\u52A0**\u56FE\u6807\u5185\u7F29\u3002\n \u56FE\u6807\u5DE6\u4FA7\u7684 30px \u5185\u8FB9\u8DDD\u53EA\u5728 `.hiwork-knowledge-search` \u91CC\u53E0\u52A0\u2014\u2014\u4E0A\u4E00\u7248\u628A\n \u68C0\u7D22\u6846\u5BBD\u5EA6\u5199\u6B7B\u6210 155px\uFF0C\u5360\u4F4D\u6587\u6848\u76F4\u63A5\u88AB\u622A\u65AD\u3002 */\n.hiwork-knowledge-input {\n width: 100%;\n min-width: 0;\n padding: 6px 10px;\n border: 1px solid var(--dsw-alias-border-l2, rgba(15, 17, 21, 0.1));\n border-radius: 8px;\n background: var(--dsw-alias-bg-layer-1, #ffffff);\n color: inherit;\n font-family: inherit;\n font-size: 13px;\n line-height: 18px;\n}\n\n.hiwork-knowledge-search .hiwork-knowledge-input {\n padding-left: 30px;\n}\n\n.hiwork-knowledge-input::placeholder {\n /* \u7528 tertiary \u800C\u4E0D\u662F caption\uFF1A\u5360\u4F4D\u7B26\u662F\u7528\u6237\u7B2C\u4E00\u773C\u8981\u8BFB\u7684\u5F15\u5BFC\u6587\u6848\uFF0C\n caption(#adb2b8) \u5728\u767D\u5E95\u4E0A\u5BF9\u6BD4\u5EA6\u504F\u4F4E\uFF0C\u5B9E\u6D4B\u5728\u622A\u56FE\u91CC\u51E0\u4E4E\u770B\u4E0D\u89C1\u3002 */\n color: var(--dsw-alias-label-tertiary, #81858c);\n}\n\n.hiwork-knowledge-input:focus {\n outline: none;\n border-color: var(--dsw-alias-state-business-primary, #4176e6);\n box-shadow: 0 0 0 2px color-mix(in srgb, var(--dsw-alias-state-business-primary, #4176e6) 18%, transparent);\n}\n\n/* ---------- \u5217\u8868\uFF08\u5706\u70B9\u4E0E\u7F29\u8FDB\u5FC5\u987B\u6E05\u6389\uFF09 ---------- */\n\n.hiwork-knowledge-list {\n display: flex;\n flex-direction: column;\n /* \u5217\u8868\u9879\u95F4\u8DDD\u53D6 10px\u3001\u9762\u677F\u5185\u533A\u5757\u95F4\u8DDD\u53D6 10px\u3001\u884C\u5185\u5143\u7D20\u95F4\u8DDD 6~8px\uFF1A\n \u4E09\u6863\u62C9\u5F00\u4E4B\u540E\u300C\u6807\u9898\u7BA1\u7740\u54EA\u4E9B\u884C\u300D\u624D\u770B\u5F97\u51FA\u6765\uFF08\u4E0A\u4E00\u7248\u5168\u662F 8px\uFF0C\u8282\u594F\u662F\u5E73\u7684\uFF09\u3002 */\n gap: 10px;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.hiwork-knowledge-list > li {\n margin: 0;\n}\n\n/* ---------- \u77E5\u8BC6\u5E93\u6761\u76EE\uFF08\u5DE6\u680F\uFF0C\u53EF\u9009\u4E2D\uFF09 ---------- */\n\n.hiwork-knowledge-base {\n display: flex;\n flex-direction: column;\n /* 4px \u800C\u4E0D\u662F 2px\uFF1A\u8FD9\u4E00\u680F\u6700\u591A\u4F1A\u6709\u4E09\u884C\uFF08\u5E93\u540D / \u63CF\u8FF0 / \u6587\u6863\u6570\u4E0E\u66F4\u65B0\u65F6\u95F4\uFF09\uFF0C\n 2px \u65F6\u4E09\u884C\u7CCA\u6210\u4E00\u5757\uFF0C\u770B\u4E0D\u51FA\u662F\u4E09\u4E2A\u5B57\u6BB5\u3002 */\n gap: 4px;\n width: 100%;\n padding: 10px 12px;\n /* button \u9ED8\u8BA4\u4E0D\u7EE7\u627F font-size\uFF08\u6D4F\u89C8\u5668\u7ED9 13.33px\uFF09\uFF0C\u663E\u5F0F\u7EE7\u627F\u4EE5\u514D\u540E\u4EE3\u7B97\u51FA\u610F\u5916\u7684\u884C\u9AD8\u3002 */\n font-size: inherit;\n border: 1px solid var(--dsw-alias-border-l2, rgba(15, 17, 21, 0.1));\n border-radius: 10px;\n background: var(--dsw-alias-bg-layer-1, #ffffff);\n color: inherit;\n font-family: inherit;\n text-align: left;\n cursor: pointer;\n transition: border-color 0.12s ease, background 0.12s ease;\n}\n\n.hiwork-knowledge-base:hover {\n border-color: var(--dsw-alias-border-l4, rgba(15, 17, 21, 0.2));\n}\n\n/* \u9009\u4E2D\u6001\u7528\u300C\u63CF\u8FB9 + \u6DE1\u5E95 + \u540D\u79F0\u67D3\u8272\u300D\u4E09\u91CD\u4FE1\u53F7\u3002\u53EA\u9760\u4E00\u5757\u6D45\u7070\u5E95\u4E0D\u591F\uFF1Ahover \u4E5F\u662F\u6D45\u7070\uFF0C\n \u7528\u6237\u5206\u4E0D\u6E05\u300C\u9009\u4E2D\u300D\u548C\u300C\u9F20\u6807\u521A\u597D\u505C\u5728\u8FD9\u300D\u3002 */\n.hiwork-knowledge-base.is-active {\n border-color: color-mix(in srgb, var(--dsw-alias-state-business-primary, #4176e6) 40%, transparent);\n background: color-mix(in srgb, var(--dsw-alias-state-business-primary, #4176e6) 5%, transparent);\n}\n\n.hiwork-knowledge-base.is-active:hover {\n border-color: color-mix(in srgb, var(--dsw-alias-state-business-primary, #4176e6) 60%, transparent);\n}\n\n/* \u9009\u4E2D\u9879\u7684\u6807\u9898**\u4E0D\u67D3\u84DD**\uFF1A\u540D\u79F0\u672C\u6765\u5C31\u5DF2\u7ECF\u662F 600 \u4E3B\u8272\u3001\u4E14\u5E26\u84DD\u63CF\u8FB9 + \u6DE1\u84DD\u5E95\uFF0C\n \u518D\u628A\u6587\u5B57\u67D3\u6210\u94FE\u63A5\u84DD\u65E2\u91CD\u590D\u8868\u8FBE\u540C\u4E00\u4EF6\u4E8B\uFF0C\u53C8\u5BB9\u6613\u88AB\u8BEF\u8BFB\u6210\u53EF\u70B9\u7684\u8D85\u94FE\u63A5\u3002 */\n.hiwork-knowledge-base.is-active .hiwork-knowledge-base-desc {\n color: var(--dsw-alias-label-secondary, #61666b);\n}\n\n.hiwork-knowledge-base:focus-visible {\n outline: 2px solid var(--dsw-alias-state-business-primary, #4176e6);\n outline-offset: 1px;\n}\n\n.hiwork-knowledge-base-name {\n color: var(--dsw-alias-label-primary, #0f1115);\n font-size: 13px;\n font-weight: 600;\n line-height: 20px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.hiwork-knowledge-base-meta {\n color: var(--dsw-alias-label-caption, #adb2b8);\n font-size: 11px;\n line-height: 16px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* \u77E5\u8BC6\u5E93\u63CF\u8FF0\uFF1A\u4E00\u884C\u622A\u65AD\u3002\u5B83\u5728\u5361\u7247\u91CC\u662F\u300C\u8FD9\u4E2A\u5E93\u662F\u5E72\u561B\u7684\u300D\uFF0C\u6BD4\u6587\u6863\u6570\u66F4\u80FD\u5E2E\u7528\u6237\u9009\u5BF9\u5E93\uFF1B\n \u622A\u65AD\u662F\u4E3A\u4E86\u5361\u7247\u9AD8\u5EA6\u4E00\u81F4\uFF08\u957F\u63CF\u8FF0\u9760 title \u63D0\u793A\u770B\u5168\uFF09\u3002 */\n.hiwork-knowledge-base-desc {\n color: var(--dsw-alias-label-tertiary, #81858c);\n font-size: 11px;\n line-height: 16px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* ---------- \u6587\u6863\u6761\u76EE ---------- */\n\n.hiwork-knowledge-doc {\n display: flex;\n align-items: center;\n gap: 10px;\n padding: 10px 12px;\n border: 1px solid var(--dsw-alias-border-l2, rgba(15, 17, 21, 0.1));\n border-radius: 10px;\n background: var(--dsw-alias-bg-layer-1, #ffffff);\n transition: border-color 0.12s ease, box-shadow 0.12s ease;\n}\n\n.hiwork-knowledge-doc:hover {\n border-color: var(--dsw-alias-border-l4, rgba(15, 17, 21, 0.2));\n box-shadow: 0 2px 10px rgba(15, 17, 21, 0.06);\n}\n\n/* \u6587\u4EF6\u7C7B\u578B\u5FBD\u6807\uFF1A\u56FA\u5B9A 32px \u65B9\u5757\uFF0C\u6269\u5C55\u540D\u5C45\u4E2D\u3002\u4E0D\u7528\u56FE\u6807\u533A\u5206\u7C7B\u578B\u2014\u20144 \u4E2A\u5B57\u7B26\u7684\n \u7C7B\u578B\u540D\u6BD4\u4E00\u5806\u96BE\u4EE5\u8FA8\u8BA4\u7684\u56FE\u6807\u66F4\u597D\u626B\u8BFB\uFF0C\u4E5F\u4E0D\u7528\u4E3A\u6BCF\u79CD\u7C7B\u578B\u7EF4\u62A4\u4E00\u5F20\u6620\u5C04\u8868\u3002 */\n.hiwork-knowledge-doc-icon {\n display: flex;\n align-items: center;\n justify-content: center;\n flex: none;\n width: 32px;\n height: 32px;\n border-radius: 8px;\n background: var(--dsw-alias-bg-module-platform, #f5f6f7);\n color: var(--dsw-alias-label-tertiary, #81858c);\n font-size: 10px;\n font-weight: 600;\n letter-spacing: 0.02em;\n}\n\n/* \u7C7B\u578B\u5FBD\u6807\u6309\u6587\u4EF6\u7C7B\u578B\u7740\u8272\uFF1A\u7EAF\u7070\u65B9\u5757\u5728\u5217\u8868\u91CC\u50CF\u6CA1\u8BBE\u8BA1\u8FC7\u7684\u5360\u4F4D\u7B26\uFF0C\u7740\u8272\u540E\u80FD\u51ED\u989C\u8272\u626B\u8BFB\u3002\n \u914D\u8272\u8D70\u4E0E tag \u76F8\u540C\u7684 `color-mix(\u4E3B\u8272 12%, transparent)` \u914D\u65B9\uFF08\u7406\u7531\u89C1\u6587\u4EF6\u5934\u7B2C 1 \u6761\uFF09\u3002 */\n.hiwork-knowledge-doc-icon.is-blue {\n background: color-mix(in srgb, var(--dsw-alias-state-business-primary, #4176e6) 12%, transparent);\n color: var(--dsw-alias-state-business-primary, #4176e6);\n}\n\n.hiwork-knowledge-doc-icon.is-green {\n background: color-mix(in srgb, var(--dsw-alias-state-success-primary, #22c55e) 14%, transparent);\n color: var(--dsw-alias-state-success-primary, #22c55e);\n}\n\n.hiwork-knowledge-doc-icon.is-amber {\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary, #f59e0b) 14%, transparent);\n color: var(--dsw-alias-state-warn-label, var(--dsw-alias-state-warn-primary, #dd8629));\n}\n\n.hiwork-knowledge-doc-icon.is-red {\n background: color-mix(in srgb, var(--dsw-alias-state-error-primary, #ec1313) 12%, transparent);\n color: var(--dsw-alias-state-error-primary, #ec1313);\n}\n\n.hiwork-knowledge-doc-icon.is-neutral {\n /* \u663E\u5F0F\u5199\u51FA\u6765\uFF08\u800C\u4E0D\u662F\u9760\u9ED8\u8BA4\u89C4\u5219\u515C\u5E95\uFF09\uFF1A\u7C7B\u578B\u8272\u8C03\u662F\u6570\u636E\u9A71\u52A8\u7684\u7C7B\u540D\uFF0C\n \u7F3A\u4E00\u6761\u89C4\u5219\u5C31\u4F1A\u9759\u9ED8\u9000\u5316\u6210\u65E0\u6837\u5F0F\u65B9\u5757\uFF0C\u8FD9\u91CC\u8BA9\u5B83\u6709\u4E2A\u660E\u786E\u7684\u843D\u70B9\u3002 */\n background: var(--dsw-alias-interactive-bg-hover, rgba(15, 17, 21, 0.06));\n color: var(--dsw-alias-label-tertiary, #81858c);\n}\n\n.hiwork-knowledge-doc-main {\n display: flex;\n flex-direction: column;\n gap: 2px;\n flex: 1;\n min-width: 0;\n}\n\n/* \u6587\u6863\u884C\u4E3B\u4F53\u662F\u6309\u94AE\uFF08\u70B9\u5F00\u6B63\u6587\uFF09\uFF1A\u6E05\u6389\u6309\u94AE\u9ED8\u8BA4\u5916\u89C2\u4E0E\u5185\u8FB9\u8DDD\uFF0C\u8BA9\u5B83\u770B\u8D77\u6765\u4ECD\u662F\u90A3\u884C\u6587\u5B57\u3002 */\n.hiwork-knowledge-doc-main.is-button {\n padding: 0;\n border: none;\n background: transparent;\n color: inherit;\n font-family: inherit;\n text-align: left;\n cursor: pointer;\n}\n\n.hiwork-knowledge-doc-main.is-button:hover .hiwork-knowledge-doc-title {\n color: var(--dsw-alias-state-business-primary, #4176e6);\n}\n\n.hiwork-knowledge-doc-main.is-button:focus-visible {\n outline: 2px solid var(--dsw-alias-state-business-primary, #4176e6);\n outline-offset: 2px;\n border-radius: 4px;\n}\n\n.hiwork-knowledge-doc-title {\n color: var(--dsw-alias-label-primary, #0f1115);\n font-size: 13px;\n font-weight: 600;\n line-height: 20px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.hiwork-knowledge-doc-meta {\n color: var(--dsw-alias-label-caption, #adb2b8);\n font-size: 11px;\n line-height: 16px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* ---------- \u8BED\u4E49\u5FBD\u6807 ----------\n \u4E0E\u5BBF\u4E3B\u81EA\u5E26\u7684 tag \u7EC4\u4EF6\u540C\u4E00\u914D\u65B9\uFF1A999px \u5706\u89D2\u30011px 8px \u5185\u8FB9\u8DDD\u300111px \u5B57\uFF0C\n \u6DE1\u5E95\u4E00\u5F8B `color-mix(\u4E3B\u8272 10~12%, transparent)`\uFF08\u539F\u56E0\u89C1\u6587\u4EF6\u5934\u7B2C 1 \u6761\uFF09\u3002 */\n.hiwork-knowledge-tag {\n display: inline-flex;\n align-items: center;\n flex: none;\n padding: 1px 8px;\n border-radius: 999px;\n background: var(--dsw-alias-bg-module-platform, #f5f6f7);\n color: var(--dsw-alias-label-secondary, #61666b);\n font-size: 11px;\n font-weight: 500;\n line-height: 17px;\n white-space: nowrap;\n}\n\n.hiwork-knowledge-tag.is-success {\n background: color-mix(in srgb, var(--dsw-alias-state-success-primary, #22c55e) 10%, transparent);\n color: var(--dsw-alias-state-success-primary, #22c55e);\n}\n\n.hiwork-knowledge-tag.is-info {\n background: color-mix(in srgb, var(--dsw-alias-state-business-primary, #4176e6) 10%, transparent);\n color: var(--dsw-alias-state-business-primary, #4176e6);\n}\n\n.hiwork-knowledge-tag.is-warning {\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary, #f59e0b) 12%, transparent);\n color: var(--dsw-alias-state-warn-label, var(--dsw-alias-state-warn-primary, #dd8629));\n}\n\n.hiwork-knowledge-tag.is-danger {\n background: color-mix(in srgb, var(--dsw-alias-state-error-primary, #ec1313) 10%, transparent);\n color: var(--dsw-alias-state-error-primary, #ec1313);\n}\n\n/* \u4E2D\u6027\u5FBD\u6807\uFF1A\u4E0D\u586B\u8272\u3001\u4E0D\u5E26\u63CF\u8FB9\uFF0C\u6539\u7528**\u524D\u5BFC\u72B6\u6001\u70B9**\u3002\n *\n * \u4E0A\u4E00\u7248\u7ED9\u5B83\u52A0\u4E86\u63CF\u8FB9\uFF0C\u7ED3\u679C\u548C\u5217\u8868\u5934\u91CC\u7684\u8303\u56F4\u80F6\u56CA\uFF08\u540C\u6837\u662F\u6D45\u8272\u5706\u89D2\u80F6\u56CA\uFF09\u957F\u5F97\u51E0\u4E4E\u4E00\u6837\uFF1A\n * \u300C\u5DF2\u5C31\u7EEA\u300D\u662F\u72B6\u6001\u3001\u8303\u56F4\u80F6\u56CA\u662F\u7B5B\u9009\u6761\u4EF6\uFF0C\u4E24\u4E2A\u4E0D\u540C\u8BED\u4E49\u7684\u4E1C\u897F\u649E\u6B3E\uFF0C\u8BFB\u8D77\u6765\u5BB9\u6613\u6DF7\u3002\n * \u5E26\u70B9\u7684\u5199\u6CD5\u662F\u72B6\u6001\u6307\u793A\u7684\u901A\u884C\u5F62\u6001\uFF0C\u4E00\u773C\u5C31\u80FD\u548C\u80F6\u56CA\u533A\u5206\uFF1B\u4E5F\u4E0D\u586B\u8272\uFF0C\u56E0\u4E3A\u540C\u5C4F\u6B63\u5E38\u6587\u6863\n * \u5360\u591A\u6570\u65F6\uFF0C\u9010\u884C\u4E0A\u8272\u53EA\u4F1A\u628A\u771F\u6B63\u5931\u8D25\u7684\u6587\u6863\u6DF9\u6389\uFF08\u89C1 `statusTone` \u7684\u8BF4\u660E\uFF09\u3002 */\n.hiwork-knowledge-tag.is-neutral {\n gap: 0;\n background: transparent;\n box-shadow: none;\n color: var(--dsw-alias-label-secondary, #61666b);\n}\n\n.hiwork-knowledge-tag.is-neutral::before {\n content: '';\n flex: none;\n width: 5px;\n height: 5px;\n margin-right: 5px;\n border-radius: 50%;\n background: currentColor;\n}\n\n/* ---------- \u68C0\u7D22\u547D\u4E2D ---------- */\n\n.hiwork-knowledge-hit {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 10px 12px;\n border: 1px solid var(--dsw-alias-border-l2, rgba(15, 17, 21, 0.1));\n border-radius: 10px;\n background: var(--dsw-alias-bg-layer-1, #ffffff);\n}\n\n.hiwork-knowledge-hit-head {\n display: flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n}\n\n.hiwork-knowledge-hit-title {\n flex: 0 1 auto;\n min-width: 0;\n color: var(--dsw-alias-label-primary, #0f1115);\n font-size: 13px;\n font-weight: 600;\n line-height: 20px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.hiwork-knowledge-hit-source {\n flex: 1;\n min-width: 0;\n color: var(--dsw-alias-label-caption, #adb2b8);\n font-size: 11px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* \u7247\u6BB5\u6B63\u6587**\u4E0D\u622A\u65AD**\uFF1A\u7528\u6237\u70B9\u5F00\u68C0\u7D22\u5C31\u662F\u4E3A\u4E86\u8BFB\u8FD9\u6BB5\u539F\u6587\uFF0CUI \u518D\u88C1\u4E00\u5200\u7B49\u4E8E\u85CF\u4FE1\u606F\u3002\n \u957F\u5EA6\u5DF2\u7531 Host \u6309 `maxChunkChars` \u63A7\u5236\uFF0C\u8D85\u9650\u65F6\u6B63\u6587\u91CC\u4F1A\u5E26\u300C\u5DF2\u622A\u65AD\u300D\u6807\u8BB0\u3002 */\n.hiwork-knowledge-hit-body {\n margin: 0;\n color: var(--dsw-alias-label-secondary, #61666b);\n font-size: 12px;\n line-height: 20px;\n white-space: pre-wrap;\n word-break: break-word;\n overflow-wrap: anywhere;\n}\n\n/* ---------- \u7A7A\u6001 / \u52A0\u8F7D\u6001 ---------- */\n\n.hiwork-knowledge-empty {\n display: flex;\n flex-direction: column;\n align-items: center;\n gap: 8px;\n padding: 22px 16px;\n border: 1px dashed var(--dsw-alias-border-l2, rgba(15, 17, 21, 0.14));\n border-radius: 10px;\n color: var(--dsw-alias-label-tertiary, #81858c);\n font-size: 12px;\n line-height: 18px;\n text-align: center;\n}\n\n.hiwork-knowledge-empty-icon {\n display: flex;\n color: var(--dsw-alias-label-caption, #adb2b8);\n}\n\n.hiwork-knowledge-status {\n display: flex;\n align-items: center;\n justify-content: center;\n min-height: 120px;\n padding: 20px;\n color: var(--dsw-alias-label-tertiary, #81858c);\n font-size: 12px;\n text-align: center;\n}\n\n/* \u52A0\u8F7D\u6001\u662F\u300C\u8FD9\u4E00\u5757\u6682\u65F6\u6CA1\u6709\u5185\u5BB9\u300D\uFF0C\u90A3\u5C31\u5360\u6EE1\u6574\u5757\u5E76\u5C45\u4E2D\uFF1B\u5426\u5219\u5B83\u4F1A\u9876\u7740\u4E0A\u6CBF\u6446\u4E00\u5C0F\u6761\uFF0C\n \u4E0B\u9762\u7A7A\u4E00\u5927\u7247\uFF0C\u770B\u7740\u50CF\u6CA1\u52A0\u8F7D\u5B8C\u3002 */\n[data-hiwork-feature-root] .hiwork-knowledge-scroll > .hiwork-knowledge-status:only-child {\n flex: 1;\n}\n\n/* ---------- \u8BBE\u7F6E\u9875\u5206\u533A\u590D\u7528 ---------- */\n\n.hiwork-knowledge-muted {\n margin: 0;\n color: var(--dsw-alias-label-caption, #adb2b8);\n font-size: 11px;\n overflow-wrap: anywhere;\n}\n\n/* \u8868\u5355\u7528\u81EA\u9002\u5E94\u6805\u683C\uFF1A\u5BBD\u5904\u4E24\u5217\u3001\u7A84\u5904\u4E00\u5217\uFF0C\u4E0D\u9700\u8981\u5A92\u4F53\u67E5\u8BE2\uFF08\u8BBE\u7F6E\u5F39\u7A97\u5BBD\u5EA6\u4E0D\u56FA\u5B9A\uFF09\u3002 */\n.hiwork-knowledge-form {\n display: grid;\n grid-template-columns: repeat(auto-fit, minmax(240px, 1fr));\n /* \u884C\u8DDD 14 / \u5217\u8DDD 16\uFF1A\u5217\u8DDD\u6BD4\u884C\u8DDD\u5927\u4E00\u70B9\uFF0C\u4E24\u5217\u8F93\u5165\u6846\u624D\u4E0D\u50CF\u6328\u5728\u4E00\u8D77\n \uFF08\u5B9E\u6D4B 12px \u65F6\u534A\u884C\u7684\u4E24\u4E2A\u8F93\u5165\u6846\u51E0\u4E4E\u8D34\u4F4F\uFF0C\u6574\u5F20\u8868\u770B\u7740\u62E5\u6324\uFF09\u3002 */\n gap: 14px 16px;\n}\n\n.hiwork-knowledge-field {\n display: flex;\n flex-direction: column;\n gap: 4px;\n min-width: 0;\n}\n\n/* \u957F\u5B57\u6BB5\u8DE8\u6EE1\u6574\u884C\uFF1A\u540E\u7AEF\u5730\u5740\u8FD9\u7C7B\u503C\u6BD4\u4E00\u5217\u8FD8\u5BBD\uFF0C\u6324\u5728\u534A\u884C\u683C\u91CC\u53EA\u80FD\u88AB\u8F93\u5165\u6846\u622A\u65AD\u3002\n \u6805\u683C\u91CC\u7684\u6BCF\u4E2A\u76F4\u63A5\u5B50\u5143\u7D20\u90FD\u662F\u4E00\u4E2A\u683C\u5B50\uFF0C\u6240\u4EE5\u300C\u8DE8\u5217\u300D\u5FC5\u987B\u5199\u5728\u5B57\u6BB5\u672C\u8EAB\u2014\u2014\n \u63D2\u4E00\u4E2A\u72EC\u7ACB\u7684\u63D0\u793A <p> \u8FDB\u53BB\u4F1A\u88AB\u5F53\u6210\u4E00\u4E2A\u666E\u901A\u683C\u5B50\uFF0C\u628A\u6574\u884C\u987A\u4F4D\u6324\u6B6A\u3002 */\n.hiwork-knowledge-field.is-wide {\n grid-column: 1 / -1;\n}\n\n.hiwork-knowledge-field-label {\n color: var(--dsw-alias-label-secondary, #61666b);\n font-size: 12px;\n font-weight: 500;\n line-height: 18px;\n}\n\n.hiwork-knowledge-field-hint {\n color: var(--dsw-alias-label-caption, #adb2b8);\n font-size: 11px;\n line-height: 16px;\n overflow-wrap: anywhere;\n}\n\n.hiwork-knowledge-actions {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: none;\n}\n\n.hiwork-knowledge-hits {\n display: flex;\n flex-direction: column;\n gap: 8px;\n}\n\n/* ==========================================================================\n * \u804A\u5929\u91CC\u7684\u5DE5\u5177\u5361\u7247\uFF08`tool.call.toolview`\uFF0C\u6309\u5DE5\u5177\u540D keyed\uFF09\n *\n * \u8FD9\u5F20\u5361\u7247**\u6D3B\u5728\u5BF9\u8BDD\u6D41\u91CC**\uFF0C\u6240\u4EE5\u5B83\u5FC5\u987B\u6BD4\u4E2D\u592E\u9875\u514B\u5236\uFF1A\u4E00\u884C\u6458\u8981 + \u53EF\u5C55\u5F00\u7684\u8BC1\u636E\u3002\n * \u989C\u8272\u89C4\u77E9\u4E0E\u9875\u9762\u4E00\u81F4\u2014\u2014\u8BED\u4E49\u8272\u53EA\u7ED9\u5F02\u5E38\uFF08\u5931\u8D25/\u622A\u65AD\uFF09\uFF0C\u6B63\u5E38\u6001\u662F\u5B89\u9759\u7684\u4E2D\u6027\u7070\uFF1B\n * \u6DE1\u5E95\u4E00\u5F8B `color-mix(\u4E3B\u8272 10%, transparent)`\uFF08\u7406\u7531\u89C1\u6587\u4EF6\u5934\u7B2C 1 \u6761\uFF09\u3002\n * ========================================================================== */\n\n.hiwork-knowledge-tool {\n display: flex;\n flex-direction: column;\n border: 1px solid var(--dsw-alias-border-l2, rgba(15, 17, 21, 0.1));\n border-radius: 10px;\n background: var(--dsw-alias-bg-layer-1, #ffffff);\n overflow: hidden;\n}\n\n.hiwork-knowledge-tool-row {\n display: flex;\n align-items: center;\n gap: 8px;\n min-width: 0;\n padding: 8px 10px;\n color: var(--dsw-alias-label-primary, #0f1115);\n font-size: 12px;\n line-height: 18px;\n}\n\n/* \u53EF\u5C55\u5F00\u65F6\u6574\u884C\u662F\u6309\u94AE\uFF08\u952E\u76D8\u53EF\u8FBE\uFF09\uFF0Chover/focus \u5FC5\u987B\u770B\u5F97\u51FA\u6765\u3002 */\n.hiwork-knowledge-tool-row[role='button'] {\n cursor: pointer;\n}\n\n.hiwork-knowledge-tool-row[role='button']:hover {\n background: var(--dsw-alias-interactive-bg-hover, rgba(15, 17, 21, 0.06));\n}\n\n.hiwork-knowledge-tool-row[role='button']:focus-visible {\n outline: 2px solid var(--dsw-alias-state-business-primary, #4176e6);\n outline-offset: -2px;\n}\n\n/* \u6267\u884C\u4E2D = \u84DD\u8272\uFF08\u552F\u4E00\u300C\u8FD8\u5728\u8DD1\u300D\u7684\u4FE1\u53F7\uFF0C\u7528\u6237\u636E\u6B64\u51B3\u5B9A\u8981\u4E0D\u8981\u7B49\uFF09\u3002 */\n.hiwork-knowledge-tool[data-state='running'] .hiwork-knowledge-tool-row {\n background: color-mix(in srgb, var(--dsw-alias-state-business-primary, #4176e6) 5%, transparent);\n}\n\n.hiwork-knowledge-tool-mark {\n display: flex;\n align-items: center;\n flex: none;\n color: var(--dsw-alias-label-tertiary, #81858c);\n}\n\n.hiwork-knowledge-tool-mark.is-ok {\n color: var(--dsw-alias-label-caption, #adb2b8);\n}\n\n.hiwork-knowledge-tool-mark.is-error {\n color: var(--dsw-alias-state-error-primary, #ec1313);\n}\n\n.hiwork-knowledge-tool-mark.is-running {\n color: var(--dsw-alias-state-business-primary, #4176e6);\n}\n\n.hiwork-knowledge-tool-title {\n flex: none;\n color: var(--dsw-alias-label-secondary, #61666b);\n font-weight: 600;\n white-space: nowrap;\n}\n\n/* \u68C0\u7D22\u8BCD/\u95EE\u9898\uFF1A\u4E00\u884C\u622A\u65AD\uFF08\u5B8C\u6574\u503C\u7ED9 title \u63D0\u793A\uFF09\u3002 */\n.hiwork-knowledge-tool-subject {\n flex: 0 1 auto;\n min-width: 0;\n color: var(--dsw-alias-label-primary, #0f1115);\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.hiwork-knowledge-tool-summary {\n flex: none;\n margin-left: auto;\n color: var(--dsw-alias-label-caption, #adb2b8);\n font-size: 11px;\n white-space: nowrap;\n}\n\n/* \u7ED3\u679C\u533A\u4E0E\u6458\u8981\u884C\u4E4B\u95F4\u6709\u4E00\u6761\u5206\u9694\uFF08\u6298\u53E0\u65F6\u5B83\u4E0D\u53EF\u89C1\uFF0C\u56E0\u4E3A body \u4E3A\u7A7A\u65F6\u6CA1\u6709\u9AD8\u5EA6\uFF09\u3002 */\n.hiwork-knowledge-tool-body {\n display: flex;\n flex-direction: column;\n gap: 8px;\n padding: 0 10px;\n}\n\n.hiwork-knowledge-tool-body:not(:empty) {\n padding-bottom: 10px;\n border-top: 1px solid var(--dsw-alias-border-l1, rgba(15, 17, 21, 0.04));\n padding-top: 8px;\n}\n\n.hiwork-knowledge-tool-answer {\n margin: 0;\n color: var(--dsw-alias-label-primary, #0f1115);\n font-size: 12px;\n line-height: 20px;\n white-space: pre-wrap;\n word-break: break-word;\n overflow-wrap: anywhere;\n}\n\n.hiwork-knowledge-tool-list {\n display: flex;\n flex-direction: column;\n gap: 8px;\n margin: 0;\n padding: 0;\n list-style: none;\n}\n\n.hiwork-knowledge-tool-hit {\n display: flex;\n flex-direction: column;\n gap: 4px;\n min-width: 0;\n padding: 8px 10px;\n border-radius: 8px;\n background: var(--dsw-alias-bg-module-platform, #f5f6f7);\n}\n\n.hiwork-knowledge-tool-hit-head {\n display: flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n}\n\n.hiwork-knowledge-tool-hit-title {\n flex: 0 1 auto;\n min-width: 0;\n color: var(--dsw-alias-label-primary, #0f1115);\n font-size: 12px;\n font-weight: 600;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n.hiwork-knowledge-tool-hit-seg {\n flex: none;\n color: var(--dsw-alias-label-caption, #adb2b8);\n font-size: 11px;\n white-space: nowrap;\n}\n\n/* \u52A8\u4F5C\u6309\u94AE\u8D34\u53F3\uFF0C\u4E0D\u4E0E\u6587\u6863\u540D\u62A2\u7A7A\u95F4\u3002 */\n.hiwork-knowledge-tool-hit-actions {\n display: flex;\n align-items: center;\n gap: 4px;\n flex: none;\n margin-left: auto;\n}\n\n.hiwork-knowledge-tool-hit-body {\n margin: 0;\n color: var(--dsw-alias-label-secondary, #61666b);\n font-size: 12px;\n line-height: 19px;\n /* \u7247\u6BB5\u4E0E\u4E2D\u592E\u9875\u540C\u53E3\u5F84\uFF1A\u7ED9\u9700\u8981\u7CBE\u8BFB\u7684\u4EBA\u6362\u884C\uFF0C\u4F46\u4E0D\u88C1\u5185\u5BB9\uFF08\u622A\u65AD\u7531 Host \u63A7\u5236\u5E76\u6807\u8BB0\uFF09\u3002 */\n white-space: pre-wrap;\n word-break: break-word;\n overflow-wrap: anywhere;\n}\n\n.hiwork-knowledge-tool-base {\n display: flex;\n align-items: baseline;\n gap: 6px;\n min-width: 0;\n padding: 6px 10px;\n border-radius: 8px;\n background: var(--dsw-alias-bg-module-platform, #f5f6f7);\n}\n\n.hiwork-knowledge-tool-base-desc {\n flex: 1;\n min-width: 0;\n color: var(--dsw-alias-label-tertiary, #81858c);\n font-size: 11px;\n overflow: hidden;\n text-overflow: ellipsis;\n white-space: nowrap;\n}\n\n/* \u5361\u7247\u5185\u7684\u5C0F\u52A8\u4F5C\uFF08\u8FFD\u95EE / \u6253\u5F00 / \u8F68\u8FF9\uFF09\u3002\u6BD4\u9875\u9762\u6309\u94AE\u518D\u5C0F\u4E00\u6863\uFF1A\u5B83\u9576\u5728\u7247\u6BB5\u884C\u91CC\u3002 */\n.hiwork-knowledge-tool-action {\n display: inline-flex;\n align-items: center;\n gap: 4px;\n padding: 2px 7px;\n border: 1px solid var(--dsw-alias-border-l2, rgba(15, 17, 21, 0.12));\n border-radius: 6px;\n background: transparent;\n color: var(--dsw-alias-label-secondary, #61666b);\n font-family: inherit;\n font-size: 11px;\n line-height: 16px;\n cursor: pointer;\n}\n\n.hiwork-knowledge-tool-action:hover {\n background: var(--dsw-alias-interactive-bg-hover, rgba(15, 17, 21, 0.06));\n color: var(--dsw-alias-label-primary, #0f1115);\n}\n\n.hiwork-knowledge-tool-action:focus-visible {\n outline: 2px solid var(--dsw-alias-state-business-primary, #4176e6);\n outline-offset: 1px;\n}\n\n.hiwork-knowledge-tool-action.is-inspect {\n align-self: flex-start;\n}\n\n.hiwork-knowledge-tool-more {\n align-self: flex-start;\n padding: 2px 0;\n border: none;\n background: transparent;\n color: var(--dsw-alias-state-business-primary, #4176e6);\n font-family: inherit;\n font-size: 11px;\n cursor: pointer;\n}\n\n.hiwork-knowledge-tool-more:hover {\n text-decoration: underline;\n}\n\n/* 0 \u6761\u547D\u4E2D\u65F6\u5DE5\u5177\u7ED9\u51FA\u7684\u53EF\u6267\u884C\u63D0\u793A\uFF1A\u5B83\u662F\u300C\u67E5\u4E0D\u5230\u300D\u7684\u6B63\u89E3\uFF0C\u914D\u5F97\u4E0A\u4E00\u4E2A\u9192\u76EE\u7684\u5E95\u3002 */\n.hiwork-knowledge-tool-hint {\n margin: 0;\n padding: 6px 8px;\n border-radius: 8px;\n background: color-mix(in srgb, var(--dsw-alias-state-warn-primary, #f59e0b) 10%, transparent);\n color: var(--dsw-alias-state-warn-label, var(--dsw-alias-state-warn-primary, #dd8629));\n font-size: 11px;\n line-height: 17px;\n}\n\n.hiwork-knowledge-tool-error {\n display: flex;\n align-items: flex-start;\n gap: 6px;\n margin: 0;\n color: var(--dsw-alias-state-error-primary, #ec1313);\n font-size: 11px;\n line-height: 17px;\n overflow-wrap: anywhere;\n}\n\n.hiwork-knowledge-tool-error-icon {\n display: flex;\n flex: none;\n padding-top: 1px;\n}\n\n/* ==========================================================================\n * \u6587\u6863\u6B63\u6587\uFF08\u4E2D\u592E\u9875\u7684\u8BE6\u60C5\u89C6\u56FE\uFF09\n * ========================================================================== */\n\n.hiwork-knowledge-doc-back {\n flex: none;\n align-self: flex-start;\n}\n\n.hiwork-knowledge-chunk {\n display: flex;\n flex-direction: column;\n gap: 6px;\n padding: 10px 12px;\n border: 1px solid var(--dsw-alias-border-l2, rgba(15, 17, 21, 0.1));\n border-radius: 10px;\n background: var(--dsw-alias-bg-layer-1, #ffffff);\n}\n\n.hiwork-knowledge-chunk-head {\n display: flex;\n align-items: center;\n gap: 6px;\n min-width: 0;\n}\n\n.hiwork-knowledge-chunk-index {\n flex: none;\n color: var(--dsw-alias-label-caption, #adb2b8);\n font-size: 11px;\n}\n\n.hiwork-knowledge-chunk-body {\n margin: 0;\n color: var(--dsw-alias-label-secondary, #61666b);\n font-size: 12px;\n line-height: 20px;\n white-space: pre-wrap;\n word-break: break-word;\n overflow-wrap: anywhere;\n}\n\n.hiwork-knowledge-pager {\n display: flex;\n align-items: center;\n gap: 8px;\n flex: none;\n}\n\n.hiwork-knowledge-pager-info {\n color: var(--dsw-alias-label-caption, #adb2b8);\n font-size: 11px;\n white-space: nowrap;\n}\n\n.hiwork-knowledge-sent {\n color: var(--dsw-alias-state-success-primary, #22c55e);\n font-size: 11px;\n white-space: nowrap;\n}\n\n/* \u300C\u6CA1\u80FD\u653E\u8FDB\u8F93\u5165\u6846\u300D\u63D0\u793A\uFF1A\u4E0E\u300C\u5DF2\u653E\u8FDB\u300D\u540C\u4E00\u4F4D\u7F6E\uFF0C\u4F46\u7528 error \u8BED\u4E49\u8272 + \u8BF4\u660E\u5177\u4F53\u539F\u56E0\n \uFF08\u6CA1\u6709\u6253\u5F00\u7684\u4F1A\u8BDD / \u8F93\u5165\u6846\u6B63\u5FD9\uFF09\u3002\u7528 role=\"status\" \u64AD\u62A5\uFF0C\u4E0D\u906E\u6321\u5DE5\u5177\u680F\u3002 */\n.hiwork-knowledge-send-failed {\n align-self: center;\n max-width: 320px;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-state-error-primary, #d84a3f);\n}\n\n/* \u884C\u5185\u5931\u8D25\u63D0\u793A\uFF08\u300C\u8FFD\u95EE\u300D\u6CA1\u80FD\u9001\u8FDB\u4F1A\u8BDD\u65F6\uFF09\u3002\n \u7528 error \u8BED\u4E49\u8272 + \u660E\u786E\u7684\u5DE6\u5BF9\u9F50\u77ED\u53E5\uFF0C\u4E0D\u505A\u6210 toast\uFF1A\u5B83\u662F\u8FD9\u4E00\u884C\u7684\u7ED3\u679C\uFF0C\u4E0D\u662F\u5168\u5C40\u544A\u8B66\u3002 */\n.hiwork-knowledge-tool-failure {\n margin: 4px 0 0;\n font-size: 12px;\n line-height: 18px;\n color: var(--dsw-alias-state-error-primary, #d84a3f);\n word-break: break-word;\n}";
|
|
78
1538
|
|
|
79
1539
|
// src/client/styles.ts
|
|
80
1540
|
var KNOWLEDGE_STYLE_ID = "hiwork-knowledge-styles";
|
|
@@ -95,13 +1555,74 @@ function installStyles() {
|
|
|
95
1555
|
};
|
|
96
1556
|
}
|
|
97
1557
|
|
|
1558
|
+
// src/client/composer.ts
|
|
1559
|
+
var WRITABLE_PHASES = /* @__PURE__ */ new Set(["plain", "claimed"]);
|
|
1560
|
+
function detectTextLength(state) {
|
|
1561
|
+
const occurrences = state.occurrences;
|
|
1562
|
+
if (occurrences === void 0) return state.draft.length;
|
|
1563
|
+
let folded = 0;
|
|
1564
|
+
for (const occurrence of occurrences) {
|
|
1565
|
+
if (occurrence.length > 1) folded += occurrence.length - 1;
|
|
1566
|
+
}
|
|
1567
|
+
return Math.max(0, state.draft.length - folded);
|
|
1568
|
+
}
|
|
1569
|
+
function insertDraftText(sessions, text, sessionId) {
|
|
1570
|
+
if (sessions === void 0) return { ok: false, reason: "no-target" };
|
|
1571
|
+
let target;
|
|
1572
|
+
try {
|
|
1573
|
+
target = sessionId ?? sessions.list?.getSnapshot().current;
|
|
1574
|
+
} catch {
|
|
1575
|
+
return { ok: false, reason: "no-target" };
|
|
1576
|
+
}
|
|
1577
|
+
if (target === void 0) return { ok: false, reason: "no-target" };
|
|
1578
|
+
let actx;
|
|
1579
|
+
try {
|
|
1580
|
+
actx = sessions.scope?.(target) ?? sessions.binding?.(target)?.ctx;
|
|
1581
|
+
} catch {
|
|
1582
|
+
return { ok: false, reason: "no-target" };
|
|
1583
|
+
}
|
|
1584
|
+
if (actx === void 0 || actx === null) return { ok: false, reason: "no-target" };
|
|
1585
|
+
let surface;
|
|
1586
|
+
try {
|
|
1587
|
+
const conversation = actx.get?.("conversation");
|
|
1588
|
+
surface = conversation?.input.for(actx);
|
|
1589
|
+
} catch {
|
|
1590
|
+
return { ok: false, reason: "no-target" };
|
|
1591
|
+
}
|
|
1592
|
+
if (surface === void 0) return { ok: false, reason: "no-target" };
|
|
1593
|
+
if (typeof surface.insertText !== "function") return { ok: false, reason: "no-target" };
|
|
1594
|
+
let snapshot;
|
|
1595
|
+
try {
|
|
1596
|
+
snapshot = surface.state.getSnapshot();
|
|
1597
|
+
} catch {
|
|
1598
|
+
return { ok: false, reason: "no-target" };
|
|
1599
|
+
}
|
|
1600
|
+
if (snapshot.phase !== void 0 && !WRITABLE_PHASES.has(snapshot.phase)) return { ok: false, reason: "busy" };
|
|
1601
|
+
const end = detectTextLength(snapshot);
|
|
1602
|
+
try {
|
|
1603
|
+
const inserted = surface.insertText(text, { start: end, end, draftRev: snapshot.draftRev });
|
|
1604
|
+
return inserted ? { ok: true } : { ok: false, reason: "rejected" };
|
|
1605
|
+
} catch {
|
|
1606
|
+
return { ok: false, reason: "rejected" };
|
|
1607
|
+
}
|
|
1608
|
+
}
|
|
1609
|
+
|
|
1610
|
+
// src/tool-names.ts
|
|
1611
|
+
var KNOWLEDGE_TOOL_NAMES = [
|
|
1612
|
+
"knowledge_list_bases",
|
|
1613
|
+
"knowledge_search",
|
|
1614
|
+
"knowledge_read_document",
|
|
1615
|
+
"knowledge_ask"
|
|
1616
|
+
];
|
|
1617
|
+
|
|
98
1618
|
// src/client/index.ts
|
|
99
1619
|
var name = "hiwork-knowledge-client";
|
|
100
|
-
var inject = ["slots", "locale"];
|
|
1620
|
+
var inject = ["slots", "locale", "connection"];
|
|
101
1621
|
var FEATURE_CENTER_SERVICE = "hiworkFeatureCenter";
|
|
102
1622
|
var FEATURE_ID = "knowledge";
|
|
103
1623
|
var FEATURE_ORDER = 30;
|
|
104
1624
|
var SETTINGS_SECTION_ID = "knowledge";
|
|
1625
|
+
var SETTINGS_SECTION_ORDER = 20;
|
|
105
1626
|
var FEATURE_ICON = '<svg width="16" height="16" viewBox="0 0 16 16" fill="none" xmlns="http://www.w3.org/2000/svg" aria-hidden="true"><path d="M3.2 3.1c1.5-.5 3.2-.3 4.8.8 1.6-1.1 3.3-1.3 4.8-.8v8.6c-1.5-.5-3.2-.3-4.8.8-1.6-1.1-3.3-1.3-4.8-.8V3.1Z" stroke="currentColor" stroke-width="1.4" stroke-linejoin="round"/><path d="M8 3.9v8.6" stroke="currentColor" stroke-width="1.4" stroke-linecap="round"/></svg>';
|
|
106
1627
|
function coreFace(ctx) {
|
|
107
1628
|
const value = ctx.get?.(FEATURE_CENTER_SERVICE);
|
|
@@ -112,24 +1633,23 @@ function apply(ctx) {
|
|
|
112
1633
|
ctx.effect(() => ctx.locale.register(NS, { zh, en }), "hiwork-knowledge: locale");
|
|
113
1634
|
const t = ctx.locale.bind(NS);
|
|
114
1635
|
ctx.effect(() => installStyles(), "hiwork-knowledge: styles");
|
|
1636
|
+
const runtime = createKnowledgeRuntime(ctx.connection.rpc);
|
|
1637
|
+
const insertToComposer = (text) => {
|
|
1638
|
+
const sessions = ctx.get?.("sessions");
|
|
1639
|
+
return insertDraftText(sessions, text);
|
|
1640
|
+
};
|
|
115
1641
|
let coreSeen = false;
|
|
116
1642
|
let featureDispose;
|
|
117
|
-
let settingsDispose;
|
|
118
|
-
const disposeFallback = () => {
|
|
119
|
-
settingsDispose?.();
|
|
120
|
-
settingsDispose = void 0;
|
|
121
|
-
};
|
|
122
1643
|
const registerFeature = (scope, face) => {
|
|
123
1644
|
if (coreSeen) return;
|
|
124
1645
|
coreSeen = true;
|
|
125
|
-
disposeFallback();
|
|
126
1646
|
scope.effect(() => {
|
|
127
1647
|
const dispose = face.featureRegistry.register({
|
|
128
1648
|
id: FEATURE_ID,
|
|
129
1649
|
label: () => t("view.title"),
|
|
130
1650
|
icon: FEATURE_ICON,
|
|
131
1651
|
order: FEATURE_ORDER,
|
|
132
|
-
render: () => (0,
|
|
1652
|
+
render: () => (0, import_react5.createElement)(KnowledgeView, { t, runtime, putInComposer: insertToComposer })
|
|
133
1653
|
});
|
|
134
1654
|
featureDispose = dispose;
|
|
135
1655
|
return () => {
|
|
@@ -138,38 +1658,72 @@ function apply(ctx) {
|
|
|
138
1658
|
};
|
|
139
1659
|
}, "hiwork-knowledge: feature center");
|
|
140
1660
|
};
|
|
141
|
-
const
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
1661
|
+
const settingsOptions = {
|
|
1662
|
+
name: "settings.section",
|
|
1663
|
+
id: SETTINGS_SECTION_ID,
|
|
1664
|
+
order: SETTINGS_SECTION_ORDER,
|
|
1665
|
+
label: () => t("view.title"),
|
|
1666
|
+
inject: () => ({ t, runtime })
|
|
1667
|
+
};
|
|
1668
|
+
ctx.slots.inject("settings.section", () => {
|
|
1669
|
+
const dispose = ctx.slots.register(
|
|
1670
|
+
settingsOptions,
|
|
1671
|
+
(props) => (0, import_react5.createElement)(KnowledgeSettings, {
|
|
1672
|
+
t: props.t ?? t,
|
|
1673
|
+
runtime: props.runtime ?? runtime,
|
|
1674
|
+
...props.close === void 0 ? {} : { close: props.close },
|
|
1675
|
+
...props.closeSettings === void 0 ? {} : { closeSettings: props.closeSettings }
|
|
1676
|
+
})
|
|
1677
|
+
);
|
|
1678
|
+
return () => {
|
|
1679
|
+
dispose();
|
|
149
1680
|
};
|
|
150
|
-
|
|
151
|
-
|
|
1681
|
+
});
|
|
1682
|
+
const toolviewOptions = (key) => ({
|
|
1683
|
+
name: "tool.call.toolview",
|
|
1684
|
+
key,
|
|
1685
|
+
locale: NS,
|
|
1686
|
+
inject: ((sessionId) => {
|
|
1687
|
+
const sessions = ctx.get?.("sessions");
|
|
1688
|
+
const id = sessionId;
|
|
1689
|
+
const followUpFace = sessions === void 0 ? void 0 : (text) => insertDraftText(sessions, text, id);
|
|
1690
|
+
return {
|
|
1691
|
+
...followUpFace === void 0 ? {} : { followUp: followUpFace },
|
|
1692
|
+
openDocument: (knowledgeId) => {
|
|
1693
|
+
requestDocumentFocus(knowledgeId);
|
|
1694
|
+
coreFace(ctx)?.openFeature(FEATURE_ID);
|
|
1695
|
+
}
|
|
152
1696
|
};
|
|
1697
|
+
})
|
|
1698
|
+
});
|
|
1699
|
+
for (const toolName of KNOWLEDGE_TOOL_NAMES) {
|
|
1700
|
+
ctx.slots.inject("tool.call.toolview", () => {
|
|
153
1701
|
const dispose = ctx.slots.register(
|
|
154
|
-
|
|
155
|
-
(props) => (0,
|
|
1702
|
+
toolviewOptions(toolName),
|
|
1703
|
+
(props) => (0, import_react5.createElement)(KnowledgeToolRow, {
|
|
156
1704
|
t: props.t ?? t,
|
|
157
|
-
|
|
1705
|
+
block: props.block,
|
|
1706
|
+
toolName: props.toolName ?? toolName,
|
|
1707
|
+
...props.inspect === void 0 ? {} : { inspect: props.inspect },
|
|
1708
|
+
...props.followUp === void 0 ? {} : { followUp: props.followUp },
|
|
1709
|
+
...props.openDocument === void 0 ? {} : { openDocument: props.openDocument }
|
|
158
1710
|
})
|
|
159
1711
|
);
|
|
160
|
-
settingsDispose = dispose;
|
|
161
1712
|
return () => {
|
|
162
|
-
settingsDispose = void 0;
|
|
163
1713
|
dispose();
|
|
164
1714
|
};
|
|
165
1715
|
});
|
|
166
|
-
}
|
|
1716
|
+
}
|
|
167
1717
|
const installed = coreFace(ctx);
|
|
168
1718
|
if (installed !== void 0) registerFeature(ctx, installed);
|
|
169
|
-
else installFallback();
|
|
170
1719
|
ctx.inject?.([FEATURE_CENTER_SERVICE], (scope) => {
|
|
171
1720
|
const face = coreFace(scope);
|
|
172
1721
|
if (face !== void 0) registerFeature(scope, face);
|
|
173
1722
|
});
|
|
174
1723
|
}
|
|
1724
|
+
var KNOWLEDGE_CLIENT_REGISTRATION = {
|
|
1725
|
+
featureId: FEATURE_ID,
|
|
1726
|
+
featureOrder: FEATURE_ORDER,
|
|
1727
|
+
settingsSectionId: SETTINGS_SECTION_ID
|
|
1728
|
+
};
|
|
175
1729
|
return module.exports; } });
|