@stack-spot/portal-network 0.183.0 → 0.184.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 (136) hide show
  1. package/CHANGELOG.md +2412 -2405
  2. package/dist/api/account.js +1 -1
  3. package/dist/api/agent-tools.js +1 -1
  4. package/dist/api/agent.js +1 -1
  5. package/dist/api/ai.js +1 -1
  6. package/dist/api/apiManagement.js +1 -1
  7. package/dist/api/apiRuntime.js +1 -1
  8. package/dist/api/cloudAccount.js +1 -1
  9. package/dist/api/cloudPlatform.js +1 -1
  10. package/dist/api/cloudPlatformHorizon.js +1 -1
  11. package/dist/api/cloudRuntimes.js +1 -1
  12. package/dist/api/cloudServices.js +1 -1
  13. package/dist/api/codeShift.js +1 -1
  14. package/dist/api/content.js +1 -1
  15. package/dist/api/dataIntegration.js +1 -1
  16. package/dist/api/discover.js +1 -1
  17. package/dist/api/genAiInference.js +1 -1
  18. package/dist/api/insights.js +1 -1
  19. package/dist/api/notification.js +1 -1
  20. package/dist/api/secrets.js +1 -1
  21. package/dist/api/serviceCatalog.js +1 -1
  22. package/dist/api/workspace-ai.js +1 -1
  23. package/dist/api/workspace.js +1 -1
  24. package/dist/api/workspaceManager.d.ts +16 -10
  25. package/dist/api/workspaceManager.d.ts.map +1 -1
  26. package/dist/api/workspaceManager.js +11 -1
  27. package/dist/api/workspaceManager.js.map +1 -1
  28. package/dist/api/workspaceSearchEngine.js +1 -1
  29. package/dist/client/workspace-manager.d.ts +6 -0
  30. package/dist/client/workspace-manager.d.ts.map +1 -1
  31. package/dist/client/workspace-manager.js +10 -1
  32. package/dist/client/workspace-manager.js.map +1 -1
  33. package/package.json +6 -6
  34. package/scripts/generate-apis.ts +134 -134
  35. package/src/api/account.ts +8367 -8367
  36. package/src/api/agent-tools.ts +2169 -2169
  37. package/src/api/agent.ts +1083 -1083
  38. package/src/api/ai.ts +3388 -3388
  39. package/src/api/apiManagement.ts +570 -570
  40. package/src/api/apiRuntime.ts +2103 -2103
  41. package/src/api/cloudAccount.ts +1239 -1239
  42. package/src/api/cloudPlatform.ts +927 -927
  43. package/src/api/cloudPlatformHorizon.ts +2655 -2655
  44. package/src/api/cloudRuntimes.ts +2043 -2043
  45. package/src/api/cloudServices.ts +1445 -1445
  46. package/src/api/codeShift.ts +3481 -3481
  47. package/src/api/content.ts +9785 -9785
  48. package/src/api/dataIntegration.ts +1657 -1657
  49. package/src/api/discover.ts +435 -435
  50. package/src/api/eventBus.ts +171 -171
  51. package/src/api/genAiInference.ts +603 -603
  52. package/src/api/insights.ts +310 -310
  53. package/src/api/notification.ts +334 -334
  54. package/src/api/secrets.ts +342 -342
  55. package/src/api/serviceCatalog.ts +2908 -2908
  56. package/src/api/workflows.ts +1669 -1669
  57. package/src/api/workspace-ai.ts +677 -677
  58. package/src/api/workspace.ts +5889 -5889
  59. package/src/api/workspaceManager.ts +2951 -2936
  60. package/src/api/workspaceSearchEngine.ts +153 -153
  61. package/src/api-addresses.ts +120 -120
  62. package/src/apis-itau.json +225 -225
  63. package/src/apis.json +225 -225
  64. package/src/client/account.ts +902 -902
  65. package/src/client/agent-tools.ts +210 -210
  66. package/src/client/agent.ts +81 -81
  67. package/src/client/ai.ts +395 -395
  68. package/src/client/api-management.ts +40 -40
  69. package/src/client/cloud-account.ts +70 -70
  70. package/src/client/cloud-platform-horizon.ts +113 -113
  71. package/src/client/cloud-platform.ts +163 -163
  72. package/src/client/cloud-runtimes.ts +129 -129
  73. package/src/client/cloud-services.ts +94 -94
  74. package/src/client/code-shift.ts +349 -349
  75. package/src/client/content.ts +538 -538
  76. package/src/client/data-integration.ts +191 -191
  77. package/src/client/discover.ts +89 -89
  78. package/src/client/event-bus.ts +84 -84
  79. package/src/client/gen-ai-inference.ts +65 -65
  80. package/src/client/insights.ts +28 -28
  81. package/src/client/notification.ts +32 -32
  82. package/src/client/runtime-manager.ts +76 -76
  83. package/src/client/secrets.ts +60 -60
  84. package/src/client/types.ts +377 -377
  85. package/src/client/workflow.ts +83 -83
  86. package/src/client/workspace-ai.ts +191 -191
  87. package/src/client/workspace-manager.ts +564 -560
  88. package/src/client/workspace-search.ts +39 -39
  89. package/src/client/workspace.ts +480 -480
  90. package/src/error/DefaultAPIError.ts +151 -151
  91. package/src/error/FileUploadError.ts +18 -18
  92. package/src/error/IgnoredErrorCodes.ts +3 -3
  93. package/src/error/StackspotAPIError.ts +101 -101
  94. package/src/error/StreamCanceledError.ts +10 -10
  95. package/src/error/StreamError.ts +7 -7
  96. package/src/error/StreamJsonError.ts +10 -10
  97. package/src/error/dictionary/account.ts +58 -58
  98. package/src/error/dictionary/action-details.ts +20 -20
  99. package/src/error/dictionary/action.ts +211 -211
  100. package/src/error/dictionary/agent-tools.ts +75 -75
  101. package/src/error/dictionary/ai-inference.ts +28 -28
  102. package/src/error/dictionary/base.ts +22 -22
  103. package/src/error/dictionary/cloud-platform.ts +82 -82
  104. package/src/error/dictionary/cnt-fields.ts +14 -14
  105. package/src/error/dictionary/cnt.ts +103 -103
  106. package/src/error/dictionary/code-shift.ts +12 -12
  107. package/src/error/dictionary/rte.ts +24 -24
  108. package/src/error/dictionary/rtm.ts +10 -10
  109. package/src/error/dictionary/secrets.ts +14 -14
  110. package/src/error/dictionary/workspace-ai.ts +10 -10
  111. package/src/error/dictionary/workspace-details.ts +15 -15
  112. package/src/error/dictionary/workspace-fields.ts +10 -10
  113. package/src/error/dictionary/workspace.ts +209 -209
  114. package/src/error/types.ts +21 -21
  115. package/src/index.ts +43 -43
  116. package/src/network/AutoInfiniteQuery.ts +115 -115
  117. package/src/network/AutoMutation.ts +27 -27
  118. package/src/network/AutoOperation.ts +73 -73
  119. package/src/network/AutoQuery.ts +75 -75
  120. package/src/network/ManualInfiniteQuery.ts +95 -95
  121. package/src/network/ManualMutation.ts +40 -40
  122. package/src/network/ManualOperation.ts +52 -52
  123. package/src/network/ManualQuery.ts +82 -82
  124. package/src/network/NetworkClient.ts +167 -167
  125. package/src/network/ReactQueryNetworkClient.ts +312 -312
  126. package/src/network/react-query-client.ts +14 -14
  127. package/src/network/types.ts +294 -294
  128. package/src/types.ts +1 -1
  129. package/src/utils/StreamedArray.tsx +146 -146
  130. package/src/utils/StreamedJson.tsx +166 -166
  131. package/src/utils/remove-authorization-param.ts +6 -6
  132. package/src/utils/string.ts +19 -19
  133. package/src/utils/use-extended-list.ts +80 -80
  134. package/src/utils/use-streamed-array.ts +17 -17
  135. package/tsconfig.build.json +4 -4
  136. package/tsconfig.json +10 -10
package/src/client/ai.ts CHANGED
@@ -1,395 +1,395 @@
1
- import { HttpError } from '@oazapfts/runtime'
2
- import { findLast, isArray, last } from 'lodash'
3
- import { getApiAddresses } from '../api-addresses'
4
- import {
5
- addFavoriteV1AiStacksStackIdFavoritePost,
6
- addFavoriteV1QuickCommandsSlugFavoritePost,
7
- calculateNextStepV1QuickCommandsSlugStepsStepSlugCalculateNextStepPost,
8
- callbackV1QuickCommandsCallbackExecutionIdGet,
9
- conversationHistoryV1ConversationsConversationIdGet,
10
- createExecutionV1QuickCommandsCreateExecutionSlugPost,
11
- currentV1TokensUsageCurrentGet,
12
- currentV1TokensUsageTotalGet,
13
- defaults,
14
- deleteConversationV1ConversationsConversationIdDelete,
15
- deleteFavoriteV1AiStacksStackIdFavoriteDelete,
16
- deleteFavoriteV1QuickCommandsSlugFavoriteDelete,
17
- deleteKnowledgeObjectByCustomIdV1KnowledgeSourcesSlugObjectsCustomIdDelete,
18
- downloadConversationV1ConversationsConversationIdDownloadGet,
19
- findKnowledgeObjectByCustomIdV1KnowledgeSourcesSlugObjectsCustomIdGet,
20
- findKnowledgeSourceV1KnowledgeSourcesSlugGet,
21
- formatFetchStepV1QuickCommandsSlugStepsStepSlugFetchFormatPost,
22
- formatResultV1QuickCommandsSlugResultFormatPost,
23
- getContentDependenciesV1ContentContentTypeContentIdDependenciesGet,
24
- getQuickCommandV1QuickCommandsSlugGet,
25
- getUploadFormV1FileUploadFormPost,
26
- HttpValidationError,
27
- listAiStacksV1AiStacksGet,
28
- listAllV1QuickCommandsAllGet,
29
- listAllV2QuickCommandsAllGet,
30
- listAssociationV1WorkspaceWorkspaceIdGet,
31
- listConversationsV1ConversationsGet,
32
- listKnowledgeSourcesV1KnowledgeSourcesGet,
33
- postEventV1EventsPost,
34
- quickActionsV1QuickActionsPost,
35
- QuickCommandPromptResponse2,
36
- QuickCommandsExecutionRequest,
37
- quickCommandsRunV2V2QuickCommandsSlugStepsStepSlugRunPost,
38
- resetKnowledgeObjectsV1KnowledgeSourcesSlugObjectsDelete,
39
- runFetchStepV1QuickCommandsSlugStepsStepSlugFetchRunPost,
40
- searchKnowledgeSourcesV1KnowledgeSourcesSearchPost,
41
- updateQuickCommandV1QuickCommandsSlugPatch,
42
- updateTitleV1ConversationsConversationIdPatch,
43
- vectorizeCustomKnowledgeSourceV1KnowledgeSourcesSlugCustomPost,
44
- } from '../api/ai'
45
- import { StackspotAPIError } from '../error/StackspotAPIError'
46
- import { ReactQueryNetworkClient } from '../network/ReactQueryNetworkClient'
47
- import { removeAuthorizationParam } from '../utils/remove-authorization-param'
48
- import { StreamedJson } from '../utils/StreamedJson'
49
- import { formatJson } from '../utils/string'
50
- import { agentToolsClient } from './agent-tools'
51
- import {
52
- ChatAgentTool,
53
- ChatResponseWithSteps,
54
- FixedChatRequest,
55
- FixedChatResponse,
56
- FixedConversationResponse,
57
- FixedDependencyResponse,
58
- ReplaceResult,
59
- StepChatStep,
60
- } from './types'
61
-
62
- class AIClient extends ReactQueryNetworkClient {
63
- constructor() {
64
- super(getApiAddresses().ai.url, defaults)
65
- }
66
-
67
- protected buildStackSpotError(error: HttpError): StackspotAPIError {
68
- // @ts-ignore API documentation is wrong
69
- const details = (error.data as HttpValidationError | undefined)?.details
70
- return new StackspotAPIError({
71
- status: error.status,
72
- headers: error.headers,
73
- stack: error.stack,
74
- message: isArray(details) ? details?.map(d => d.msg)?.join('\n') : details,
75
- })
76
- }
77
-
78
- /**
79
- * Chat: runs a quick action.
80
- */
81
- runQuickAction = this.mutation(removeAuthorizationParam(quickActionsV1QuickActionsPost))
82
- /**
83
- * Deletes a KO from a KS
84
- */
85
- deleteKnowledgeObjectFromKs = this.mutation(
86
- removeAuthorizationParam(deleteKnowledgeObjectByCustomIdV1KnowledgeSourcesSlugObjectsCustomIdDelete))
87
- /**
88
- * Deletes a KO by standalone (reset Knowledge Objects)
89
- */
90
- deleteKnowledgeObjectsByStandalone = this.mutation(
91
- removeAuthorizationParam(resetKnowledgeObjectsV1KnowledgeSourcesSlugObjectsDelete))
92
- /**
93
- * Uploads a KO file
94
- */
95
- fileUploadFormKnowledgeObject = this.mutation(
96
- removeAuthorizationParam(getUploadFormV1FileUploadFormPost))
97
- /**
98
- * Creates a custom KO (Vectorize)
99
- */
100
- vectorizeCustomKS = this.mutation(
101
- removeAuthorizationParam(vectorizeCustomKnowledgeSourceV1KnowledgeSourcesSlugCustomPost))
102
- /**
103
- * Lists the AI Stacks according to their visibilities.
104
- */
105
- aiStacks = this.query(removeAuthorizationParam(listAiStacksV1AiStacksGet))
106
- /**
107
- * Gets total tokens usage
108
- */
109
- totalTokensUsage = this.query(removeAuthorizationParam(currentV1TokensUsageTotalGet))
110
- /**
111
- * Gets current tokens usage
112
- */
113
- currentTokensUsage = this.query(removeAuthorizationParam(currentV1TokensUsageCurrentGet))
114
- /**
115
- * Gets a workspace by its id.
116
- */
117
- workspace = this.query(removeAuthorizationParam(listAssociationV1WorkspaceWorkspaceIdGet))
118
- /**
119
- * @deprecated
120
- * Lists the quick commands according to filters passed as parameter (QC with secrets will not be returned).
121
- */
122
- quickCommands = this.query(removeAuthorizationParam(listAllV1QuickCommandsAllGet))
123
- /**
124
- * Lists all the quick commands according to filters passed as parameter (including QC with secrets).
125
- */
126
- allQuickCommands = this.query(removeAuthorizationParam(listAllV2QuickCommandsAllGet))
127
- /**
128
- * Gets a quick command by its slug.
129
- */
130
- quickCommand = this.query(removeAuthorizationParam(getQuickCommandV1QuickCommandsSlugGet))
131
- /**
132
- * Creates a new execution for a quick command by its slug.
133
- */
134
- quickCommandCreateExecution = this.mutation(removeAuthorizationParam(createExecutionV1QuickCommandsCreateExecutionSlugPost))
135
- /**
136
- * Gets the execution status and result of a quick command by its execution ID.
137
- */
138
- quickCommandCallbackExecutionId = this.query(removeAuthorizationParam(callbackV1QuickCommandsCallbackExecutionIdGet))
139
- /**
140
- * Lists the knowledge sources according to filters passed as parameter.
141
- */
142
- knowledgeSources = this.query(removeAuthorizationParam(listKnowledgeSourcesV1KnowledgeSourcesGet))
143
- /**
144
- * Gets a knowledge source by its slug.
145
- */
146
- knowledgeSource = this.query(removeAuthorizationParam(findKnowledgeSourceV1KnowledgeSourcesSlugGet))
147
- /**
148
- * Gets a knowledge source document by the slug of the parent knowledge source and the document id.
149
- */
150
- knowledgeSourceDocument = this.query(removeAuthorizationParam(findKnowledgeObjectByCustomIdV1KnowledgeSourcesSlugObjectsCustomIdGet))
151
- /**
152
- * Lists knowledge sources matching the provided IDs.
153
- */
154
- searchKnowledgeSources = this.query(removeAuthorizationParam(searchKnowledgeSourcesV1KnowledgeSourcesSearchPost))
155
- /**
156
- * Gets the chat history. This is a paginated resource.
157
- */
158
- chats = this.infiniteQuery(removeAuthorizationParam(listConversationsV1ConversationsGet))
159
- /**
160
- * Gets a specific chat from the history according to its id.
161
- */
162
- chat = this.query(removeAuthorizationParam(
163
- conversationHistoryV1ConversationsConversationIdGet as ReplaceResult<
164
- typeof conversationHistoryV1ConversationsConversationIdGet,
165
- FixedConversationResponse
166
- >,
167
- ))
168
- /**
169
- * Deletes a chat from the chat history.
170
- */
171
- deleteChat = this.mutation(removeAuthorizationParam(deleteConversationV1ConversationsConversationIdDelete))
172
- /**
173
- * Gets a plain text version of the chat with id passed as parameter.
174
- */
175
- downloadChat = this.mutation(removeAuthorizationParam(downloadConversationV1ConversationsConversationIdDownloadGet))
176
- /**
177
- * Renames a chat.
178
- */
179
- renameChat = this.mutation(removeAuthorizationParam(updateTitleV1ConversationsConversationIdPatch))
180
- /**
181
- * Creates an event so it can be used as metric by the product designers (analytics).
182
- */
183
- createEvent = this.mutation(removeAuthorizationParam(postEventV1EventsPost))
184
- /**
185
- * Runs a step of type "fetch" of a quick command.
186
- */
187
- fetchStepOfQuickCommand = this.mutation(removeAuthorizationParam(formatFetchStepV1QuickCommandsSlugStepsStepSlugFetchFormatPost))
188
- /**
189
- * Remotely runs a step of type "fetch" of a quick command remotely (used when secrets are present).
190
- */
191
- fetchStepOfQuickCommandRemotely = this.mutation({
192
- name: 'fetchStepOfQuickCommandRemotely',
193
- request: (
194
- signal,
195
- variables: Omit<Parameters<typeof runFetchStepV1QuickCommandsSlugStepsStepSlugFetchRunPost>[0], 'authorization'> &
196
- { headers?: Record<string, any> },
197
- ) => {
198
- const { headers, ...props } = variables
199
- return runFetchStepV1QuickCommandsSlugStepsStepSlugFetchRunPost({ ...props, authorization: '' }, { signal, headers })
200
- },
201
- permission: this.createPermissionFunctionFor(runFetchStepV1QuickCommandsSlugStepsStepSlugFetchRunPost),
202
- })
203
-
204
- /**
205
- * @deprecated This method does not use stream, only json. The json support has been removed
206
- * So this method might not work as expected.
207
- * Runs a step of type "llm" of a quick command.
208
- */
209
- llmStepOfQuickCommand = this.mutation(removeAuthorizationParam(quickCommandsRunV2V2QuickCommandsSlugStepsStepSlugRunPost))
210
- /**
211
- * Calculates QC router next step.
212
- */
213
- calculateNextStep = this.mutation(removeAuthorizationParam(calculateNextStepV1QuickCommandsSlugStepsStepSlugCalculateNextStepPost))
214
- /**
215
- * Runs a stream of a step of type "llm" of a quick command.
216
- */
217
- streamLlmStepOfQuickCommand(slug: string, stepSlug: string, quickCommandsExecutionRequest: QuickCommandsExecutionRequest,
218
- minChangeIntervalMS?: number):
219
- StreamedJson<QuickCommandPromptResponse2> {
220
- const abortController = new AbortController()
221
- const headers = {
222
- 'Content-Type': 'application/json',
223
- 'Accept': 'text/event-stream',
224
- }
225
- const events = this.stream(
226
- this.resolveURL(`/v2/quick-commands/${slug}/steps/${stepSlug}/run`),
227
- { method: 'post', body: JSON.stringify(quickCommandsExecutionRequest), headers, signal: abortController.signal },
228
- )
229
-
230
- return new StreamedJson({
231
- eventsPromise: events,
232
- abortController,
233
- minChangeIntervalMS,
234
- })
235
- }
236
- /**
237
- * Formats the result of a quick command into a human-readable text (markdown).
238
- */
239
- formatResultOfQuickCommand = this.mutation(removeAuthorizationParam(formatResultV1QuickCommandsSlugResultFormatPost))
240
- /**
241
- * Adds the resource of type Stack AI to the list of favorites.
242
- */
243
- addFavoriteStackAi = this.mutation(removeAuthorizationParam(addFavoriteV1AiStacksStackIdFavoritePost))
244
- /**
245
- * Removes the resource of type Stack AI from the list of favorites.
246
- */
247
- removeFavoriteStackAi = this.mutation(removeAuthorizationParam(deleteFavoriteV1AiStacksStackIdFavoriteDelete))
248
- /**
249
- * Updates a Quick Command
250
- */
251
- updateQuickCommand = this.mutation(removeAuthorizationParam(updateQuickCommandV1QuickCommandsSlugPatch))
252
- /**
253
- * Adds the resource of type Quick Command to the list of favorites.
254
- */
255
- addFavoriteQuickCommand = this.mutation(removeAuthorizationParam(addFavoriteV1QuickCommandsSlugFavoritePost))
256
- /**
257
- * Removes the resource of type Quick Command from the list of favorites.
258
- */
259
- removeFavoriteQuickCommand = this.mutation(removeAuthorizationParam(deleteFavoriteV1QuickCommandsSlugFavoriteDelete))
260
-
261
- private static async toolsOfAgent(agentId?: string) {
262
- try {
263
- const agent = agentId ? await agentToolsClient.agent.query({ agentId }) : undefined
264
- if (!agent) return []
265
- const tools: (Omit<ChatAgentTool, 'duration' | 'prompt' | 'output'>)[] = []
266
- agent.toolkits?.builtin_toolkits?.forEach(kit => kit.tools?.forEach(({ id, name, description }) => {
267
- if (id) tools.push({ image: kit.image_url, id, name: name || id, description })
268
- }))
269
- return tools
270
- } catch {
271
- return []
272
- }
273
- }
274
-
275
- sendChatMessage(request: FixedChatRequest, minChangeIntervalMS?: number): StreamedJson<ChatResponseWithSteps> {
276
- const abortController = new AbortController()
277
- const headers = {
278
- 'Content-Type': 'application/json',
279
- 'Accept': 'text/event-stream',
280
- }
281
- const events = this.stream(
282
- this.resolveURL('v3/chat'),
283
- { method: 'post', body: JSON.stringify(request), headers, signal: abortController.signal },
284
- )
285
-
286
- /**
287
- * This function treats events in the streaming that deals with the execution of tools. Since these events are not concatenated like
288
- * normal streamings of data, we need this separate function to deal with them. It transforms the internal data model of the
289
- * StreamedJson object whenever an event is triggered.
290
- */
291
- async function transform(event: Partial<FixedChatResponse>, data: Partial<ChatResponseWithSteps>) {
292
- const info = event.agent_info
293
- if (!info) return
294
- const tools = await AIClient.toolsOfAgent(request.context?.agent_id)
295
- data.steps = data.steps ? [...data.steps] : []
296
-
297
- if (info.type === 'planning' && info.action === 'end') {
298
- data.steps.push({
299
- id: 'planning',
300
- type: 'planning',
301
- status: 'success',
302
- duration: info.duration || 0,
303
- steps: info.data?.steps?.map(s => s.goal) ?? [],
304
- goal: info.data?.plan_goal ?? '',
305
- })
306
- info.data?.steps.forEach(s => data.steps?.push({
307
- id: s.id,
308
- type: 'step',
309
- status: 'pending',
310
- input: s.goal,
311
- attempts: [{
312
- tools: s.tools?.map(t => ({
313
- ...(tools.find(({ id }) => id === t.tool_id) ?? { id: t.tool_id, name: t.tool_id }),
314
- executionId: t.tool_execution_id,
315
- })),
316
- }],
317
- }))
318
- data.steps.push({ id: 'answer', type: 'answer', status: 'pending' })
319
- }
320
-
321
- if (info.type === 'step' && info.action === 'start') {
322
- const step = data.steps.find(s => s.id === info.id)
323
- if (step) step.status = 'running'
324
- }
325
-
326
- if (info.type === 'step' && info.action === 'end') {
327
- const step = data.steps.find(s => s.id === info.id) as StepChatStep
328
- if (step) {
329
- step.status = 'success'
330
- step.duration = info.duration
331
- const lastToolId = last(step.attempts[0].tools)?.id
332
- const lastAttemptOfLastTool = findLast(step.attempts.map(a => a.tools).flat(), t => t?.id === lastToolId)
333
- step.output = lastAttemptOfLastTool?.output
334
- }
335
- }
336
-
337
- if (info.type === 'tool' && info.action === 'start') {
338
- const currentStep = data.steps.find(s => s.status === 'running') as StepChatStep
339
- if (!currentStep || !info.data || !currentStep.attempts[0].tools) return
340
- const toolInFirstAttempt = currentStep.attempts[0].tools.find(t => t.executionId === info.id)
341
- if (!toolInFirstAttempt) return
342
- const input = formatJson(info.data.input)
343
- if (info.data.attempt === 0) {
344
- toolInFirstAttempt.input = input
345
- } else {
346
- currentStep.attempts[info.data.attempt] ??= { tools: [] }
347
- currentStep.attempts[info.data.attempt].tools?.push({
348
- ...toolInFirstAttempt,
349
- input,
350
- })
351
- }
352
- }
353
-
354
- if (info.type === 'tool' && info.action === 'end') {
355
- const currentStep = data.steps.find(s => s.status === 'running') as StepChatStep
356
- if (!currentStep || !info.data) return
357
- const tool = currentStep.attempts[info.data.attempt]?.tools?.find(t => t.executionId === info.id)
358
- if (tool) {
359
- tool.output = formatJson(info.data.output)
360
- tool.duration = info.duration
361
- }
362
- }
363
-
364
- if (info.type === 'final_answer' && info.action === 'start') {
365
- const answerStep = last(data.steps)
366
- if (answerStep) answerStep.status = 'running'
367
- }
368
-
369
- if (info.type === 'final_answer' && info.action === 'end') {
370
- const answerStep = last(data.steps)
371
- if (answerStep) {
372
- answerStep.status = 'success'
373
- answerStep.duration = info.duration
374
- }
375
- }
376
- }
377
-
378
- return new StreamedJson({
379
- eventsPromise: events,
380
- abortController,
381
- minChangeIntervalMS,
382
- ignoreKeys: ['agent_info'],
383
- transform,
384
- })
385
- }
386
-
387
- contentDependencies = this.query(removeAuthorizationParam(
388
- getContentDependenciesV1ContentContentTypeContentIdDependenciesGet as ReplaceResult<
389
- typeof getContentDependenciesV1ContentContentTypeContentIdDependenciesGet,
390
- FixedDependencyResponse
391
- >,
392
- ))
393
- }
394
-
395
- export const aiClient = new AIClient()
1
+ import { HttpError } from '@oazapfts/runtime'
2
+ import { findLast, isArray, last } from 'lodash'
3
+ import { getApiAddresses } from '../api-addresses'
4
+ import {
5
+ addFavoriteV1AiStacksStackIdFavoritePost,
6
+ addFavoriteV1QuickCommandsSlugFavoritePost,
7
+ calculateNextStepV1QuickCommandsSlugStepsStepSlugCalculateNextStepPost,
8
+ callbackV1QuickCommandsCallbackExecutionIdGet,
9
+ conversationHistoryV1ConversationsConversationIdGet,
10
+ createExecutionV1QuickCommandsCreateExecutionSlugPost,
11
+ currentV1TokensUsageCurrentGet,
12
+ currentV1TokensUsageTotalGet,
13
+ defaults,
14
+ deleteConversationV1ConversationsConversationIdDelete,
15
+ deleteFavoriteV1AiStacksStackIdFavoriteDelete,
16
+ deleteFavoriteV1QuickCommandsSlugFavoriteDelete,
17
+ deleteKnowledgeObjectByCustomIdV1KnowledgeSourcesSlugObjectsCustomIdDelete,
18
+ downloadConversationV1ConversationsConversationIdDownloadGet,
19
+ findKnowledgeObjectByCustomIdV1KnowledgeSourcesSlugObjectsCustomIdGet,
20
+ findKnowledgeSourceV1KnowledgeSourcesSlugGet,
21
+ formatFetchStepV1QuickCommandsSlugStepsStepSlugFetchFormatPost,
22
+ formatResultV1QuickCommandsSlugResultFormatPost,
23
+ getContentDependenciesV1ContentContentTypeContentIdDependenciesGet,
24
+ getQuickCommandV1QuickCommandsSlugGet,
25
+ getUploadFormV1FileUploadFormPost,
26
+ HttpValidationError,
27
+ listAiStacksV1AiStacksGet,
28
+ listAllV1QuickCommandsAllGet,
29
+ listAllV2QuickCommandsAllGet,
30
+ listAssociationV1WorkspaceWorkspaceIdGet,
31
+ listConversationsV1ConversationsGet,
32
+ listKnowledgeSourcesV1KnowledgeSourcesGet,
33
+ postEventV1EventsPost,
34
+ quickActionsV1QuickActionsPost,
35
+ QuickCommandPromptResponse2,
36
+ QuickCommandsExecutionRequest,
37
+ quickCommandsRunV2V2QuickCommandsSlugStepsStepSlugRunPost,
38
+ resetKnowledgeObjectsV1KnowledgeSourcesSlugObjectsDelete,
39
+ runFetchStepV1QuickCommandsSlugStepsStepSlugFetchRunPost,
40
+ searchKnowledgeSourcesV1KnowledgeSourcesSearchPost,
41
+ updateQuickCommandV1QuickCommandsSlugPatch,
42
+ updateTitleV1ConversationsConversationIdPatch,
43
+ vectorizeCustomKnowledgeSourceV1KnowledgeSourcesSlugCustomPost,
44
+ } from '../api/ai'
45
+ import { StackspotAPIError } from '../error/StackspotAPIError'
46
+ import { ReactQueryNetworkClient } from '../network/ReactQueryNetworkClient'
47
+ import { removeAuthorizationParam } from '../utils/remove-authorization-param'
48
+ import { StreamedJson } from '../utils/StreamedJson'
49
+ import { formatJson } from '../utils/string'
50
+ import { agentToolsClient } from './agent-tools'
51
+ import {
52
+ ChatAgentTool,
53
+ ChatResponseWithSteps,
54
+ FixedChatRequest,
55
+ FixedChatResponse,
56
+ FixedConversationResponse,
57
+ FixedDependencyResponse,
58
+ ReplaceResult,
59
+ StepChatStep,
60
+ } from './types'
61
+
62
+ class AIClient extends ReactQueryNetworkClient {
63
+ constructor() {
64
+ super(getApiAddresses().ai.url, defaults)
65
+ }
66
+
67
+ protected buildStackSpotError(error: HttpError): StackspotAPIError {
68
+ // @ts-ignore API documentation is wrong
69
+ const details = (error.data as HttpValidationError | undefined)?.details
70
+ return new StackspotAPIError({
71
+ status: error.status,
72
+ headers: error.headers,
73
+ stack: error.stack,
74
+ message: isArray(details) ? details?.map(d => d.msg)?.join('\n') : details,
75
+ })
76
+ }
77
+
78
+ /**
79
+ * Chat: runs a quick action.
80
+ */
81
+ runQuickAction = this.mutation(removeAuthorizationParam(quickActionsV1QuickActionsPost))
82
+ /**
83
+ * Deletes a KO from a KS
84
+ */
85
+ deleteKnowledgeObjectFromKs = this.mutation(
86
+ removeAuthorizationParam(deleteKnowledgeObjectByCustomIdV1KnowledgeSourcesSlugObjectsCustomIdDelete))
87
+ /**
88
+ * Deletes a KO by standalone (reset Knowledge Objects)
89
+ */
90
+ deleteKnowledgeObjectsByStandalone = this.mutation(
91
+ removeAuthorizationParam(resetKnowledgeObjectsV1KnowledgeSourcesSlugObjectsDelete))
92
+ /**
93
+ * Uploads a KO file
94
+ */
95
+ fileUploadFormKnowledgeObject = this.mutation(
96
+ removeAuthorizationParam(getUploadFormV1FileUploadFormPost))
97
+ /**
98
+ * Creates a custom KO (Vectorize)
99
+ */
100
+ vectorizeCustomKS = this.mutation(
101
+ removeAuthorizationParam(vectorizeCustomKnowledgeSourceV1KnowledgeSourcesSlugCustomPost))
102
+ /**
103
+ * Lists the AI Stacks according to their visibilities.
104
+ */
105
+ aiStacks = this.query(removeAuthorizationParam(listAiStacksV1AiStacksGet))
106
+ /**
107
+ * Gets total tokens usage
108
+ */
109
+ totalTokensUsage = this.query(removeAuthorizationParam(currentV1TokensUsageTotalGet))
110
+ /**
111
+ * Gets current tokens usage
112
+ */
113
+ currentTokensUsage = this.query(removeAuthorizationParam(currentV1TokensUsageCurrentGet))
114
+ /**
115
+ * Gets a workspace by its id.
116
+ */
117
+ workspace = this.query(removeAuthorizationParam(listAssociationV1WorkspaceWorkspaceIdGet))
118
+ /**
119
+ * @deprecated
120
+ * Lists the quick commands according to filters passed as parameter (QC with secrets will not be returned).
121
+ */
122
+ quickCommands = this.query(removeAuthorizationParam(listAllV1QuickCommandsAllGet))
123
+ /**
124
+ * Lists all the quick commands according to filters passed as parameter (including QC with secrets).
125
+ */
126
+ allQuickCommands = this.query(removeAuthorizationParam(listAllV2QuickCommandsAllGet))
127
+ /**
128
+ * Gets a quick command by its slug.
129
+ */
130
+ quickCommand = this.query(removeAuthorizationParam(getQuickCommandV1QuickCommandsSlugGet))
131
+ /**
132
+ * Creates a new execution for a quick command by its slug.
133
+ */
134
+ quickCommandCreateExecution = this.mutation(removeAuthorizationParam(createExecutionV1QuickCommandsCreateExecutionSlugPost))
135
+ /**
136
+ * Gets the execution status and result of a quick command by its execution ID.
137
+ */
138
+ quickCommandCallbackExecutionId = this.query(removeAuthorizationParam(callbackV1QuickCommandsCallbackExecutionIdGet))
139
+ /**
140
+ * Lists the knowledge sources according to filters passed as parameter.
141
+ */
142
+ knowledgeSources = this.query(removeAuthorizationParam(listKnowledgeSourcesV1KnowledgeSourcesGet))
143
+ /**
144
+ * Gets a knowledge source by its slug.
145
+ */
146
+ knowledgeSource = this.query(removeAuthorizationParam(findKnowledgeSourceV1KnowledgeSourcesSlugGet))
147
+ /**
148
+ * Gets a knowledge source document by the slug of the parent knowledge source and the document id.
149
+ */
150
+ knowledgeSourceDocument = this.query(removeAuthorizationParam(findKnowledgeObjectByCustomIdV1KnowledgeSourcesSlugObjectsCustomIdGet))
151
+ /**
152
+ * Lists knowledge sources matching the provided IDs.
153
+ */
154
+ searchKnowledgeSources = this.query(removeAuthorizationParam(searchKnowledgeSourcesV1KnowledgeSourcesSearchPost))
155
+ /**
156
+ * Gets the chat history. This is a paginated resource.
157
+ */
158
+ chats = this.infiniteQuery(removeAuthorizationParam(listConversationsV1ConversationsGet))
159
+ /**
160
+ * Gets a specific chat from the history according to its id.
161
+ */
162
+ chat = this.query(removeAuthorizationParam(
163
+ conversationHistoryV1ConversationsConversationIdGet as ReplaceResult<
164
+ typeof conversationHistoryV1ConversationsConversationIdGet,
165
+ FixedConversationResponse
166
+ >,
167
+ ))
168
+ /**
169
+ * Deletes a chat from the chat history.
170
+ */
171
+ deleteChat = this.mutation(removeAuthorizationParam(deleteConversationV1ConversationsConversationIdDelete))
172
+ /**
173
+ * Gets a plain text version of the chat with id passed as parameter.
174
+ */
175
+ downloadChat = this.mutation(removeAuthorizationParam(downloadConversationV1ConversationsConversationIdDownloadGet))
176
+ /**
177
+ * Renames a chat.
178
+ */
179
+ renameChat = this.mutation(removeAuthorizationParam(updateTitleV1ConversationsConversationIdPatch))
180
+ /**
181
+ * Creates an event so it can be used as metric by the product designers (analytics).
182
+ */
183
+ createEvent = this.mutation(removeAuthorizationParam(postEventV1EventsPost))
184
+ /**
185
+ * Runs a step of type "fetch" of a quick command.
186
+ */
187
+ fetchStepOfQuickCommand = this.mutation(removeAuthorizationParam(formatFetchStepV1QuickCommandsSlugStepsStepSlugFetchFormatPost))
188
+ /**
189
+ * Remotely runs a step of type "fetch" of a quick command remotely (used when secrets are present).
190
+ */
191
+ fetchStepOfQuickCommandRemotely = this.mutation({
192
+ name: 'fetchStepOfQuickCommandRemotely',
193
+ request: (
194
+ signal,
195
+ variables: Omit<Parameters<typeof runFetchStepV1QuickCommandsSlugStepsStepSlugFetchRunPost>[0], 'authorization'> &
196
+ { headers?: Record<string, any> },
197
+ ) => {
198
+ const { headers, ...props } = variables
199
+ return runFetchStepV1QuickCommandsSlugStepsStepSlugFetchRunPost({ ...props, authorization: '' }, { signal, headers })
200
+ },
201
+ permission: this.createPermissionFunctionFor(runFetchStepV1QuickCommandsSlugStepsStepSlugFetchRunPost),
202
+ })
203
+
204
+ /**
205
+ * @deprecated This method does not use stream, only json. The json support has been removed
206
+ * So this method might not work as expected.
207
+ * Runs a step of type "llm" of a quick command.
208
+ */
209
+ llmStepOfQuickCommand = this.mutation(removeAuthorizationParam(quickCommandsRunV2V2QuickCommandsSlugStepsStepSlugRunPost))
210
+ /**
211
+ * Calculates QC router next step.
212
+ */
213
+ calculateNextStep = this.mutation(removeAuthorizationParam(calculateNextStepV1QuickCommandsSlugStepsStepSlugCalculateNextStepPost))
214
+ /**
215
+ * Runs a stream of a step of type "llm" of a quick command.
216
+ */
217
+ streamLlmStepOfQuickCommand(slug: string, stepSlug: string, quickCommandsExecutionRequest: QuickCommandsExecutionRequest,
218
+ minChangeIntervalMS?: number):
219
+ StreamedJson<QuickCommandPromptResponse2> {
220
+ const abortController = new AbortController()
221
+ const headers = {
222
+ 'Content-Type': 'application/json',
223
+ 'Accept': 'text/event-stream',
224
+ }
225
+ const events = this.stream(
226
+ this.resolveURL(`/v2/quick-commands/${slug}/steps/${stepSlug}/run`),
227
+ { method: 'post', body: JSON.stringify(quickCommandsExecutionRequest), headers, signal: abortController.signal },
228
+ )
229
+
230
+ return new StreamedJson({
231
+ eventsPromise: events,
232
+ abortController,
233
+ minChangeIntervalMS,
234
+ })
235
+ }
236
+ /**
237
+ * Formats the result of a quick command into a human-readable text (markdown).
238
+ */
239
+ formatResultOfQuickCommand = this.mutation(removeAuthorizationParam(formatResultV1QuickCommandsSlugResultFormatPost))
240
+ /**
241
+ * Adds the resource of type Stack AI to the list of favorites.
242
+ */
243
+ addFavoriteStackAi = this.mutation(removeAuthorizationParam(addFavoriteV1AiStacksStackIdFavoritePost))
244
+ /**
245
+ * Removes the resource of type Stack AI from the list of favorites.
246
+ */
247
+ removeFavoriteStackAi = this.mutation(removeAuthorizationParam(deleteFavoriteV1AiStacksStackIdFavoriteDelete))
248
+ /**
249
+ * Updates a Quick Command
250
+ */
251
+ updateQuickCommand = this.mutation(removeAuthorizationParam(updateQuickCommandV1QuickCommandsSlugPatch))
252
+ /**
253
+ * Adds the resource of type Quick Command to the list of favorites.
254
+ */
255
+ addFavoriteQuickCommand = this.mutation(removeAuthorizationParam(addFavoriteV1QuickCommandsSlugFavoritePost))
256
+ /**
257
+ * Removes the resource of type Quick Command from the list of favorites.
258
+ */
259
+ removeFavoriteQuickCommand = this.mutation(removeAuthorizationParam(deleteFavoriteV1QuickCommandsSlugFavoriteDelete))
260
+
261
+ private static async toolsOfAgent(agentId?: string) {
262
+ try {
263
+ const agent = agentId ? await agentToolsClient.agent.query({ agentId }) : undefined
264
+ if (!agent) return []
265
+ const tools: (Omit<ChatAgentTool, 'duration' | 'prompt' | 'output'>)[] = []
266
+ agent.toolkits?.builtin_toolkits?.forEach(kit => kit.tools?.forEach(({ id, name, description }) => {
267
+ if (id) tools.push({ image: kit.image_url, id, name: name || id, description })
268
+ }))
269
+ return tools
270
+ } catch {
271
+ return []
272
+ }
273
+ }
274
+
275
+ sendChatMessage(request: FixedChatRequest, minChangeIntervalMS?: number): StreamedJson<ChatResponseWithSteps> {
276
+ const abortController = new AbortController()
277
+ const headers = {
278
+ 'Content-Type': 'application/json',
279
+ 'Accept': 'text/event-stream',
280
+ }
281
+ const events = this.stream(
282
+ this.resolveURL('v3/chat'),
283
+ { method: 'post', body: JSON.stringify(request), headers, signal: abortController.signal },
284
+ )
285
+
286
+ /**
287
+ * This function treats events in the streaming that deals with the execution of tools. Since these events are not concatenated like
288
+ * normal streamings of data, we need this separate function to deal with them. It transforms the internal data model of the
289
+ * StreamedJson object whenever an event is triggered.
290
+ */
291
+ async function transform(event: Partial<FixedChatResponse>, data: Partial<ChatResponseWithSteps>) {
292
+ const info = event.agent_info
293
+ if (!info) return
294
+ const tools = await AIClient.toolsOfAgent(request.context?.agent_id)
295
+ data.steps = data.steps ? [...data.steps] : []
296
+
297
+ if (info.type === 'planning' && info.action === 'end') {
298
+ data.steps.push({
299
+ id: 'planning',
300
+ type: 'planning',
301
+ status: 'success',
302
+ duration: info.duration || 0,
303
+ steps: info.data?.steps?.map(s => s.goal) ?? [],
304
+ goal: info.data?.plan_goal ?? '',
305
+ })
306
+ info.data?.steps.forEach(s => data.steps?.push({
307
+ id: s.id,
308
+ type: 'step',
309
+ status: 'pending',
310
+ input: s.goal,
311
+ attempts: [{
312
+ tools: s.tools?.map(t => ({
313
+ ...(tools.find(({ id }) => id === t.tool_id) ?? { id: t.tool_id, name: t.tool_id }),
314
+ executionId: t.tool_execution_id,
315
+ })),
316
+ }],
317
+ }))
318
+ data.steps.push({ id: 'answer', type: 'answer', status: 'pending' })
319
+ }
320
+
321
+ if (info.type === 'step' && info.action === 'start') {
322
+ const step = data.steps.find(s => s.id === info.id)
323
+ if (step) step.status = 'running'
324
+ }
325
+
326
+ if (info.type === 'step' && info.action === 'end') {
327
+ const step = data.steps.find(s => s.id === info.id) as StepChatStep
328
+ if (step) {
329
+ step.status = 'success'
330
+ step.duration = info.duration
331
+ const lastToolId = last(step.attempts[0].tools)?.id
332
+ const lastAttemptOfLastTool = findLast(step.attempts.map(a => a.tools).flat(), t => t?.id === lastToolId)
333
+ step.output = lastAttemptOfLastTool?.output
334
+ }
335
+ }
336
+
337
+ if (info.type === 'tool' && info.action === 'start') {
338
+ const currentStep = data.steps.find(s => s.status === 'running') as StepChatStep
339
+ if (!currentStep || !info.data || !currentStep.attempts[0].tools) return
340
+ const toolInFirstAttempt = currentStep.attempts[0].tools.find(t => t.executionId === info.id)
341
+ if (!toolInFirstAttempt) return
342
+ const input = formatJson(info.data.input)
343
+ if (info.data.attempt === 0) {
344
+ toolInFirstAttempt.input = input
345
+ } else {
346
+ currentStep.attempts[info.data.attempt] ??= { tools: [] }
347
+ currentStep.attempts[info.data.attempt].tools?.push({
348
+ ...toolInFirstAttempt,
349
+ input,
350
+ })
351
+ }
352
+ }
353
+
354
+ if (info.type === 'tool' && info.action === 'end') {
355
+ const currentStep = data.steps.find(s => s.status === 'running') as StepChatStep
356
+ if (!currentStep || !info.data) return
357
+ const tool = currentStep.attempts[info.data.attempt]?.tools?.find(t => t.executionId === info.id)
358
+ if (tool) {
359
+ tool.output = formatJson(info.data.output)
360
+ tool.duration = info.duration
361
+ }
362
+ }
363
+
364
+ if (info.type === 'final_answer' && info.action === 'start') {
365
+ const answerStep = last(data.steps)
366
+ if (answerStep) answerStep.status = 'running'
367
+ }
368
+
369
+ if (info.type === 'final_answer' && info.action === 'end') {
370
+ const answerStep = last(data.steps)
371
+ if (answerStep) {
372
+ answerStep.status = 'success'
373
+ answerStep.duration = info.duration
374
+ }
375
+ }
376
+ }
377
+
378
+ return new StreamedJson({
379
+ eventsPromise: events,
380
+ abortController,
381
+ minChangeIntervalMS,
382
+ ignoreKeys: ['agent_info'],
383
+ transform,
384
+ })
385
+ }
386
+
387
+ contentDependencies = this.query(removeAuthorizationParam(
388
+ getContentDependenciesV1ContentContentTypeContentIdDependenciesGet as ReplaceResult<
389
+ typeof getContentDependenciesV1ContentContentTypeContentIdDependenciesGet,
390
+ FixedDependencyResponse
391
+ >,
392
+ ))
393
+ }
394
+
395
+ export const aiClient = new AIClient()