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/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 import_react2 = require("react");
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
- function KnowledgeView(props) {
34
- const { t, closeSettings } = props;
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, import_react.createElement)(
302
+ (0, import_react2.createElement)(
39
303
  "header",
40
304
  { className: "hiwork-knowledge-header" },
41
- (0, import_react.createElement)(
305
+ (0, import_react2.createElement)(
42
306
  "div",
43
307
  { className: "hiwork-knowledge-heading" },
44
- (0, import_react.createElement)("h1", { className: "hiwork-knowledge-title" }, t("view.title")),
45
- (0, import_react.createElement)("p", { className: "hiwork-knowledge-subtitle" }, t("view.subtitle"))
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
- closeSettings === void 0 ? null : (0, import_react.createElement)(
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: closeSettings },
50
- t("view.close")
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, import_react.createElement)(
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-placeholder", "data-hiwork-knowledge-placeholder": "" },
56
- t("view.placeholder")
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": "\u6D77\u666E\u77E5\u8BC6\u5E93\u5BF9\u63A5\u5165\u53E3",
66
- "view.placeholder": "\u6B64\u5904\u5BF9\u63A5\u6D77\u666E\u77E5\u8BC6\u5E93\u76F8\u5173\u5185\u5BB9",
67
- "view.close": "\u5173\u95ED\u8BBE\u7F6E"
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": "HiWork knowledge base integration",
72
- "view.placeholder": "HiWork knowledge base content will be integrated here.",
73
- "view.close": "Close settings"
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, import_react2.createElement)(KnowledgeView, { t })
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 installFallback = () => {
142
- if (coreSeen) return;
143
- const settingsOptions = {
144
- name: "settings.section",
145
- id: SETTINGS_SECTION_ID,
146
- order: 20,
147
- label: () => t("view.title"),
148
- inject: () => ({ t })
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
- ctx.slots.inject("settings.section", () => {
151
- if (coreSeen) return () => {
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
- settingsOptions,
155
- (props) => (0, import_react2.createElement)(KnowledgeView, {
1702
+ toolviewOptions(toolName),
1703
+ (props) => (0, import_react5.createElement)(KnowledgeToolRow, {
156
1704
  t: props.t ?? t,
157
- ...props.closeSettings === void 0 ? {} : { closeSettings: props.closeSettings }
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; } });