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,390 @@
1
+ /**
2
+ * createAgentStudioSpringBackend — returns the full callback bag the two
3
+ * top-level agent pages (AgentAppsPage / AgentChatPage) need, backed by the
4
+ * spring-agent-web-starter REST endpoints under {@code baseUrl}.
5
+ *
6
+ * import {
7
+ * AgentAppsPage,
8
+ * createAgentStudioSpringBackend,
9
+ * } from 'vue-agent-start';
10
+ *
11
+ * <AgentAppsPage :api="createAgentStudioSpringBackend({ baseUrl: '/api' })" />
12
+ *
13
+ * The bag is a superset of {@link AppStudioApi} (drawer / annotation / monitor
14
+ * / api-key panels) with the extra CRUD + streaming methods the list page uses.
15
+ * Hosts that want a totally custom backend can implement {@link AgentStudioApi}
16
+ * directly instead.
17
+ */
18
+ import type { AppStudioApi } from '../api';
19
+
20
+ // ---------------------------------------------------------------------------
21
+ // Types — mirror the shapes emitted by spring-agent-web-starter. Copies of
22
+ // what used to live under `#/api/agent-start/*` in the host app. Kept flat here
23
+ // so the whole adapter is one drop-in file.
24
+ // ---------------------------------------------------------------------------
25
+
26
+ export type AgentStrategy = 'FUNCTION_CALLING' | 'PLAN_EXECUTE' | 'REACT';
27
+
28
+ export type AppMode =
29
+ | 'agent'
30
+ | 'chat'
31
+ | 'chatflow'
32
+ | 'completion'
33
+ | 'workflow';
34
+
35
+ export interface AgentEntity {
36
+ id: string;
37
+ tenantId?: string;
38
+ name: string;
39
+ description?: string;
40
+ icon?: string;
41
+ iconBackground?: string;
42
+ mode?: AppMode;
43
+ instructions?: string;
44
+ openingStatement?: string;
45
+ suggestedQuestionsJson?: string;
46
+ datasetIdsJson?: string;
47
+ retrievalConfigJson?: string;
48
+ workflowId?: string;
49
+ modelName?: string;
50
+ modelProvider?: string;
51
+ modelSettingsJson?: string;
52
+ strategy?: AgentStrategy;
53
+ toolNamesJson?: string;
54
+ approvalToolsJson?: string;
55
+ delegateAgentIdsJson?: string;
56
+ maxIterations?: number;
57
+ memoryEnabled?: boolean;
58
+ memoryWindow?: number;
59
+ published?: boolean;
60
+ createdAt?: string;
61
+ updatedAt?: string;
62
+ }
63
+
64
+ export interface CreateAgentRequest {
65
+ tenantId?: string;
66
+ name: string;
67
+ description?: string;
68
+ icon?: string;
69
+ iconBackground?: string;
70
+ mode?: AppMode;
71
+ instructions?: string;
72
+ openingStatement?: string;
73
+ suggestedQuestions?: string[];
74
+ datasetIds?: string[];
75
+ retrievalConfig?: Record<string, unknown>;
76
+ modelName?: string;
77
+ modelProvider?: string;
78
+ strategy?: AgentStrategy;
79
+ toolNames?: string[];
80
+ approvalRequiredTools?: string[];
81
+ delegateAgentIds?: string[];
82
+ maxIterations?: number;
83
+ memoryEnabled?: boolean;
84
+ memoryWindow?: number;
85
+ published?: boolean;
86
+ modelSettings?: Record<string, unknown>;
87
+ }
88
+
89
+ export interface AgentToolView {
90
+ name: string;
91
+ description: string;
92
+ inputSchema?: string;
93
+ }
94
+
95
+ export interface AgentHistoryMessage {
96
+ role: 'ASSISTANT' | 'SYSTEM' | 'USER';
97
+ content: string;
98
+ }
99
+
100
+ export interface ConversationSummary {
101
+ conversationId: string;
102
+ name?: string;
103
+ userId?: null | string;
104
+ firstMessage?: string;
105
+ updatedAt?: string;
106
+ pinned?: boolean;
107
+ }
108
+
109
+ export interface ChatRequest {
110
+ query: string;
111
+ conversationId?: string;
112
+ variables?: Record<string, unknown>;
113
+ }
114
+
115
+ export interface DatasetLite {
116
+ id: string;
117
+ name: string;
118
+ description?: string;
119
+ }
120
+
121
+ export interface ModelLite {
122
+ id: string;
123
+ providerName: string;
124
+ modelName: string;
125
+ modelType?: string;
126
+ enabled?: boolean;
127
+ isDefault?: boolean;
128
+ }
129
+
130
+ export interface ToolLite {
131
+ name: string;
132
+ description: string;
133
+ }
134
+
135
+ export interface WorkflowGraphLike {
136
+ nodes: Array<Record<string, unknown>>;
137
+ edges: Array<Record<string, unknown>>;
138
+ [k: string]: unknown;
139
+ }
140
+
141
+ export interface WorkflowEntityLite {
142
+ id: string;
143
+ appId?: string;
144
+ name?: string;
145
+ mode?: string;
146
+ graph?: WorkflowGraphLike | Record<string, unknown> | null;
147
+ version?: string;
148
+ published?: boolean;
149
+ createdAt?: string;
150
+ updatedAt?: string;
151
+ }
152
+
153
+ /**
154
+ * Full API bag consumed by AgentAppsPage / AgentChatPage. Extends
155
+ * {@link AppStudioApi} so an instance passed to the page also drives the
156
+ * drawer's built-in panels.
157
+ */
158
+ export interface AgentStudioApi extends AppStudioApi {
159
+ // agent CRUD
160
+ listAgents(): Promise<AgentEntity[]>;
161
+ getAgent(id: string): Promise<AgentEntity>;
162
+ createAgent(req: CreateAgentRequest): Promise<AgentEntity>;
163
+ updateAgent(id: string, req: CreateAgentRequest): Promise<AgentEntity>;
164
+ deleteAgent(id: string): Promise<void>;
165
+
166
+ // chat runtime
167
+ fetchAgentTools(id: string): Promise<AgentToolView[]>;
168
+ chatStream(id: string, req: ChatRequest): Promise<Response>;
169
+ fetchConversations(agentId: string, limit?: number): Promise<ConversationSummary[]>;
170
+ fetchHistoryMessages(
171
+ agentId: string,
172
+ conversationId: string,
173
+ limit?: number,
174
+ ): Promise<AgentHistoryMessage[]>;
175
+
176
+ // drawer dropdown data
177
+ listDatasets(): Promise<DatasetLite[]>;
178
+ listModels(type?: string): Promise<ModelLite[]>;
179
+ listTools(): Promise<ToolLite[]>;
180
+
181
+ // workflow draft/publish (chatflow / workflow modes)
182
+ getWorkflowDraft(appId: string): Promise<WorkflowEntityLite>;
183
+ saveWorkflowDraft(appId: string, graph: WorkflowGraphLike): Promise<WorkflowEntityLite>;
184
+ publishWorkflowDraft(appId: string): Promise<WorkflowEntityLite>;
185
+
186
+ /** Raw base URL — components may append their own paths (e.g. copy-curl). */
187
+ baseUrl: string;
188
+ }
189
+
190
+ // ---------------------------------------------------------------------------
191
+ // Factory
192
+ // ---------------------------------------------------------------------------
193
+
194
+ type FetchLike = typeof fetch;
195
+ type HeadersProvider = () =>
196
+ | Record<string, string>
197
+ | Promise<Record<string, string>>;
198
+
199
+ export interface AgentStudioAdapterOptions {
200
+ /** Backend base URL. Default: `/api`. */
201
+ baseUrl?: string;
202
+ fetch?: FetchLike;
203
+ headers?: HeadersProvider;
204
+ onError?(msg: string): void;
205
+ onSuccess?(msg: string): void;
206
+ timeoutMs?: number;
207
+ }
208
+
209
+ interface Envelope<T> {
210
+ code: string;
211
+ message?: string;
212
+ data: T;
213
+ }
214
+
215
+ export function createAgentStudioSpringBackend(
216
+ opts: AgentStudioAdapterOptions = {},
217
+ ): AgentStudioApi {
218
+ const baseUrl = (opts.baseUrl ?? '/api').replace(/\/+$/, '');
219
+ const doFetch: FetchLike = opts.fetch ?? ((...args) => fetch(...args));
220
+ const timeoutMs = opts.timeoutMs ?? 60_000;
221
+
222
+ async function extraHeaders(): Promise<Record<string, string>> {
223
+ return opts.headers ? await opts.headers() : {};
224
+ }
225
+
226
+ function qs(params?: Record<string, unknown>): string {
227
+ if (!params) return '';
228
+ const parts: string[] = [];
229
+ for (const [k, v] of Object.entries(params)) {
230
+ if (v == null) continue;
231
+ parts.push(`${encodeURIComponent(k)}=${encodeURIComponent(String(v))}`);
232
+ }
233
+ return parts.length > 0 ? `?${parts.join('&')}` : '';
234
+ }
235
+
236
+ async function call<T>(
237
+ path: string,
238
+ init: RequestInit = {},
239
+ ): Promise<T> {
240
+ const controller = new AbortController();
241
+ const timer = setTimeout(() => controller.abort(), timeoutMs);
242
+ try {
243
+ const headers: Record<string, string> = {
244
+ 'Content-Type': 'application/json',
245
+ ...(await extraHeaders()),
246
+ ...((init.headers as Record<string, string>) ?? {}),
247
+ };
248
+ const res = await doFetch(`${baseUrl}${path}`, {
249
+ ...init,
250
+ headers,
251
+ signal: controller.signal,
252
+ });
253
+ if (!res.ok) {
254
+ let msg = `${res.status} ${res.statusText}`;
255
+ try {
256
+ const body = (await res.json()) as { message?: string };
257
+ if (body?.message) msg = body.message;
258
+ } catch {
259
+ // ignore body-parse errors
260
+ }
261
+ opts.onError?.(msg);
262
+ throw new Error(msg);
263
+ }
264
+ const env = (await res.json()) as Envelope<T>;
265
+ if (env.code !== 'ok') {
266
+ const msg = env.message ?? env.code;
267
+ opts.onError?.(msg);
268
+ throw new Error(msg);
269
+ }
270
+ return env.data;
271
+ } finally {
272
+ clearTimeout(timer);
273
+ }
274
+ }
275
+
276
+ return {
277
+ baseUrl,
278
+
279
+ // ---- agent CRUD --------------------------------------------------------
280
+ listAgents: () => call<AgentEntity[]>('/agents'),
281
+ getAgent: (id) => call<AgentEntity>(`/agents/${id}`),
282
+ createAgent: (req) =>
283
+ call<AgentEntity>('/agents', {
284
+ method: 'POST',
285
+ body: JSON.stringify(req),
286
+ }),
287
+ updateAgent: (id, req) =>
288
+ call<AgentEntity>(`/agents/${id}`, {
289
+ method: 'PUT',
290
+ body: JSON.stringify(req),
291
+ }),
292
+ deleteAgent: (id) =>
293
+ call<void>(`/agents/${id}`, { method: 'DELETE' }),
294
+
295
+ // ---- chat runtime ------------------------------------------------------
296
+ fetchAgentTools: (id) => call<AgentToolView[]>(`/agents/${id}/tools`),
297
+ chatStream: async (id, req) => {
298
+ const headers: Record<string, string> = {
299
+ 'Content-Type': 'application/json',
300
+ Accept: 'text/event-stream',
301
+ ...(await extraHeaders()),
302
+ };
303
+ return doFetch(`${baseUrl}/agents/${id}/chat/stream`, {
304
+ method: 'POST',
305
+ headers,
306
+ body: JSON.stringify(req),
307
+ });
308
+ },
309
+ fetchConversations: (agentId, limit = 100) =>
310
+ call<ConversationSummary[]>(`/chat/conversations/${agentId}`, {
311
+ method: 'POST',
312
+ body: JSON.stringify({ limit }),
313
+ }),
314
+ fetchHistoryMessages: (agentId, conversationId, limit = 500) =>
315
+ call<AgentHistoryMessage[]>(
316
+ `/chat/conversations/${agentId}/${conversationId}/messages`,
317
+ {
318
+ method: 'POST',
319
+ body: JSON.stringify({ limit }),
320
+ },
321
+ ),
322
+
323
+ // ---- drawer dropdown data ---------------------------------------------
324
+ listDatasets: () =>
325
+ call<DatasetLite[]>('/datasets').catch(() => []),
326
+ listModels: (type = 'LLM') =>
327
+ call<ModelLite[]>(`/models${qs({ type })}`).catch(() => []),
328
+ listTools: () =>
329
+ call<ToolLite[]>('/tools').catch(() => []),
330
+
331
+ // ---- workflow draft/publish -------------------------------------------
332
+ getWorkflowDraft: (appId) =>
333
+ call<WorkflowEntityLite>(`/apps/${appId}/workflow/draft`),
334
+ saveWorkflowDraft: (appId, graph) =>
335
+ call<WorkflowEntityLite>(`/apps/${appId}/workflow/draft`, {
336
+ method: 'PUT',
337
+ body: JSON.stringify({ graph }),
338
+ }),
339
+ publishWorkflowDraft: (appId) =>
340
+ call<WorkflowEntityLite>(`/apps/${appId}/workflow/publish`, {
341
+ method: 'POST',
342
+ body: JSON.stringify({}),
343
+ }),
344
+
345
+ // ---- AppStudioApi bag (drawer panels) ---------------------------------
346
+ listConversations: (appId, limit = 100) =>
347
+ call('/chat/conversations/' + appId, {
348
+ method: 'POST',
349
+ body: JSON.stringify({ limit }),
350
+ }),
351
+ fetchHistory: (appId, conversationId, limit = 500) =>
352
+ call(`/chat/conversations/${appId}/${conversationId}/messages`, {
353
+ method: 'POST',
354
+ body: JSON.stringify({ limit }),
355
+ }),
356
+
357
+ listAnnotations: (appId) => call(`/apps/${appId}/annotations`),
358
+ createAnnotation: (appId, req) =>
359
+ call(`/apps/${appId}/annotations`, {
360
+ method: 'POST',
361
+ body: JSON.stringify(req),
362
+ }),
363
+ updateAnnotation: (appId, id, req) =>
364
+ call(`/apps/${appId}/annotations/${id}`, {
365
+ method: 'PUT',
366
+ body: JSON.stringify(req),
367
+ }),
368
+ deleteAnnotation: (appId, id) =>
369
+ call<void>(`/apps/${appId}/annotations/${id}`, { method: 'DELETE' }),
370
+
371
+ fetchAppMetrics: (appId) => call(`/apps/${appId}/metrics`),
372
+ fetchLlmUsage: () => call('/llmops/total'),
373
+ fetchRecentLlmCalls: (limit = 50) =>
374
+ call(`/llmops/recent${qs({ limit })}`),
375
+
376
+ listApiKeys: (appId) => call(`/apps/${appId}/api-tokens`),
377
+ createApiKey: (appId, name) =>
378
+ call(`/apps/${appId}/api-tokens`, {
379
+ method: 'POST',
380
+ body: JSON.stringify({ name }),
381
+ }),
382
+ renameApiKey: (appId, id, name) =>
383
+ call(`/apps/${appId}/api-tokens/${id}/rename`, {
384
+ method: 'POST',
385
+ body: JSON.stringify({ name }),
386
+ }),
387
+ deleteApiKey: (appId, id) =>
388
+ call<void>(`/apps/${appId}/api-tokens/${id}`, { method: 'DELETE' }),
389
+ };
390
+ }
@@ -0,0 +1 @@
1
+ export * from './types';
@@ -0,0 +1,173 @@
1
+ /**
2
+ * `AppStudioApi` — the callback bag a host app supplies to
3
+ * {@code <AppDesignDrawer :api="...">}. The drawer's built-in panels
4
+ * ({@code LogAnnotationPanel}, {@code MonitorPanel}, …) call these functions
5
+ * for every backend I/O; the plugin never imports the host's HTTP client
6
+ * directly.
7
+ *
8
+ * <p>Rationale: keeps the plugin a self-contained npm package. A consumer
9
+ * just implements this interface once against their axios/fetch stack and
10
+ * every panel wires up — no more copying panel implementations around.</p>
11
+ *
12
+ * <p>Every method returns a {@link Promise}; the plugin awaits and handles
13
+ * loading / error UI centrally. A missing implementation (e.g. no annotation
14
+ * backend yet) can just resolve to an empty array — the panel degrades to an
15
+ * empty-state placeholder, no crash.</p>
16
+ */
17
+
18
+ // ---------------------------------------------------------------------------
19
+ // Domain types — mirrors the shapes the plugin panels need to render. Kept
20
+ // intentionally minimal so a host adapting to a different backend only has
21
+ // to supply these fields.
22
+ // ---------------------------------------------------------------------------
23
+
24
+ /** A single row in a chat conversation history. */
25
+ export interface StudioHistoryMessage {
26
+ role: 'ASSISTANT' | 'SYSTEM' | 'USER';
27
+ content: string;
28
+ createdAt?: string;
29
+ }
30
+
31
+ /** One row in the "对话" tab table. */
32
+ export interface StudioConversationSummary {
33
+ conversationId: string;
34
+ /**
35
+ * 会话所有者标识。后端来自 conversations.from_end_user_id(用户侧终端 id)
36
+ * 或 from_account_id(控制台账号);两者皆无为 null,UI 展示为 "—"。
37
+ */
38
+ userId?: null | string;
39
+ firstMessage?: string;
40
+ updatedAt?: string;
41
+ messageCount?: number;
42
+ }
43
+
44
+ /** A saved QA-pair annotation (Dify's 标注回复). */
45
+ export interface StudioAnnotation {
46
+ id: string;
47
+ appId?: string;
48
+ question?: string;
49
+ content?: string;
50
+ enabled?: boolean;
51
+ hitCount?: number;
52
+ createdAt?: string;
53
+ updatedAt?: string;
54
+ }
55
+
56
+ /** Payload for create/update annotation. */
57
+ export interface StudioAnnotationRequest {
58
+ question: string;
59
+ content: string;
60
+ enabled?: boolean;
61
+ }
62
+
63
+ /** Per-app conversation/message metrics powering the "监测" tab tiles. */
64
+ export interface StudioAppMetrics {
65
+ appId: string;
66
+ totalConversations: number;
67
+ totalMessages: number;
68
+ userMessages?: number;
69
+ assistantMessages?: number;
70
+ avgInteractionsPerConversation: number;
71
+ lastActivityAt?: string;
72
+ }
73
+
74
+ /** Rolled-up LLM usage. */
75
+ export interface StudioLlmUsageStats {
76
+ calls: number;
77
+ errors: number;
78
+ promptTokens: number;
79
+ completionTokens: number;
80
+ totalTokens: number;
81
+ costMicros: number;
82
+ avgLatencyMs: number;
83
+ }
84
+
85
+ /** A single LLM call record in the recent-calls table. */
86
+ export interface StudioLlmCallRecord {
87
+ id: string;
88
+ provider?: string;
89
+ model?: string;
90
+ promptTokens?: number;
91
+ completionTokens?: number;
92
+ totalTokens?: number;
93
+ costMicros?: number;
94
+ latencyMs?: number;
95
+ success?: boolean;
96
+ createdAt?: string;
97
+ }
98
+
99
+ /**
100
+ * One row in the "API 密钥" table under the 访问 API tab. Matches the shape
101
+ * exposed by the backend {@code /api/agent-start/apps/{appId}/api-tokens} endpoints —
102
+ * the full token value is included so the frontend can render both the masked
103
+ * preview (`app...xxxx`) and a one-shot "已复制" toast on create.
104
+ */
105
+ export interface StudioApiKey {
106
+ id: string;
107
+ appId?: string;
108
+ name?: string;
109
+ /** {@code app} / {@code dataset} — narrow it later if we support dataset keys. */
110
+ type?: string;
111
+ /** Full opaque token value (e.g. {@code app-xyz...}). Sensitive. */
112
+ token: string;
113
+ createdAt?: string;
114
+ lastUsedAt?: string;
115
+ }
116
+
117
+ // ---------------------------------------------------------------------------
118
+ // The callback bag itself.
119
+ // ---------------------------------------------------------------------------
120
+
121
+ /**
122
+ * Every field is optional so a host can wire only the panels they need. A
123
+ * panel whose API method is missing renders as read-only / empty.
124
+ */
125
+ export interface AppStudioApi {
126
+ // ── Conversation history / logs tab ────────────────────────────────────
127
+ listConversations?: (appId: string, limit?: number) => Promise<StudioConversationSummary[]>;
128
+ fetchHistory?: (
129
+ appId: string,
130
+ conversationId: string,
131
+ limit?: number,
132
+ ) => Promise<StudioHistoryMessage[]>;
133
+
134
+ // ── Annotation tab ─────────────────────────────────────────────────────
135
+ listAnnotations?: (appId: string) => Promise<StudioAnnotation[]>;
136
+ createAnnotation?: (
137
+ appId: string,
138
+ req: StudioAnnotationRequest,
139
+ ) => Promise<StudioAnnotation>;
140
+ updateAnnotation?: (
141
+ appId: string,
142
+ id: string,
143
+ req: StudioAnnotationRequest,
144
+ ) => Promise<StudioAnnotation>;
145
+ deleteAnnotation?: (appId: string, id: string) => Promise<void>;
146
+
147
+ // ── Monitor tab ────────────────────────────────────────────────────────
148
+ fetchAppMetrics?: (appId: string) => Promise<StudioAppMetrics>;
149
+ fetchLlmUsage?: () => Promise<StudioLlmUsageStats>;
150
+ fetchRecentLlmCalls?: (limit?: number) => Promise<StudioLlmCallRecord[]>;
151
+
152
+ // ── 访问 API tab — API-key management ─────────────────────────────────
153
+ /**
154
+ * List every API key attached to {@code appId}. Called on tab open. Returns
155
+ * an empty array when the host hasn't wired the endpoint yet — the manager
156
+ * degrades to the "尚未生成" empty state.
157
+ */
158
+ listApiKeys?: (appId: string) => Promise<StudioApiKey[]>;
159
+ /**
160
+ * Mint a new key. The response is expected to include the full token value
161
+ * so the UI can show it — subsequent list calls also include the value
162
+ * (this is an internal console, matching Dify's UX).
163
+ */
164
+ createApiKey?: (appId: string, name?: string) => Promise<StudioApiKey>;
165
+ /** Rename an existing key. Optional — the manager hides the rename button when absent. */
166
+ renameApiKey?: (
167
+ appId: string,
168
+ id: string,
169
+ name: string,
170
+ ) => Promise<StudioApiKey>;
171
+ /** Delete a key permanently. */
172
+ deleteApiKey?: (appId: string, id: string) => Promise<void>;
173
+ }