@stack-spot/portal-network 0.184.0-beta.1 → 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 (151) hide show
  1. package/CHANGELOG.md +2412 -2431
  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.d.ts +4 -76
  14. package/dist/api/codeShift.d.ts.map +1 -1
  15. package/dist/api/codeShift.js +1 -14
  16. package/dist/api/codeShift.js.map +1 -1
  17. package/dist/api/content.js +1 -1
  18. package/dist/api/dataIntegration.js +1 -1
  19. package/dist/api/discover.js +1 -1
  20. package/dist/api/genAiInference.js +1 -1
  21. package/dist/api/insights.js +1 -1
  22. package/dist/api/notification.js +1 -1
  23. package/dist/api/secrets.js +1 -1
  24. package/dist/api/serviceCatalog.js +1 -1
  25. package/dist/api/workspace-ai.js +1 -1
  26. package/dist/api/workspace.js +1 -1
  27. package/dist/api/workspaceManager.d.ts +16 -10
  28. package/dist/api/workspaceManager.d.ts.map +1 -1
  29. package/dist/api/workspaceManager.js +11 -1
  30. package/dist/api/workspaceManager.js.map +1 -1
  31. package/dist/api/workspaceSearchEngine.js +1 -1
  32. package/dist/client/ai.d.ts.map +1 -1
  33. package/dist/client/ai.js +14 -84
  34. package/dist/client/ai.js.map +1 -1
  35. package/dist/client/code-shift.d.ts +0 -30
  36. package/dist/client/code-shift.d.ts.map +1 -1
  37. package/dist/client/code-shift.js +1 -37
  38. package/dist/client/code-shift.js.map +1 -1
  39. package/dist/client/types.d.ts +6 -26
  40. package/dist/client/types.d.ts.map +1 -1
  41. package/dist/client/workspace-manager.d.ts +6 -0
  42. package/dist/client/workspace-manager.d.ts.map +1 -1
  43. package/dist/client/workspace-manager.js +10 -1
  44. package/dist/client/workspace-manager.js.map +1 -1
  45. package/package.json +1 -1
  46. package/readme.md +1 -1
  47. package/scripts/generate-apis.ts +134 -134
  48. package/src/api/account.ts +8367 -8368
  49. package/src/api/agent-tools.ts +2169 -2172
  50. package/src/api/agent.ts +1083 -1085
  51. package/src/api/ai.ts +3388 -3388
  52. package/src/api/apiManagement.ts +570 -570
  53. package/src/api/apiRuntime.ts +2103 -2103
  54. package/src/api/cloudAccount.ts +1239 -1239
  55. package/src/api/cloudPlatform.ts +927 -927
  56. package/src/api/cloudPlatformHorizon.ts +2655 -2655
  57. package/src/api/cloudRuntimes.ts +2043 -2043
  58. package/src/api/cloudServices.ts +1445 -1445
  59. package/src/api/codeShift.ts +3481 -3580
  60. package/src/api/content.ts +9785 -9785
  61. package/src/api/dataIntegration.ts +1657 -1657
  62. package/src/api/discover.ts +435 -435
  63. package/src/api/eventBus.ts +171 -171
  64. package/src/api/genAiInference.ts +603 -603
  65. package/src/api/insights.ts +310 -310
  66. package/src/api/notification.ts +334 -336
  67. package/src/api/secrets.ts +342 -342
  68. package/src/api/serviceCatalog.ts +2908 -2908
  69. package/src/api/workflows.ts +1669 -1669
  70. package/src/api/workspace-ai.ts +677 -677
  71. package/src/api/workspace.ts +5889 -5889
  72. package/src/api/workspaceManager.ts +2951 -2936
  73. package/src/api/workspaceSearchEngine.ts +153 -153
  74. package/src/api-addresses.ts +120 -120
  75. package/src/apis-itau.json +225 -225
  76. package/src/apis.json +225 -225
  77. package/src/client/account.ts +902 -902
  78. package/src/client/agent-tools.ts +210 -210
  79. package/src/client/agent.ts +81 -81
  80. package/src/client/ai.ts +395 -469
  81. package/src/client/api-management.ts +40 -40
  82. package/src/client/cloud-account.ts +70 -70
  83. package/src/client/cloud-platform-horizon.ts +113 -113
  84. package/src/client/cloud-platform.ts +163 -163
  85. package/src/client/cloud-runtimes.ts +129 -129
  86. package/src/client/cloud-services.ts +94 -94
  87. package/src/client/code-shift.ts +349 -371
  88. package/src/client/content.ts +538 -538
  89. package/src/client/data-integration.ts +191 -191
  90. package/src/client/discover.ts +89 -89
  91. package/src/client/event-bus.ts +84 -84
  92. package/src/client/gen-ai-inference.ts +65 -65
  93. package/src/client/insights.ts +28 -28
  94. package/src/client/notification.ts +32 -32
  95. package/src/client/runtime-manager.ts +76 -76
  96. package/src/client/secrets.ts +60 -60
  97. package/src/client/types.ts +377 -398
  98. package/src/client/workflow.ts +83 -83
  99. package/src/client/workspace-ai.ts +191 -191
  100. package/src/client/workspace-manager.ts +564 -560
  101. package/src/client/workspace-search.ts +39 -39
  102. package/src/client/workspace.ts +480 -480
  103. package/src/error/DefaultAPIError.ts +151 -151
  104. package/src/error/FileUploadError.ts +18 -18
  105. package/src/error/IgnoredErrorCodes.ts +3 -3
  106. package/src/error/StackspotAPIError.ts +101 -101
  107. package/src/error/StreamCanceledError.ts +10 -10
  108. package/src/error/StreamError.ts +7 -7
  109. package/src/error/StreamJsonError.ts +10 -10
  110. package/src/error/dictionary/account.ts +58 -58
  111. package/src/error/dictionary/action-details.ts +20 -20
  112. package/src/error/dictionary/action.ts +211 -211
  113. package/src/error/dictionary/agent-tools.ts +75 -75
  114. package/src/error/dictionary/ai-inference.ts +28 -28
  115. package/src/error/dictionary/base.ts +22 -22
  116. package/src/error/dictionary/cloud-platform.ts +82 -82
  117. package/src/error/dictionary/cnt-fields.ts +14 -14
  118. package/src/error/dictionary/cnt.ts +103 -103
  119. package/src/error/dictionary/code-shift.ts +12 -12
  120. package/src/error/dictionary/rte.ts +24 -24
  121. package/src/error/dictionary/rtm.ts +10 -10
  122. package/src/error/dictionary/secrets.ts +14 -14
  123. package/src/error/dictionary/workspace-ai.ts +10 -10
  124. package/src/error/dictionary/workspace-details.ts +15 -15
  125. package/src/error/dictionary/workspace-fields.ts +10 -10
  126. package/src/error/dictionary/workspace.ts +209 -209
  127. package/src/error/types.ts +21 -21
  128. package/src/index.ts +43 -43
  129. package/src/network/AutoInfiniteQuery.ts +115 -115
  130. package/src/network/AutoMutation.ts +27 -27
  131. package/src/network/AutoOperation.ts +73 -73
  132. package/src/network/AutoQuery.ts +75 -75
  133. package/src/network/ManualInfiniteQuery.ts +95 -95
  134. package/src/network/ManualMutation.ts +40 -40
  135. package/src/network/ManualOperation.ts +52 -52
  136. package/src/network/ManualQuery.ts +82 -82
  137. package/src/network/NetworkClient.ts +167 -167
  138. package/src/network/ReactQueryNetworkClient.ts +312 -312
  139. package/src/network/react-query-client.ts +14 -14
  140. package/src/network/types.ts +294 -294
  141. package/src/types.ts +1 -1
  142. package/src/utils/StreamedArray.tsx +146 -146
  143. package/src/utils/StreamedJson.tsx +166 -166
  144. package/src/utils/remove-authorization-param.ts +6 -6
  145. package/src/utils/string.ts +19 -19
  146. package/src/utils/use-extended-list.ts +80 -80
  147. package/src/utils/use-streamed-array.ts +17 -17
  148. package/tsconfig.build.json +4 -4
  149. package/tsconfig.json +10 -10
  150. package/logs/simple-failure/01JBER7AWKACEC3Y1NF7M6PHFF/job_id_1.log +0 -3
  151. package/logs/simple-suspend/01JBEMQG94ADPT99MSZ7EJKGXZ/job_id_1.log +0 -5
package/src/client/ai.ts CHANGED
@@ -1,469 +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, goal: '' })
268
- }))
269
- agent.toolkits?.custom_toolkits?.forEach(kit => kit.tools?.forEach(({ id, name, description }) => {
270
- if (id) tools.push({ image: kit.avatar ?? undefined, id, name: name || id, description, goal: '' })
271
- }))
272
- return tools
273
- } catch {
274
- return []
275
- }
276
- }
277
-
278
- sendChatMessage(request: FixedChatRequest, minChangeIntervalMS?: number): StreamedJson<ChatResponseWithSteps> {
279
- const abortController = new AbortController()
280
- const headers = {
281
- 'Content-Type': 'application/json',
282
- 'Accept': 'text/event-stream',
283
- }
284
- const events = this.stream(
285
- this.resolveURL('v3/chat'),
286
- { method: 'post', body: JSON.stringify(request), headers, signal: abortController.signal },
287
- )
288
-
289
- /**
290
- * This function treats events in the streaming that deals with the execution of tools. Since these events are not concatenated like
291
- * normal streamings of data, we need this separate function to deal with them. It transforms the internal data model of the
292
- * StreamedJson object whenever an event is triggered.
293
- */
294
- async function transform(event: Partial<FixedChatResponse>, data: Partial<ChatResponseWithSteps>) {
295
- const info = event.agent_info
296
- if (!info) return
297
- const tools = await AIClient.toolsOfAgent(request.context?.agent_id)
298
- data.steps = data.steps ? [...data.steps] : []
299
-
300
- if (info.type === 'planning' && info.action === 'end') {
301
- data.steps.push({
302
- id: 'planning',
303
- type: 'planning',
304
- status: 'success',
305
- duration: info.duration || 0,
306
- steps: info.data?.steps?.map(s => s.goal) ?? [],
307
- goal: info.data?.plan_goal ?? '',
308
- })
309
-
310
- info.data?.steps.forEach(s => data.steps?.push({
311
- id: s.id,
312
- type: 'step',
313
- status: 'pending',
314
- input: s.goal,
315
- attempts: [{
316
- tools: s.tools?.map(t => ({
317
- ...(tools.find(({ id }) => id === t.tool_id) ?? { id: t.tool_id, name: t.tool_id }),
318
- executionId: t.tool_execution_id,
319
- goal: t.goal,
320
- })),
321
- }],
322
- }))
323
- data.steps.push({ id: 'answer', type: 'answer', status: 'pending' })
324
- }
325
-
326
- if (info.type === 'planning' && info.action === 'awaiting_approval') {
327
- data.steps.push({
328
- id: 'planning',
329
- type: 'planning',
330
- status: 'awaiting_approval',
331
- user_question: info.data?.user_question,
332
- duration: info.duration || 0,
333
- steps: info.data?.steps?.map(s => s.goal) ?? [],
334
- goal: info.data?.plan_goal ?? '',
335
- })
336
- info.data?.steps.forEach(s => data.steps?.push({
337
- id: s.id,
338
- type: 'step',
339
- status: 'pending',
340
- input: s.goal,
341
- attempts: [{
342
- tools: s.tools?.map(t => ({
343
- ...(tools.find(({ id }) => id === t.tool_id) ?? { id: t.tool_id, name: t.tool_id }),
344
- executionId: t.tool_execution_id,
345
- goal: t.goal,
346
- })),
347
- }],
348
- }))
349
- data.steps.push({ id: 'answer', type: 'answer', status: 'pending' })
350
- }
351
-
352
- if (info.type === 'step' && info.action === 'start') {
353
- const step = data.steps.find(s => s.id === info.id)
354
- if (step) step.status = 'running'
355
- }
356
-
357
- if (info.type === 'step' && info.action === 'end') {
358
- const step = data.steps.find(s => s.id === info.id) as StepChatStep
359
- if (step) {
360
- step.status = 'success'
361
- step.duration = info.duration
362
- const lastToolId = last(step.attempts[0].tools)?.id
363
- const lastAttemptOfLastTool = findLast(step.attempts.map(a => a.tools).flat(), t => t?.id === lastToolId)
364
- step.output = lastAttemptOfLastTool?.output
365
- }
366
- }
367
-
368
- if (info.type === 'tool' && info.action === 'awaiting_approval') {
369
- const tool = tools.find(({ id }) => id === info.data?.tool_id)
370
- data.steps.push({
371
- id: info.id,
372
- type: 'tool',
373
- status: 'awaiting_approval',
374
- duration: info.duration || 0,
375
- input: info.data?.input,
376
- user_question: info.data?.user_question,
377
- attempts: [{
378
- tools: [{
379
- executionId: info.id,
380
- id: info.data?.tool_id ?? '',
381
- name: tool?.name ?? '',
382
- goal: tool?.goal ?? '',
383
- ...tool,
384
- }],
385
- }],
386
- })
387
- data.steps.push({ id: 'answer', type: 'answer', status: 'pending' })
388
- }
389
-
390
- if (info.type === 'tool' && info.action === 'start') {
391
- const currentStep = data.steps.find(s => s.status === 'running') as StepChatStep
392
- if (!info.data) return
393
-
394
- //There might be a tool with status awaiting_approval, so we want to inform tool has already started
395
- if (!currentStep || !currentStep.attempts[0].tools) {
396
- const input = formatJson(info.data.input)
397
- const tool = tools.find(({ id }) => id === info.data?.tool_id) ?? { id: info.data?.tool_id, name: info.data?.tool_id }
398
- data.steps.push({
399
- id: info.id,
400
- type: 'tool',
401
- status: 'running',
402
- duration: info.duration || 0,
403
- input: info.data?.input,
404
- user_question: info.data?.user_question,
405
- attempts: [{
406
- tools:[{ ...tool, executionId: info.id, input }],
407
- }],
408
- })
409
- } else {
410
- const toolInFirstAttempt = currentStep.attempts[0].tools.find(t => t.executionId === info.id)
411
- if (!toolInFirstAttempt) return
412
- const input = formatJson(info.data.input)
413
- if (info.data.attempt === 1) {
414
- toolInFirstAttempt.input = input
415
- } else {
416
- const tool = tools.find(({ id }) => id === info.data?.tool_id) ?? { id: info.data?.tool_id, name: info.data?.tool_id }
417
- currentStep.attempts[info.data.attempt-1] ??= { tools: [] }
418
- currentStep.attempts[info.data.attempt-1].tools?.push({
419
- ...tool,
420
- input,
421
- })
422
- }
423
-
424
- }
425
- }
426
-
427
- if (info.type === 'tool' && info.action === 'end') {
428
- const currentStep = data.steps.find(s => s.status === 'running') as StepChatStep
429
- if (!currentStep || !info.data) return
430
- const tool = currentStep.attempts[info.data.attempt-1]?.tools?.find(t => t.executionId === info.id)
431
- if (tool) {
432
- tool.output = formatJson(info.data.output)
433
- tool.duration = info.duration
434
- }
435
- }
436
-
437
- if (info.type === 'final_answer' && info.action === 'start') {
438
- const answerStep = last(data.steps)
439
- if (answerStep) answerStep.status = 'running'
440
- }
441
-
442
- if (info.type === 'final_answer' && info.action === 'end') {
443
- const answerStep = last(data.steps)
444
- if (answerStep) {
445
- answerStep.status = 'success'
446
- answerStep.duration = info.duration
447
- }
448
- }
449
- }
450
-
451
- return new StreamedJson({
452
- eventsPromise: events,
453
- abortController,
454
- minChangeIntervalMS,
455
- ignoreKeys: ['agent_info'],
456
- transform,
457
- })
458
- }
459
-
460
- contentDependencies = this.query(removeAuthorizationParam(
461
- getContentDependenciesV1ContentContentTypeContentIdDependenciesGet as ReplaceResult<
462
- typeof getContentDependenciesV1ContentContentTypeContentIdDependenciesGet,
463
- FixedDependencyResponse
464
- >,
465
- ))
466
- }
467
-
468
- export const aiClient = new AIClient()
469
-
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()