vue-agent-start 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (169) hide show
  1. package/package.json +30 -0
  2. package/pnpm-workspace.yaml +3 -0
  3. package/src/agent-flow/adapter/backend.ts +99 -0
  4. package/src/agent-flow/components/ChatIframePanel.vue +773 -0
  5. package/src/agent-flow/components/DatasetItemCard.vue +313 -0
  6. package/src/agent-flow/components/MemoryWindow.vue +104 -0
  7. package/src/agent-flow/components/PromptEditor.vue +804 -0
  8. package/src/agent-flow/components/PromptEditorTagPanel.vue +460 -0
  9. package/src/agent-flow/components/SvgIcon.vue +32 -0
  10. package/src/agent-flow/components/ToolItemCard.vue +169 -0
  11. package/src/agent-flow/components/VariableCard.vue +161 -0
  12. package/src/agent-flow/components/VariableSelector.vue +162 -0
  13. package/src/agent-flow/components/chat-iframe-types.ts +35 -0
  14. package/src/agent-flow/components/stubs/DatasetChooser.vue +70 -0
  15. package/src/agent-flow/components/stubs/Embedding.vue +22 -0
  16. package/src/agent-flow/components/stubs/ModelSelect.vue +24 -0
  17. package/src/agent-flow/components/stubs/RestfulSelectCard.vue +24 -0
  18. package/src/agent-flow/components/stubs/ToolChooser.vue +96 -0
  19. package/src/agent-flow/components/stubs/TriggersItemCard.vue +126 -0
  20. package/src/agent-flow/components/stubs/VariableModal.vue +115 -0
  21. package/src/agent-flow/index.ts +73 -0
  22. package/src/agent-flow/stores/workflow.ts +72 -0
  23. package/src/agent-flow/utils/langUtils.ts +173 -0
  24. package/src/agent-flow/workflow/Ability.vue +65 -0
  25. package/src/agent-flow/workflow/AuthorizationItem.vue +101 -0
  26. package/src/agent-flow/workflow/ConversationVar.vue +42 -0
  27. package/src/agent-flow/workflow/CustomEdge.vue +94 -0
  28. package/src/agent-flow/workflow/EnvironmentVar.vue +40 -0
  29. package/src/agent-flow/workflow/FlowDesigner.vue +2802 -0
  30. package/src/agent-flow/workflow/Icon.vue +179 -0
  31. package/src/agent-flow/workflow/NodeConfig.vue +509 -0
  32. package/src/agent-flow/workflow/NodeConfigCard.vue +460 -0
  33. package/src/agent-flow/workflow/NodeHandle.vue +147 -0
  34. package/src/agent-flow/workflow/NodeHeaderToolbar.vue +77 -0
  35. package/src/agent-flow/workflow/NodeHoverToolbar.vue +176 -0
  36. package/src/agent-flow/workflow/OutputItemCard.vue +668 -0
  37. package/src/agent-flow/workflow/ParamTableItem.vue +200 -0
  38. package/src/agent-flow/workflow/StructTable.vue +202 -0
  39. package/src/agent-flow/workflow/VarInsertField.vue +517 -0
  40. package/src/agent-flow/workflow/VarSelectField.vue +223 -0
  41. package/src/agent-flow/workflow/VariableSelectorItem.vue +48 -0
  42. package/src/agent-flow/workflow/WfField.vue +206 -0
  43. package/src/agent-flow/workflow/_config-base.css +470 -0
  44. package/src/agent-flow/workflow/composables/useNode.js +55 -0
  45. package/src/agent-flow/workflow/index.vue +53 -0
  46. package/src/agent-flow/workflow/nodeCard/AgentNodeCard.vue +180 -0
  47. package/src/agent-flow/workflow/nodeCard/AnswerNodeCard.vue +65 -0
  48. package/src/agent-flow/workflow/nodeCard/ClassifierCard.vue +152 -0
  49. package/src/agent-flow/workflow/nodeCard/CodeNodeCard.vue +139 -0
  50. package/src/agent-flow/workflow/nodeCard/ConditionNodeCard.vue +323 -0
  51. package/src/agent-flow/workflow/nodeCard/DocumentExtractorCard.vue +83 -0
  52. package/src/agent-flow/workflow/nodeCard/EndNodeCard.vue +123 -0
  53. package/src/agent-flow/workflow/nodeCard/HttpNodeCard.vue +451 -0
  54. package/src/agent-flow/workflow/nodeCard/HumanInputCard.vue +152 -0
  55. package/src/agent-flow/workflow/nodeCard/IterationCard.vue +66 -0
  56. package/src/agent-flow/workflow/nodeCard/KnowledgeRetrievalCard.vue +48 -0
  57. package/src/agent-flow/workflow/nodeCard/LLMNodeCard.vue +206 -0
  58. package/src/agent-flow/workflow/nodeCard/ListOperatorCard.vue +188 -0
  59. package/src/agent-flow/workflow/nodeCard/ParameterExtractorCard.vue +352 -0
  60. package/src/agent-flow/workflow/nodeCard/ServiceApiNodeCard.vue +188 -0
  61. package/src/agent-flow/workflow/nodeCard/StartNodeCard.vue +216 -0
  62. package/src/agent-flow/workflow/nodeCard/VariableAssignerCard.vue +125 -0
  63. package/src/agent-flow/workflow/nodeCard/VariableNodeCard.vue +121 -0
  64. package/src/agent-flow/workflow/nodes/AgentNode.vue +122 -0
  65. package/src/agent-flow/workflow/nodes/AnswerNode.vue +99 -0
  66. package/src/agent-flow/workflow/nodes/ClassifierNode.vue +199 -0
  67. package/src/agent-flow/workflow/nodes/CodeNode.vue +152 -0
  68. package/src/agent-flow/workflow/nodes/ConditionNode.vue +232 -0
  69. package/src/agent-flow/workflow/nodes/DocumentExtractorNode.vue +96 -0
  70. package/src/agent-flow/workflow/nodes/EndNode.vue +119 -0
  71. package/src/agent-flow/workflow/nodes/FileUploadNode.vue +97 -0
  72. package/src/agent-flow/workflow/nodes/HttpNode.vue +204 -0
  73. package/src/agent-flow/workflow/nodes/HumanInputNode.vue +110 -0
  74. package/src/agent-flow/workflow/nodes/IterationNode.vue +98 -0
  75. package/src/agent-flow/workflow/nodes/KnowledgeRetrievalNode.vue +253 -0
  76. package/src/agent-flow/workflow/nodes/LLMNode.vue +134 -0
  77. package/src/agent-flow/workflow/nodes/ListOperatorNode.vue +111 -0
  78. package/src/agent-flow/workflow/nodes/LoopNode.vue +94 -0
  79. package/src/agent-flow/workflow/nodes/ParameterExtractorNode.vue +147 -0
  80. package/src/agent-flow/workflow/nodes/ServiceApiNode.vue +161 -0
  81. package/src/agent-flow/workflow/nodes/StartNode.vue +199 -0
  82. package/src/agent-flow/workflow/nodes/TemplateNode.vue +103 -0
  83. package/src/agent-flow/workflow/nodes/UserInputNode.vue +92 -0
  84. package/src/agent-flow/workflow/nodes/VariableAssignerNode.vue +145 -0
  85. package/src/agent-flow/workflow/nodes/VariableNode.vue +130 -0
  86. package/src/agent-flow/workflow/nodes/_node-base.css +338 -0
  87. package/src/agent-flow/workflow/utils/node_card_form.ts +335 -0
  88. package/src/agent-flow/workflow/utils/node_config.ts +63 -0
  89. package/src/agent-flow/workflow/utils/workflow_utils.ts +151 -0
  90. package/src/agent-studio/adapters/springAgentStart.ts +390 -0
  91. package/src/agent-studio/api/index.ts +1 -0
  92. package/src/agent-studio/api/types.ts +173 -0
  93. package/src/agent-studio/components/AgentApiDocs.vue +500 -0
  94. package/src/agent-studio/components/AgentAppsPage.vue +1601 -0
  95. package/src/agent-studio/components/AgentCardGrid.vue +259 -0
  96. package/src/agent-studio/components/AgentChatPage.vue +553 -0
  97. package/src/agent-studio/components/AgentDebugPanel.vue +350 -0
  98. package/src/agent-studio/components/AgentLogsPanel.vue +391 -0
  99. package/src/agent-studio/components/AgentMonitorPanel.vue +204 -0
  100. package/src/agent-studio/components/AgentOrchestrate.vue +505 -0
  101. package/src/agent-studio/components/AgentPromptEditor.vue +237 -0
  102. package/src/agent-studio/components/AgentStudioShell.vue +227 -0
  103. package/src/agent-studio/components/AgentToolsPanel.vue +394 -0
  104. package/src/agent-studio/components/AgentVariablesPanel.vue +205 -0
  105. package/src/agent-studio/components/ApiKeyManager.vue +251 -0
  106. package/src/agent-studio/components/AppDesignDrawer.vue +3391 -0
  107. package/src/agent-studio/components/CreateAppModal.vue +737 -0
  108. package/src/agent-studio/components/SparkChart.vue +200 -0
  109. package/src/agent-studio/components/VariableEditorModal.vue +499 -0
  110. package/src/agent-studio/composables/useAgentStudio.ts +347 -0
  111. package/src/agent-studio/index.ts +60 -0
  112. package/src/agent-studio/panels/DrawerFlowDesigner.vue +203 -0
  113. package/src/agent-studio/panels/LogAnnotationPanel.vue +490 -0
  114. package/src/agent-studio/panels/MonitorPanel.vue +535 -0
  115. package/src/agent-studio/types.ts +242 -0
  116. package/src/index.ts +155 -0
  117. package/src/knowledge-hub/adapters/springAgentStart.ts +472 -0
  118. package/src/knowledge-hub/components/AddDocumentsWizard.vue +1452 -0
  119. package/src/knowledge-hub/components/CreateDatasetWizard.vue +1723 -0
  120. package/src/knowledge-hub/components/DatasetCardGrid.vue +467 -0
  121. package/src/knowledge-hub/components/DatasetDetailDrawer.vue +888 -0
  122. package/src/knowledge-hub/components/DatasetPicker.vue +65 -0
  123. package/src/knowledge-hub/components/DatasetPickerModal.vue +526 -0
  124. package/src/knowledge-hub/components/DatasetSettingsPanel.vue +908 -0
  125. package/src/knowledge-hub/components/DatasetSidebar.vue +781 -0
  126. package/src/knowledge-hub/components/DocumentChunksView.vue +802 -0
  127. package/src/knowledge-hub/components/DocumentTable.vue +552 -0
  128. package/src/knowledge-hub/components/HitTestingPanel.vue +74 -0
  129. package/src/knowledge-hub/components/KnowledgeApp.vue +66 -0
  130. package/src/knowledge-hub/components/KnowledgeHubApp.vue +504 -0
  131. package/src/knowledge-hub/components/RecallTestingPanelV2.vue +515 -0
  132. package/src/knowledge-hub/components/RetrievalConfigPopover.vue +270 -0
  133. package/src/knowledge-hub/components/RetrievalMethodPicker.vue +547 -0
  134. package/src/knowledge-hub/components/RetrievedList.vue +24 -0
  135. package/src/knowledge-hub/components/internal/KhDialog.vue +195 -0
  136. package/src/knowledge-hub/composables/useKnowledge.ts +89 -0
  137. package/src/knowledge-hub/i18n/index.ts +2 -0
  138. package/src/knowledge-hub/i18n/messages.ts +422 -0
  139. package/src/knowledge-hub/i18n/useKhI18n.ts +107 -0
  140. package/src/knowledge-hub/index.ts +46 -0
  141. package/src/knowledge-hub/styles/index.css +4 -0
  142. package/src/knowledge-hub/styles/tokens.css +138 -0
  143. package/src/knowledge-hub/types/api.ts +213 -0
  144. package/src/knowledge-hub/types/dataset.ts +88 -0
  145. package/src/knowledge-hub/types/document.ts +45 -0
  146. package/src/knowledge-hub/types/index.ts +9 -0
  147. package/src/knowledge-hub/types/retrieval.ts +46 -0
  148. package/src/provider-hub/components/CredentialForm.vue +103 -0
  149. package/src/provider-hub/components/DefaultModelsPanel.vue +270 -0
  150. package/src/provider-hub/components/GroupedModelSelect.vue +445 -0
  151. package/src/provider-hub/components/ModelCardGrid.vue +332 -0
  152. package/src/provider-hub/components/ModelParameterDrawer.vue +739 -0
  153. package/src/provider-hub/components/ModelPickerPopover.vue +1282 -0
  154. package/src/provider-hub/components/ProviderApp.vue +159 -0
  155. package/src/provider-hub/components/ProviderCredentialModal.vue +321 -0
  156. package/src/provider-hub/components/ProviderGallery.vue +131 -0
  157. package/src/provider-hub/components/ProviderHubShell.vue +1992 -0
  158. package/src/provider-hub/components/ProviderIcon.vue +130 -0
  159. package/src/provider-hub/composables/useProviderHub.ts +358 -0
  160. package/src/provider-hub/index.ts +43 -0
  161. package/src/provider-hub/svg/MiniMax.svg +1 -0
  162. package/src/provider-hub/svg/Volcengine.svg +1 -0
  163. package/src/provider-hub/svg/Zhipu.svg +1 -0
  164. package/src/provider-hub/svg/deepseek.svg +1 -0
  165. package/src/provider-hub/svg/moonshot.svg +1 -0
  166. package/src/provider-hub/svg/openai.svg +1 -0
  167. package/src/provider-hub/svg/qwen.svg +1 -0
  168. package/src/provider-hub/svg/siliconflow.svg +1 -0
  169. package/src/provider-hub/types.ts +256 -0
@@ -0,0 +1,107 @@
1
+ /**
2
+ * useKhI18n — the internal i18n hook every component uses.
3
+ *
4
+ * `t('recall.hits', {n: 5})` looks up the key from the current locale, falls
5
+ * back to en-US, then to the raw key if truly missing.
6
+ *
7
+ * Locales are provided by wrapping the tree in <KhI18nProvider :locale="..."/>
8
+ * or by passing :locale directly on KnowledgeHubApp (which does the provide
9
+ * for us). Hosts can also override just a few keys — the hook deep-merges the
10
+ * provided partial over the default.
11
+ */
12
+ import {
13
+ computed,
14
+ inject,
15
+ type InjectionKey,
16
+ provide,
17
+ ref,
18
+ type Ref,
19
+ } from 'vue';
20
+
21
+ import { DEFAULT_LOCALE, enUS, type KhMessages } from './messages';
22
+
23
+ /** A partial locale — hosts only need to override the keys they change. */
24
+ export type KhLocale =
25
+ | 'en-US'
26
+ | 'zh-CN'
27
+ | DeepPartial<KhMessages>;
28
+
29
+ type DeepPartial<T> = {
30
+ [P in keyof T]?: DeepPartial<T[P]>;
31
+ };
32
+
33
+ const KEY: InjectionKey<Ref<KhMessages>> = Symbol('kh-i18n');
34
+
35
+ function isPartial(v: KhLocale): v is DeepPartial<KhMessages> {
36
+ return typeof v === 'object' && v !== null;
37
+ }
38
+
39
+ function deepMerge<T>(base: T, override: DeepPartial<T>): T {
40
+ if (!override) return base;
41
+ const out: any = { ...base };
42
+ for (const k in override) {
43
+ const v = (override as any)[k];
44
+ if (v && typeof v === 'object' && !Array.isArray(v)) {
45
+ out[k] = deepMerge((base as any)[k], v);
46
+ } else if (v !== undefined) {
47
+ out[k] = v;
48
+ }
49
+ }
50
+ return out as T;
51
+ }
52
+
53
+ function resolveLocale(locale?: KhLocale): KhMessages {
54
+ if (locale === 'en-US') return enUS;
55
+ if (locale === 'zh-CN' || locale === undefined) return DEFAULT_LOCALE;
56
+ if (isPartial(locale)) {
57
+ return deepMerge(DEFAULT_LOCALE, locale);
58
+ }
59
+ return DEFAULT_LOCALE;
60
+ }
61
+
62
+ /**
63
+ * KnowledgeHubApp calls this in its setup so every descendant gets the same
64
+ * message catalog. Passing a new `locale` prop updates it reactively.
65
+ */
66
+ export function provideKhI18n(locale: () => KhLocale | undefined) {
67
+ const messages = ref<KhMessages>(resolveLocale(locale()));
68
+ // A simple watcher wouldn't work here because we don't want a vue-watcher
69
+ // dep for the module — refresh manually on next tick by re-calling the fn.
70
+ // Consumers who need reactivity can pass a locale that never changes, or
71
+ // remount KnowledgeHubApp with the new locale.
72
+ provide(KEY, messages);
73
+ return messages;
74
+ }
75
+
76
+ /**
77
+ * Every component uses this. Returns `t(key, params?)` — key is dot-separated
78
+ * ('recall.hits'); params is a `{name}` map interpolated into the string.
79
+ */
80
+ export function useKhI18n() {
81
+ const messages = inject(KEY, ref(DEFAULT_LOCALE));
82
+
83
+ const t = (path: string, params?: Record<string, number | string>): string => {
84
+ const parts = path.split('.');
85
+ let cur: any = messages.value;
86
+ for (const p of parts) {
87
+ cur = cur?.[p];
88
+ if (cur === undefined) break;
89
+ }
90
+ if (typeof cur !== 'string') {
91
+ // Fall back to en-US
92
+ cur = enUS;
93
+ for (const p of parts) {
94
+ cur = cur?.[p];
95
+ if (cur === undefined) break;
96
+ }
97
+ if (typeof cur !== 'string') return path;
98
+ }
99
+ if (!params) return cur;
100
+ return cur.replaceAll(/\{(\w+)\}/g, (_, k) => String(params[k] ?? `{${k}}`));
101
+ };
102
+
103
+ return {
104
+ t,
105
+ messages: computed(() => messages.value),
106
+ };
107
+ }
@@ -0,0 +1,46 @@
1
+ /**
2
+ * @agent-start/knowledge-hub — public entry point.
3
+ *
4
+ * See README.md for usage. Quick recap:
5
+ *
6
+ * import { KnowledgeHubApp, createSpringAgentStartAdapter } from '@agent-start/knowledge-hub'
7
+ * import '@agent-start/knowledge-hub/style.css'
8
+ *
9
+ * <KnowledgeHubApp :api="createSpringAgentStartAdapter({baseUrl: '/api/agent-start'})" />
10
+ *
11
+ * Consumers with a non-spring-agent-start backend implement the `KnowledgeHubApi`
12
+ * interface themselves (see types/api.ts — it's split into small sub-interfaces
13
+ * so partial implementations are easy).
14
+ */
15
+
16
+ // --- Style tokens (defaults). Consumers can also import '@agent-start/knowledge-hub/style.css'
17
+ // separately if they want to control when the CSS is injected.
18
+ import './styles/index.css';
19
+
20
+ // --- Drop-in top-level
21
+ export { default as KnowledgeHubApp } from './components/KnowledgeHubApp.vue';
22
+
23
+ // --- Building blocks
24
+ export { default as CreateDatasetWizard } from './components/CreateDatasetWizard.vue';
25
+ export { default as DatasetCardGrid } from './components/DatasetCardGrid.vue';
26
+ export { default as DatasetDetailDrawer } from './components/DatasetDetailDrawer.vue';
27
+ export { default as DatasetSettingsPanel } from './components/DatasetSettingsPanel.vue';
28
+ export { default as DatasetSidebar } from './components/DatasetSidebar.vue';
29
+ export { default as DocumentChunksView } from './components/DocumentChunksView.vue';
30
+ export { default as DocumentTable } from './components/DocumentTable.vue';
31
+ export { default as RecallTestingPanelV2 } from './components/RecallTestingPanelV2.vue';
32
+
33
+ // --- Legacy widgets (still used by /workflow KNOWLEDGE_RETRIEVAL node etc.)
34
+ export { default as DatasetPicker } from './components/DatasetPicker.vue';
35
+ export { default as DatasetPickerModal } from './components/DatasetPickerModal.vue';
36
+ export { default as HitTestingPanel } from './components/HitTestingPanel.vue';
37
+ export { default as RetrievedList } from './components/RetrievedList.vue';
38
+
39
+ // --- Adapters (implement KnowledgeHubApi against a known backend)
40
+ export { createSpringAgentStartAdapter } from './adapters/springAgentStart';
41
+
42
+ // --- Composables
43
+ export * from './composables/useKnowledge';
44
+
45
+ // --- All types re-exported from a single surface
46
+ export * from './types';
@@ -0,0 +1,4 @@
1
+ /* Entry stylesheet — hosts import this once at their app entry:
2
+ import '@agent-start/knowledge-hub/style.css'
3
+ Everything else is composed of design tokens declared in tokens.css. */
4
+ @import './tokens.css';
@@ -0,0 +1,138 @@
1
+ /**
2
+ * Design tokens for @agent-start/knowledge-hub.
3
+ *
4
+ * These are the ONLY colors, radii and shadows the components should reference.
5
+ * A host that wants to rebrand overrides them at the root:
6
+ *
7
+ * :root {
8
+ * --kh-color-primary: #ff6600;
9
+ * --kh-color-primary-strong: #cc4d00;
10
+ * }
11
+ *
12
+ * A dark ruleset ships out of the box — flip it by setting `data-theme="dark"`
13
+ * on any ancestor of the components.
14
+ */
15
+
16
+ :root {
17
+ /* ------- Color: brand */
18
+ --kh-color-primary: #6366f1;
19
+ --kh-color-primary-strong: #4f46e5;
20
+ --kh-color-primary-soft: #eef2ff;
21
+ --kh-color-primary-contrast: #ffffff;
22
+ --kh-color-primary-outline: rgba(99, 102, 241, 0.15);
23
+
24
+ /* ------- Color: neutrals (text + surface) */
25
+ --kh-color-text-primary: #0f172a;
26
+ --kh-color-text-secondary: #334155;
27
+ --kh-color-text-tertiary: #64748b;
28
+ --kh-color-text-muted: #94a3b8;
29
+ --kh-color-text-inverse: #ffffff;
30
+
31
+ --kh-color-surface: #ffffff;
32
+ --kh-color-surface-raised: #ffffff;
33
+ --kh-color-surface-sunken: #f8fafc;
34
+ --kh-color-surface-hover: #f1f5f9;
35
+
36
+ --kh-color-border: #e2e8f0;
37
+ --kh-color-border-hover: #cbd5e1;
38
+ --kh-color-border-strong: #94a3b8;
39
+ --kh-color-divider: #f1f5f9;
40
+
41
+ /* ------- Color: semantic */
42
+ --kh-color-success: #059669;
43
+ --kh-color-success-soft: #dcfce7;
44
+ --kh-color-warning: #b45309;
45
+ --kh-color-warning-soft: #fef3c7;
46
+ --kh-color-danger: #dc2626;
47
+ --kh-color-danger-soft: #fef2f2;
48
+ --kh-color-info: #4338ca;
49
+ --kh-color-info-soft: #eef4ff;
50
+
51
+ /* ------- Radius */
52
+ --kh-radius-xs: 4px;
53
+ --kh-radius-sm: 6px;
54
+ --kh-radius-md: 8px;
55
+ --kh-radius-lg: 12px;
56
+ --kh-radius-xl: 16px;
57
+ --kh-radius-round: 50%;
58
+
59
+ /* ------- Spacing */
60
+ --kh-space-1: 4px;
61
+ --kh-space-2: 8px;
62
+ --kh-space-3: 12px;
63
+ --kh-space-4: 16px;
64
+ --kh-space-5: 20px;
65
+ --kh-space-6: 24px;
66
+
67
+ /* ------- Font sizes */
68
+ --kh-fs-xs: 10px;
69
+ --kh-fs-sm: 11px;
70
+ --kh-fs-md: 12px;
71
+ --kh-fs-lg: 13px;
72
+ --kh-fs-xl: 14px;
73
+ --kh-fs-2xl: 15px;
74
+ --kh-fs-3xl: 18px;
75
+
76
+ /* ------- Shadows */
77
+ --kh-shadow-sm: 0 1px 2px rgba(15, 23, 42, 0.04);
78
+ --kh-shadow-md: 0 3px 12px rgba(15, 23, 42, 0.06);
79
+ --kh-shadow-lg: 0 4px 14px rgba(15, 23, 42, 0.08);
80
+ --kh-shadow-drawer: -6px 0 22px rgba(15, 23, 42, 0.14);
81
+ --kh-shadow-modal: 0 20px 60px rgba(15, 23, 42, 0.25);
82
+
83
+ /* ------- Transition */
84
+ --kh-tx-fast: 0.15s ease;
85
+
86
+ /* ------- z-index (mostly for drawer/modal stacking) */
87
+ --kh-z-drawer: 1040;
88
+ --kh-z-modal: 1050;
89
+
90
+ /* ------- Focus ring */
91
+ --kh-focus-ring: 0 0 0 3px var(--kh-color-primary-outline);
92
+
93
+ /* ------- Component-level (composed from primitives) */
94
+ --kh-card-bg: var(--kh-color-surface);
95
+ --kh-card-border: var(--kh-color-border);
96
+ --kh-card-radius: var(--kh-radius-lg);
97
+ --kh-card-shadow-hover: var(--kh-shadow-lg);
98
+
99
+ --kh-input-bg: var(--kh-color-surface);
100
+ --kh-input-border: #d1d5db;
101
+ --kh-input-radius: var(--kh-radius-md);
102
+ }
103
+
104
+ /* Dark mode overrides — flipped by setting data-theme="dark" on any ancestor. */
105
+ [data-theme='dark'] {
106
+ --kh-color-primary: #818cf8;
107
+ --kh-color-primary-strong: #6366f1;
108
+ --kh-color-primary-soft: rgba(129, 140, 248, 0.15);
109
+ --kh-color-primary-contrast: #ffffff;
110
+ --kh-color-primary-outline: rgba(129, 140, 248, 0.3);
111
+
112
+ --kh-color-text-primary: #f3f4f6;
113
+ --kh-color-text-secondary: #d1d5db;
114
+ --kh-color-text-tertiary: #9ca3af;
115
+ --kh-color-text-muted: #6b7280;
116
+ --kh-color-text-inverse: #0f172a;
117
+
118
+ --kh-color-surface: #1f2937;
119
+ --kh-color-surface-raised: #262f3d;
120
+ --kh-color-surface-sunken: #171e2b;
121
+ --kh-color-surface-hover: #2d3748;
122
+
123
+ --kh-color-border: #374151;
124
+ --kh-color-border-hover: #4b5563;
125
+ --kh-color-border-strong: #6b7280;
126
+ --kh-color-divider: #2d3748;
127
+
128
+ --kh-color-success-soft: rgba(16, 185, 129, 0.15);
129
+ --kh-color-warning-soft: rgba(217, 119, 6, 0.15);
130
+ --kh-color-danger-soft: rgba(220, 38, 38, 0.15);
131
+ --kh-color-info-soft: rgba(99, 102, 241, 0.15);
132
+
133
+ --kh-input-border: #4b5563;
134
+
135
+ --kh-shadow-sm: 0 1px 2px rgba(0, 0, 0, 0.4);
136
+ --kh-shadow-md: 0 3px 12px rgba(0, 0, 0, 0.4);
137
+ --kh-shadow-lg: 0 4px 14px rgba(0, 0, 0, 0.5);
138
+ }
@@ -0,0 +1,213 @@
1
+ /**
2
+ * The API contract KnowledgeHubApp needs. Split into 5 sub-interfaces so a
3
+ * host can implement a partial (e.g. a read-only viewer only needs
4
+ * DatasetsReadApi + DocumentsReadApi + RetrievalApi).
5
+ *
6
+ * `KnowledgeHubApi` is a type union of every sub-interface — code that
7
+ * accepts one can accept any richer implementation.
8
+ */
9
+ import type { Chunk, DocMetadata, DocumentRow } from './document';
10
+ import type {
11
+ DatasetCardItem,
12
+ DatasetSummary,
13
+ IndexingTechnique,
14
+ ProcessRule,
15
+ RetrievalConfig,
16
+ } from './dataset';
17
+ import type { RecallHit, RecentQuery } from './retrieval';
18
+
19
+ // ------- datasets
20
+ export interface DatasetsApi {
21
+ listDatasets(): Promise<DatasetCardItem[]>;
22
+ getDataset(id: string): Promise<DatasetSummary>;
23
+ createDataset(req: {
24
+ name: string;
25
+ description?: string;
26
+ embeddingModelId?: string;
27
+ indexingTechnique?: IndexingTechnique;
28
+ processRule?: ProcessRule;
29
+ retrievalConfig?: RetrievalConfig;
30
+ }): Promise<DatasetCardItem>;
31
+ updateDataset(
32
+ id: string,
33
+ patch: Partial<DatasetSummary> & Record<string, unknown>,
34
+ ): Promise<DatasetSummary>;
35
+ deleteDataset(id: string): Promise<void>;
36
+ }
37
+
38
+ // ------- documents
39
+ export interface DocumentsApi {
40
+ listDocuments(datasetId: string): Promise<DocumentRow[]>;
41
+ uploadDocument(datasetId: string, file: File): Promise<void>;
42
+ deleteDocument(datasetId: string, docId: string): Promise<void>;
43
+ setDocumentEnabled?(
44
+ datasetId: string,
45
+ docId: string,
46
+ enabled: boolean,
47
+ ): Promise<void>;
48
+ /**
49
+ * Preview how a file would be chunked under a given {@link ProcessRule}
50
+ * without touching the DB or the vector store. Used by the wizard's
51
+ * "文本分段与清洗" step so the preview reflects the real ingestion result
52
+ * (same reader → same cleaner → same chunker as on save). Backends that
53
+ * don't implement it get the wizard's mock preview as a fallback.
54
+ *
55
+ * @param file raw file bytes the user just picked
56
+ * @param rule the currently-editing {@link ProcessRule}
57
+ * @param limit max chunks to return; server may cap further
58
+ */
59
+ previewChunks?(
60
+ file: File,
61
+ rule: ProcessRule,
62
+ limit?: number,
63
+ ): Promise<ChunkPreview>;
64
+ }
65
+
66
+ /**
67
+ * Response shape of {@link DocumentsApi.previewChunks}. {@code totalChunks}
68
+ * is the full chunker output; {@code chunks} is truncated to {@code limit}.
69
+ */
70
+ export interface ChunkPreview {
71
+ totalChunks: number;
72
+ chunks: Array<{ index: number; text: string; tokens: number }>;
73
+ }
74
+
75
+ // ------- segments
76
+ export interface SegmentsApi {
77
+ /**
78
+ * Paged fetch of a document's segments. `page` is 1-indexed; when omitted the
79
+ * host implementation is expected to return the first page with a sensible
80
+ * default page size. The total comes from {@link DocMetadata#totalChunks} —
81
+ * kept out of this response to avoid an extra count query on hot paths.
82
+ */
83
+ listSegments(
84
+ datasetId: string,
85
+ docId: string,
86
+ page?: number,
87
+ pageSize?: number,
88
+ ): Promise<Chunk[]>;
89
+ loadDocumentMetadata(datasetId: string, docId: string): Promise<DocMetadata>;
90
+ updateSegment(
91
+ datasetId: string,
92
+ docId: string,
93
+ segId: string,
94
+ content: string,
95
+ ): Promise<Chunk>;
96
+ deleteSegment(datasetId: string, docId: string, segId: string): Promise<void>;
97
+ setSegmentEnabled(
98
+ datasetId: string,
99
+ docId: string,
100
+ segId: string,
101
+ enabled: boolean,
102
+ ): Promise<Chunk>;
103
+ appendSegment?(
104
+ datasetId: string,
105
+ docId: string,
106
+ content: string,
107
+ ): Promise<Chunk>;
108
+ }
109
+
110
+ // ------- retrieval
111
+ export interface RetrievalApi {
112
+ retrieve(
113
+ datasetId: string,
114
+ req: { query: string; method: string; topK?: number },
115
+ ): Promise<RecallHit[]>;
116
+ listRecallHistory(datasetId: string, limit?: number): Promise<RecentQuery[]>;
117
+ }
118
+
119
+ // ------- models
120
+ /**
121
+ * Embedding-model list entry. {@code providerName} is optional but recommended —
122
+ * when present, the settings panel groups the dropdown by provider and shows a
123
+ * brand icon for each row. {@code providerLabel} is a display label; falls back
124
+ * to {@code providerName} when omitted.
125
+ */
126
+ export interface EmbeddingModelOption {
127
+ id: string;
128
+ label: string;
129
+ providerName?: string;
130
+ providerLabel?: string;
131
+ /** Marks the tenant-default embedding model — the panel auto-selects it. */
132
+ isDefault?: boolean;
133
+ }
134
+
135
+ export interface ModelsApi {
136
+ listEmbeddingModels(): Promise<EmbeddingModelOption[]>;
137
+ /**
138
+ * Optional — list rerank models the wizard's 检索设置 offers. Hosts that don't
139
+ * implement it get an empty dropdown (rerank stays off).
140
+ */
141
+ listRerankModels?(): Promise<Array<{ id: string; label: string }>>;
142
+ /**
143
+ * Optional — resolve the tenant-scoped default embedding model id (from
144
+ * {@code /models/defaults} on the spring-agent-start backend). When present,
145
+ * the settings panel pre-fills the picker if the dataset itself has none.
146
+ */
147
+ getDefaultEmbeddingModelId?(): Promise<null | string>;
148
+ }
149
+
150
+ // ------- side effects (all optional)
151
+ export interface KnowledgeHubHooks {
152
+ /** Toast success. */
153
+ onSuccess?(message: string): void;
154
+ /** Toast failure. */
155
+ onError?(message: string): void;
156
+ /** Called by the sidebar's ⌘ 访问 API button. */
157
+ onCopyApi?(datasetId: string): void;
158
+ /**
159
+ * Called when the built-in "先注册 Embedding 模型" empty-state nudge is
160
+ * clicked. Hosts wire this to their model-management route so the user
161
+ * can register an embedding model without leaving the flow. When omitted
162
+ * the nudge card renders without a button.
163
+ */
164
+ onGoToEmbeddingSetup?(): void;
165
+ }
166
+
167
+ /**
168
+ * The bag of async operations KnowledgeHubApp needs. Consumers implement this
169
+ * shape (typically by wrapping their existing REST client — or by calling
170
+ * `createSpringAgentStartAdapter` if their backend is spring-agent-start itself).
171
+ */
172
+ export type KnowledgeHubApi = DatasetsApi &
173
+ DocumentsApi &
174
+ SegmentsApi &
175
+ RetrievalApi &
176
+ ModelsApi &
177
+ KnowledgeHubHooks;
178
+
179
+ /**
180
+ * Subset used by DatasetDetailDrawer. Standalone (not `extends`) because it
181
+ * exposes `loadDataset` + `uploadDocuments` (plural, batch semantic) rather
182
+ * than the {@link DatasetsApi#getDataset} + {@link DocumentsApi#uploadDocument}
183
+ * atoms. Hosts that only need the drawer implement this smaller surface.
184
+ */
185
+ export interface DatasetDetailHub extends SegmentsApi, RetrievalApi, ModelsApi {
186
+ loadDataset(id: string): Promise<DatasetSummary>;
187
+ updateDataset(
188
+ id: string,
189
+ patch: Partial<DatasetSummary> & Record<string, unknown>,
190
+ ): Promise<DatasetSummary>;
191
+ deleteDataset(id: string): Promise<void>;
192
+
193
+ listDocuments(datasetId: string): Promise<DocumentRow[]>;
194
+ uploadDocuments(datasetId: string, files: File[]): Promise<void>;
195
+ deleteDocument(datasetId: string, docId: string): Promise<void>;
196
+ setDocumentEnabled?(
197
+ datasetId: string,
198
+ docId: string,
199
+ enabled: boolean,
200
+ ): Promise<void>;
201
+ /**
202
+ * Preview how a file would be chunked, for the add-documents wizard's
203
+ * step-2 pane. Same shape as {@link DocumentsApi.previewChunks}. Optional —
204
+ * when the host adapter omits it, the wizard falls back to a mock preview.
205
+ */
206
+ previewChunks?(
207
+ file: File,
208
+ rule: ProcessRule,
209
+ limit?: number,
210
+ ): Promise<ChunkPreview>;
211
+
212
+ onCopyApi?(datasetId: string): void;
213
+ }
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Dataset-level types. Mirror the spring-agent-web JSON contract, but the
3
+ * module has no hard dependency on that backend — any REST source that returns
4
+ * these shapes works.
5
+ */
6
+
7
+ export type IndexingTechnique = 'ECONOMY' | 'HIGH_QUALITY';
8
+
9
+ /**
10
+ * Slim dataset view suitable for the card grid. Only the visual fields are
11
+ * required — a partial-shape backend still works, the card just shows less.
12
+ */
13
+ export interface DatasetCardItem {
14
+ id: string;
15
+ name: string;
16
+ description?: string;
17
+ documentCount?: number;
18
+ segmentCount?: number;
19
+ indexingTechnique?: IndexingTechnique;
20
+ updatedAt?: string;
21
+ }
22
+
23
+ /**
24
+ * Full dataset shape for the detail view. Optional JSON-blob fields
25
+ * (`retrievalConfigJson`, `processRuleJson`) are strings so the module can
26
+ * parse them defensively without coupling to a specific config schema.
27
+ */
28
+ export interface DatasetSummary {
29
+ id: string;
30
+ name: string;
31
+ description?: string;
32
+ documentCount?: number;
33
+ segmentCount?: number;
34
+ indexingTechnique?: IndexingTechnique;
35
+ embeddingModelId?: string;
36
+ retrievalConfigJson?: string;
37
+ processRuleJson?: string;
38
+ }
39
+
40
+ /** Legacy alias kept for backwards compat with older Dify-style flows. */
41
+ export interface Dataset extends DatasetSummary {
42
+ tenantId?: string;
43
+ }
44
+
45
+ /** Navigation tabs of the dataset detail view. */
46
+ export type DatasetTab = 'documents' | 'recall' | 'settings';
47
+
48
+ // --------- process rule (chunking) -----------------------------------------
49
+
50
+ export type ChunkingTemplate =
51
+ | 'NAIVE'
52
+ | 'PARENT_CHILD'
53
+ | 'QA'
54
+ | 'MARKDOWN'
55
+ | 'ONE';
56
+
57
+ export type ParentMode = 'PARAGRAPH' | 'FULL_DOC';
58
+
59
+ /**
60
+ * Wire shape of the backend `ProcessRule`. Only fields the wizard writes are
61
+ * enumerated — hosts can send extras and the backend just ignores them.
62
+ */
63
+ export interface ProcessRule {
64
+ template?: ChunkingTemplate;
65
+ chunkTokens?: number;
66
+ overlapTokens?: number;
67
+ parentChunkTokens?: number;
68
+ parentMode?: ParentMode;
69
+ separators?: string[];
70
+ removeExtraWhitespace?: boolean;
71
+ removeUrlsEmails?: boolean;
72
+ }
73
+
74
+ // --------- retrieval config -------------------------------------------------
75
+ // Note: RetrievalMethod itself lives in ./retrieval to keep the retrieval module
76
+ // self-contained; we import it here just for RetrievalConfig.
77
+ import type { RetrievalMethod } from './retrieval';
78
+
79
+ /** Wire shape of the backend `RetrievalConfig`. */
80
+ export interface RetrievalConfig {
81
+ method?: RetrievalMethod;
82
+ topK?: number;
83
+ scoreThreshold?: number;
84
+ vectorWeight?: number;
85
+ rerankEnabled?: boolean;
86
+ rerankModelId?: string;
87
+ rerankerName?: string;
88
+ }
@@ -0,0 +1,45 @@
1
+ /**
2
+ * Document + chunk (segment) types.
3
+ */
4
+
5
+ /** One row in the DocumentTable. */
6
+ export interface DocumentRow {
7
+ id: string;
8
+ name: string;
9
+ /** "自定义" / "父子分段" — display string, not enum. */
10
+ chunkMode?: string;
11
+ wordCount?: number;
12
+ hitCount?: number;
13
+ uploadedAt?: string;
14
+ status: 'AVAILABLE' | 'FAILED' | 'PROCESSING';
15
+ enabled: boolean;
16
+ }
17
+
18
+ /** One chunk shown in DocumentChunksView. */
19
+ export interface Chunk {
20
+ id: string;
21
+ position: number;
22
+ content: string;
23
+ tokenCount?: number;
24
+ charCount?: number;
25
+ hitCount?: number;
26
+ enabled: boolean;
27
+ keywords?: string[];
28
+ }
29
+
30
+ /** Right-side metadata pane of DocumentChunksView. */
31
+ export interface DocMetadata {
32
+ fileName?: string;
33
+ kind?: string;
34
+ size?: string;
35
+ uploadedAt?: string;
36
+ parsedAt?: string;
37
+ embeddedAt?: string;
38
+ chunkMode?: string;
39
+ chunkMaxSize?: number;
40
+ totalChars?: number;
41
+ totalChunks?: number;
42
+ avgChunkChars?: number;
43
+ avgEmbedMs?: number;
44
+ totalTokens?: number;
45
+ }
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Public type surface of @agent-start/knowledge-hub. Everything a consumer might
3
+ * need to type their host code is re-exported here.
4
+ */
5
+
6
+ export * from './api';
7
+ export * from './dataset';
8
+ export * from './document';
9
+ export * from './retrieval';
@@ -0,0 +1,46 @@
1
+ /**
2
+ * Retrieval / hit-testing types.
3
+ */
4
+
5
+ export type RetrievalMethod = 'FULL_TEXT' | 'HYBRID' | 'VECTOR';
6
+
7
+ export interface RetrieveRequest {
8
+ query: string;
9
+ method?: RetrievalMethod;
10
+ topK?: number;
11
+ scoreThreshold?: number;
12
+ vectorWeight?: number;
13
+ metadataFilter?: Record<string, unknown>;
14
+ }
15
+
16
+ /** Row in the retrieval result list — from HybridRetriever. */
17
+ export interface RetrievedSegment {
18
+ segmentId: string;
19
+ datasetId: string;
20
+ documentId: string;
21
+ position: number;
22
+ content: string;
23
+ parentContent?: string;
24
+ vectorScore: number;
25
+ keywordScore: number;
26
+ score: number;
27
+ metadata?: Record<string, unknown>;
28
+ }
29
+
30
+ /** One row in the RecallTestingPanel result pane. Simpler than RetrievedSegment. */
31
+ export interface RecallHit {
32
+ segmentId: string;
33
+ content: string;
34
+ position?: number;
35
+ score: number;
36
+ documentName?: string;
37
+ }
38
+
39
+ /** Historical recall query row shown in the "记录" list. */
40
+ export interface RecentQuery {
41
+ id: string;
42
+ query: string;
43
+ method: string;
44
+ hitCount: number;
45
+ at: string;
46
+ }