@stack-spot/portal-network 0.203.0 → 0.204.0-beta.1

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 (141) hide show
  1. package/CHANGELOG.md +259 -0
  2. package/dist/api/account.d.ts +344 -91
  3. package/dist/api/account.d.ts.map +1 -1
  4. package/dist/api/account.js +203 -46
  5. package/dist/api/account.js.map +1 -1
  6. package/dist/api/accountAssetManager.d.ts +309 -0
  7. package/dist/api/accountAssetManager.d.ts.map +1 -0
  8. package/dist/api/accountAssetManager.js +169 -0
  9. package/dist/api/accountAssetManager.js.map +1 -0
  10. package/dist/api/agent-tools.d.ts +623 -141
  11. package/dist/api/agent-tools.d.ts.map +1 -1
  12. package/dist/api/agent-tools.js +168 -45
  13. package/dist/api/agent-tools.js.map +1 -1
  14. package/dist/api/ai.d.ts +135 -24
  15. package/dist/api/ai.d.ts.map +1 -1
  16. package/dist/api/ai.js +79 -26
  17. package/dist/api/ai.js.map +1 -1
  18. package/dist/api/codeShift.d.ts +140 -10
  19. package/dist/api/codeShift.d.ts.map +1 -1
  20. package/dist/api/codeShift.js +73 -6
  21. package/dist/api/codeShift.js.map +1 -1
  22. package/dist/api/discover.d.ts +9 -6
  23. package/dist/api/discover.d.ts.map +1 -1
  24. package/dist/api/discover.js +5 -5
  25. package/dist/api/discover.js.map +1 -1
  26. package/dist/api/edpBfa.d.ts +215 -0
  27. package/dist/api/edpBfa.d.ts.map +1 -0
  28. package/dist/api/edpBfa.js +87 -0
  29. package/dist/api/edpBfa.js.map +1 -0
  30. package/dist/api/genAiInference.d.ts +49 -2
  31. package/dist/api/genAiInference.d.ts.map +1 -1
  32. package/dist/api/genAiInference.js +55 -2
  33. package/dist/api/genAiInference.js.map +1 -1
  34. package/dist/api/workspace-ai.d.ts +41 -0
  35. package/dist/api/workspace-ai.d.ts.map +1 -1
  36. package/dist/api/workspace-ai.js +34 -0
  37. package/dist/api/workspace-ai.js.map +1 -1
  38. package/dist/api-addresses.d.ts +13 -20
  39. package/dist/api-addresses.d.ts.map +1 -1
  40. package/dist/api-addresses.js +60 -17
  41. package/dist/api-addresses.js.map +1 -1
  42. package/dist/apis-itau.json +16 -0
  43. package/dist/apis.json +16 -0
  44. package/dist/client/account-asset-manager.d.ts +112 -0
  45. package/dist/client/account-asset-manager.d.ts.map +1 -0
  46. package/dist/client/account-asset-manager.js +160 -0
  47. package/dist/client/account-asset-manager.js.map +1 -0
  48. package/dist/client/account.d.ts +11 -9
  49. package/dist/client/account.d.ts.map +1 -1
  50. package/dist/client/account.js +11 -8
  51. package/dist/client/account.js.map +1 -1
  52. package/dist/client/agent-tools.d.ts +122 -3
  53. package/dist/client/agent-tools.d.ts.map +1 -1
  54. package/dist/client/agent-tools.js +105 -10
  55. package/dist/client/agent-tools.js.map +1 -1
  56. package/dist/client/ai.d.ts +149 -4
  57. package/dist/client/ai.d.ts.map +1 -1
  58. package/dist/client/ai.js +93 -208
  59. package/dist/client/ai.js.map +1 -1
  60. package/dist/client/code-shift.d.ts +54 -3
  61. package/dist/client/code-shift.d.ts.map +1 -1
  62. package/dist/client/code-shift.js +46 -1
  63. package/dist/client/code-shift.js.map +1 -1
  64. package/dist/client/data-integration.d.ts.map +1 -1
  65. package/dist/client/data-integration.js +8 -1
  66. package/dist/client/data-integration.js.map +1 -1
  67. package/dist/client/discover.d.ts +3 -3
  68. package/dist/client/discover.d.ts.map +1 -1
  69. package/dist/client/discover.js +4 -3
  70. package/dist/client/discover.js.map +1 -1
  71. package/dist/client/edp-bfa.d.ts +16 -0
  72. package/dist/client/edp-bfa.d.ts.map +1 -0
  73. package/dist/client/edp-bfa.js +24 -0
  74. package/dist/client/edp-bfa.js.map +1 -0
  75. package/dist/client/gen-ai-inference.d.ts +4 -0
  76. package/dist/client/gen-ai-inference.d.ts.map +1 -1
  77. package/dist/client/gen-ai-inference.js +267 -0
  78. package/dist/client/gen-ai-inference.js.map +1 -1
  79. package/dist/client/notification.d.ts +7 -0
  80. package/dist/client/notification.d.ts.map +1 -1
  81. package/dist/client/notification.js +10 -1
  82. package/dist/client/notification.js.map +1 -1
  83. package/dist/client/types.d.ts +24 -17
  84. package/dist/client/types.d.ts.map +1 -1
  85. package/dist/client/workspace-ai.d.ts +13 -3
  86. package/dist/client/workspace-ai.d.ts.map +1 -1
  87. package/dist/client/workspace-ai.js +17 -3
  88. package/dist/client/workspace-ai.js.map +1 -1
  89. package/dist/client/workspace-manager.d.ts +24 -0
  90. package/dist/client/workspace-manager.d.ts.map +1 -1
  91. package/dist/client/workspace-manager.js +28 -1
  92. package/dist/client/workspace-manager.js.map +1 -1
  93. package/dist/error/dictionary/accountAssetManager.d.ts +11 -0
  94. package/dist/error/dictionary/accountAssetManager.d.ts.map +1 -0
  95. package/dist/error/dictionary/accountAssetManager.js +11 -0
  96. package/dist/error/dictionary/accountAssetManager.js.map +1 -0
  97. package/dist/index.d.ts +3 -1
  98. package/dist/index.d.ts.map +1 -1
  99. package/dist/index.js +3 -1
  100. package/dist/index.js.map +1 -1
  101. package/dist/network/NetworkClient.d.ts.map +1 -1
  102. package/dist/network/NetworkClient.js +12 -2
  103. package/dist/network/NetworkClient.js.map +1 -1
  104. package/dist/network/types.d.ts +1 -0
  105. package/dist/network/types.d.ts.map +1 -1
  106. package/dist/utils/StreamedJson.d.ts +9 -1
  107. package/dist/utils/StreamedJson.d.ts.map +1 -1
  108. package/dist/utils/StreamedJson.js +22 -2
  109. package/dist/utils/StreamedJson.js.map +1 -1
  110. package/package.json +2 -2
  111. package/readme.md +39 -1
  112. package/src/api/account.ts +592 -165
  113. package/src/api/accountAssetManager.ts +771 -0
  114. package/src/api/agent-tools.ts +824 -188
  115. package/src/api/ai.ts +206 -38
  116. package/src/api/codeShift.ts +246 -13
  117. package/src/api/discover.ts +10 -10
  118. package/src/api/edpBfa.ts +472 -0
  119. package/src/api/genAiInference.ts +119 -3
  120. package/src/api/workspace-ai.ts +83 -0
  121. package/src/api-addresses.ts +93 -37
  122. package/src/apis-itau.json +16 -0
  123. package/src/apis.json +16 -0
  124. package/src/client/account-asset-manager.ts +100 -0
  125. package/src/client/account.ts +11 -7
  126. package/src/client/agent-tools.ts +69 -16
  127. package/src/client/ai.ts +60 -213
  128. package/src/client/code-shift.ts +29 -0
  129. package/src/client/data-integration.ts +9 -2
  130. package/src/client/discover.ts +8 -7
  131. package/src/client/edp-bfa.ts +24 -0
  132. package/src/client/gen-ai-inference.ts +281 -0
  133. package/src/client/notification.ts +6 -1
  134. package/src/client/types.ts +26 -17
  135. package/src/client/workspace-ai.ts +21 -6
  136. package/src/client/workspace-manager.ts +18 -0
  137. package/src/error/dictionary/accountAssetManager.ts +12 -0
  138. package/src/index.ts +4 -1
  139. package/src/network/NetworkClient.ts +13 -4
  140. package/src/network/types.ts +1 -0
  141. package/src/utils/StreamedJson.tsx +19 -2
@@ -0,0 +1,24 @@
1
+ import { HttpError } from '@oazapfts/runtime'
2
+ import { getApiAddresses } from '../api-addresses'
3
+ import { defaults, executeCodeWorkflow } from '../api/edpBfa'
4
+ import { DefaultAPIError } from '../error/DefaultAPIError'
5
+ import { baseDictionary } from '../error/dictionary/base'
6
+ import { StackspotAPIError } from '../error/StackspotAPIError'
7
+ import { ReactQueryNetworkClient } from '../network/ReactQueryNetworkClient'
8
+
9
+ class EdpBfaClient extends ReactQueryNetworkClient {
10
+ constructor() {
11
+ super(getApiAddresses().edpBfa.url, defaults)
12
+ }
13
+
14
+ protected buildStackSpotError(error: HttpError): StackspotAPIError {
15
+ return new DefaultAPIError(error.data, error.status, baseDictionary, error.headers)
16
+ }
17
+
18
+ /**
19
+ * Triggers an workflow to generate code.
20
+ */
21
+ generateCode = this.mutation(executeCodeWorkflow)
22
+ }
23
+
24
+ export const edpBfaClient = new EdpBfaClient()
@@ -1,5 +1,6 @@
1
1
 
2
2
  import { HttpError } from '@oazapfts/runtime'
3
+ import { findLast, last } from 'lodash'
3
4
  import { getApiAddresses } from '../api-addresses'
4
5
  import { addSelfHostedModelV1LlmModelsPost, agentChatV1AgentAgentIdChatPost, defaults, deleteModelResourcesV1LlmResourcesResourceIdDelete, deleteV1LlmModelsModelIdDelete, getModelV1LlmModelsModelIdGet, listLlmProvidersV1LlmProvidersGet, listModelsV1LlmModelsGet, saveOrUpdateModelResourcesV1LlmModelsModelIdResourcesPut, toggleModelStatusV1LlmModelsModelIdPatch, updateV1LlmModelsModelIdPut } from '../api/genAiInference'
5
6
  import { DefaultAPIError } from '../error/DefaultAPIError'
@@ -7,6 +8,10 @@ import { inferenceDictionary } from '../error/dictionary/ai-inference'
7
8
  import { StackspotAPIError } from '../error/StackspotAPIError'
8
9
  import { ReactQueryNetworkClient } from '../network/ReactQueryNetworkClient'
9
10
  import { removeAuthorizationParam } from '../utils/remove-authorization-param'
11
+ import { StreamedJson } from '../utils/StreamedJson'
12
+ import { formatJson } from '../utils/string'
13
+ import { agentToolsClient } from './agent-tools'
14
+ import { AgentInfo, ChatAgentTool, ChatResponseWithSteps, FixedChatRequest, FixedChatResponse, StepChatStep } from './types'
10
15
 
11
16
  class GenAiInference extends ReactQueryNetworkClient {
12
17
  constructor() {
@@ -60,6 +65,282 @@ class GenAiInference extends ReactQueryNetworkClient {
60
65
  * Interaction with a specific AI agent
61
66
  */
62
67
  sendAgentMessage = this.mutation(removeAuthorizationParam(agentChatV1AgentAgentIdChatPost))
68
+
69
+
70
+ private static async toolsOfAgent(agentId?: string) {
71
+ try {
72
+ const agent = agentId ? await agentToolsClient.agent.query({ agentId }) : undefined
73
+ if (!agent) return []
74
+ const tools: (Omit<ChatAgentTool, 'duration' | 'prompt' | 'output'>)[] = []
75
+ agent.toolkits?.builtin_toolkits?.forEach(kit => kit.tools?.forEach(({ id, name, description }) => {
76
+ if (id) tools.push({ image: kit.image_url, id, name: name || id, description })
77
+ }))
78
+ agent.toolkits?.custom_toolkits?.forEach(kit => kit.tools?.forEach(({ id, name, description }) => {
79
+ if (id) tools.push({ image: kit.avatar ?? undefined, id, name: name || id, description })
80
+ }))
81
+ return tools
82
+ } catch {
83
+ return []
84
+ }
85
+ }
86
+
87
+ sendChatMessage(request: FixedChatRequest, minChangeIntervalMS?: number): StreamedJson<ChatResponseWithSteps> {
88
+ const abortController = new AbortController()
89
+ const { context, ...body } = request ?? {}
90
+ const headers = {
91
+ 'Content-Type': 'application/json',
92
+ 'Accept': 'text/event-stream',
93
+ 'x-platform': context?.platform ?? '',
94
+ 'x-os': context?.os ?? '',
95
+ 'x-platform-version': context?.platform_version ?? '',
96
+ 'x-stackspot-ai-version': context?.stackspot_ai_version ?? '',
97
+ 'x-request-origin': 'chat',
98
+ }
99
+ const events = this.stream(
100
+ this.resolveURL(`/v1/agent/${context?.agent_id}/chat`),
101
+ { method: 'post', body: JSON.stringify(body), headers, signal: abortController.signal },
102
+ )
103
+
104
+ const DYNAMIC_TOOL_ID = 'dynamic'
105
+ function isDynamicTool(info: AgentInfo) {
106
+ return info.type === 'tool' && info.id === DYNAMIC_TOOL_ID
107
+ }
108
+ /**
109
+ * This function treats events in the streaming that deals with the execution of tools. Since these events are not concatenated like
110
+ * normal streamings of data, we need this separate function to deal with them. It transforms the internal data model of the
111
+ * StreamedJson object whenever an event is triggered.
112
+ */
113
+ async function transform(event: Partial<FixedChatResponse>, data: Partial<ChatResponseWithSteps>) {
114
+ // The API send a final snapshot containing the full `agent_info`.
115
+ // When `stop_reason === 'stop'` we can ignore it to avoid duplicating steps.
116
+ if (event?.stop_reason === 'stop') return
117
+
118
+ const infoList = event.agent_info ?? []
119
+ if (infoList.length === 0) return
120
+
121
+ const tools = await GenAiInference.toolsOfAgent(request.context?.agent_id)
122
+ data.steps = data.steps ? [...data.steps] : []
123
+
124
+ for (const info of infoList) {
125
+
126
+ if (info.type === 'planning' && info.action === 'end') {
127
+ data.steps.push({
128
+ id: 'planning',
129
+ type: 'planning',
130
+ status: 'success',
131
+ duration: info.duration || 0,
132
+ steps: info.data?.steps?.map(s => s.goal) ?? [],
133
+ goal: info.data?.plan_goal ?? '',
134
+ })
135
+
136
+ info.data?.steps.forEach(s => data.steps?.push({
137
+ id: s.id,
138
+ type: 'step',
139
+ status: 'pending',
140
+ input: s.goal,
141
+ attempts: [{
142
+ tools: s.tools?.map(t => ({
143
+ ...(tools.find(({ id }) => id === t.tool_id) ?? { id: t.tool_id, name: t.tool_id }),
144
+ executionId: t.tool_execution_id,
145
+ goal: t.goal,
146
+ })),
147
+ }],
148
+ }))
149
+ data.steps.push({ id: 'answer', type: 'answer', status: 'pending' })
150
+ }
151
+
152
+ if (info.type === 'planning' && info.action === 'awaiting_approval') {
153
+ data.steps.push({
154
+ id: 'planning',
155
+ type: 'planning',
156
+ status: 'awaiting_approval',
157
+ user_question: info.data?.user_question,
158
+ duration: info.duration || 0,
159
+ steps: info.data?.steps?.map(s => s.goal) ?? [],
160
+ goal: info.data?.plan_goal ?? '',
161
+ })
162
+ info.data?.steps.forEach(s => data.steps?.push({
163
+ id: s.id,
164
+ type: 'step',
165
+ status: 'pending',
166
+ input: s.goal,
167
+ attempts: [{
168
+ tools: s.tools?.map(t => ({
169
+ ...(tools.find(({ id }) => id === t.tool_id) ?? { id: t.tool_id, name: t.tool_id }),
170
+ executionId: t.tool_execution_id,
171
+ goal: t.goal,
172
+ })),
173
+ }],
174
+ }))
175
+ data.steps.push({ id: 'answer', type: 'answer', status: 'pending' })
176
+ }
177
+
178
+ if (info.type === 'step' && info.action === 'start') {
179
+ const step = data.steps.find(s => s.id === info.id)
180
+ if (step) step.status = 'running'
181
+ }
182
+
183
+ if (info.type === 'step' && info.action === 'end') {
184
+ const step = data.steps.find(s => s.id === info.id) as StepChatStep
185
+ if (step) {
186
+ step.status = 'success'
187
+ step.duration = info.duration
188
+ const lastToolId = last(step.attempts[0].tools)?.id
189
+ const lastAttemptOfLastTool = findLast(step.attempts.map(a => a.tools).flat(), t => t?.id === lastToolId)
190
+ step.output = lastAttemptOfLastTool?.output
191
+ }
192
+ }
193
+
194
+ if (info.type === 'tool_calls' && info.action === 'start') {
195
+ const hasPlanning = data.steps.find(s => s.type === 'planning')
196
+ // On the first tool_calls:start, create the synthetic planning ("dynamic") step.
197
+ if (!hasPlanning) {
198
+ const userPrompt = request.user_prompt === 'string' ? request.user_prompt : JSON.stringify(request.user_prompt)
199
+ data.steps.push({
200
+ id: 'dynamic',
201
+ type: 'planning',
202
+ status: 'success',
203
+ steps: [],
204
+ goal: userPrompt,
205
+ user_question: userPrompt,
206
+ })
207
+ }
208
+ const toolsStepId = data.steps.filter(s => s.id === 'tools' || s.id.startsWith('tools-')).length + 1
209
+ data.steps.push({
210
+ id: `tools-${toolsStepId.toString()}`,
211
+ type: 'step',
212
+ status: 'running',
213
+ attempts: [{ tools: [] }],
214
+ } as StepChatStep)
215
+ }
216
+
217
+ if (info.type === 'tool_calls' && info.action === 'end') {
218
+ const lastStep = findLast(data.steps, s => s.id === 'tools' || s.id.startsWith('tools-')) as StepChatStep
219
+ if (lastStep) {
220
+ lastStep.status = 'success'
221
+ lastStep.duration = info.duration
222
+ const lastAttemptOfLastTool = last(lastStep.attempts.map(a => a.tools).flat())
223
+ lastStep.output = lastAttemptOfLastTool?.output
224
+ }
225
+ }
226
+
227
+ if (info.type === 'tool' && info.action === 'awaiting_approval') {
228
+ const tool = tools.find(({ id }) => id === info.data?.tool_id)
229
+ data.steps.push({
230
+ id: info.id,
231
+ type: 'tool',
232
+ status: 'awaiting_approval',
233
+ duration: info.duration || 0,
234
+ input: info.data?.input,
235
+ user_question: info.data?.user_question,
236
+ attempts: [{
237
+ tools: [{
238
+ executionId: info.id,
239
+ id: info.data?.tool_id ?? '',
240
+ name: tool?.name ?? '',
241
+ goal: tool?.goal,
242
+ ...tool,
243
+ }],
244
+ }],
245
+ })
246
+ data.steps.push({ id: 'answer', type: 'answer', status: 'pending' })
247
+ }
248
+
249
+ if (info.type === 'tool' && info.action === 'start') {
250
+ if (!info.data) return
251
+ const input = formatJson(info.data.input)
252
+ const tool = findLast(tools, ({ id }) => id === info.data?.tool_id) ?? { id: info.data?.tool_id, name: info.data?.tool_id }
253
+
254
+ const currentStep = findLast(data.steps, s => s.status === 'running') as StepChatStep
255
+
256
+ //There might be a tool with status awaiting_approval, so we want to inform tool has already started
257
+ if (!currentStep || !currentStep?.attempts?.[0]?.tools) {
258
+ data.steps.push({
259
+ id: info.id,
260
+ type: 'tool',
261
+ status: 'running',
262
+ duration: info.duration || 0,
263
+ input: info.data?.input,
264
+ user_question: info.data?.user_question,
265
+ attempts: [{
266
+ tools: [{ ...tool, executionId: info.id, input }],
267
+ }],
268
+ })
269
+ } else {
270
+ const toolInFirstAttempt = findLast(currentStep?.attempts?.[0]?.tools, t => t.executionId === info.id)
271
+ //One step might have multiple tools. When in an approval mode, we might not have all the tools in the array yet.
272
+ //For dynamic tools (id === 'dynamic'), we always push a new tool, since dynamic executions can trigger
273
+ //multiple tool runs in the same step and do not follow the planned tool structure.
274
+ //So we make sure to add any tools that are not in there, or always add for dynamic tools.
275
+ if (!toolInFirstAttempt || isDynamicTool(info)) {
276
+ currentStep.attempts?.[0].tools?.push({
277
+ ...tool,
278
+ executionId: info.id,
279
+ input,
280
+ status: 'running',
281
+ })
282
+ } else {
283
+ const input = formatJson(info.data.input)
284
+ if (info.data.attempt === 1) {
285
+ toolInFirstAttempt.input = input
286
+ } else {
287
+ currentStep.attempts[info.data.attempt - 1] ??= { tools: [] }
288
+ currentStep.attempts[info.data.attempt - 1].tools?.push({
289
+ ...tool,
290
+ executionId: info.id,
291
+ input,
292
+ })
293
+ }
294
+ }
295
+ }
296
+ }
297
+
298
+ if (info.type === 'tool' && info.action === 'end') {
299
+ const currentStep = data.steps.find(s => s.status === 'running') as StepChatStep
300
+ if (!currentStep || !info.data) return
301
+
302
+ // attempt index for tool execution starts at 0 for dynamically executed tools,while for planned tools it starts at 1
303
+ const attempt = isDynamicTool(info) ? info.data.attempt : info.data.attempt - 1
304
+ const tool = last(currentStep?.attempts?.[attempt]?.tools)
305
+ if (tool) {
306
+ tool.output = formatJson(info.data.output)
307
+ tool.duration = info.duration
308
+ tool.status = 'success'
309
+ }
310
+ }
311
+
312
+ if (info.type === 'final_answer' && info.action === 'start') {
313
+ const answerStep = last(data.steps)
314
+ if (answerStep) answerStep.status = 'running'
315
+ }
316
+
317
+
318
+ if (info.type === 'chat' && info.action === 'end') {
319
+ const lastStep = last(data.steps)
320
+ if (lastStep?.type === 'answer') {
321
+ lastStep.status = 'success'
322
+ lastStep.duration = info.duration
323
+ } else {
324
+ data.steps.push({ id: 'answer', type: 'answer', status: 'success' })
325
+ }
326
+ }
327
+ }
328
+ }
329
+
330
+ return new StreamedJson({
331
+ eventsPromise: events,
332
+ abortController,
333
+ ignoreKeys: ['agent_info'],
334
+ transform,
335
+ textFromErrorEvent: data => data.message ?? 'Unknown error',
336
+ minChangeIntervalMS,
337
+ minChangeIntervalMSFromEvent: (event) => {
338
+ if (event?.agent_info?.length) return 0
339
+ return minChangeIntervalMS
340
+ },
341
+ })
342
+ }
343
+
63
344
  }
64
345
 
65
346
  export const genAiInferenceClient = new GenAiInference()
@@ -1,5 +1,5 @@
1
1
  import { HttpError } from '@oazapfts/runtime'
2
- import { commit, committedNotifications, defaults, findAll } from '../api/notification'
2
+ import { commit, committedNotifications, defaults, findAll, uncommit } from '../api/notification'
3
3
  import { DefaultAPIError } from '../error/DefaultAPIError'
4
4
  import { baseDictionary } from '../error/dictionary/base'
5
5
  import { StackspotAPIError } from '../error/StackspotAPIError'
@@ -27,6 +27,11 @@ class NotificationClient extends ReactQueryNetworkClient {
27
27
  * Mark a notification as committed (mark as read)
28
28
  */
29
29
  commit = this.mutation(commit)
30
+ /**
31
+ * Mark a notification as uncommitted (mark as unread)
32
+ */
33
+ uncommit = this.mutation(uncommit)
34
+
30
35
  }
31
36
 
32
37
  export const notificationClient = new NotificationClient()
@@ -1,9 +1,10 @@
1
1
  import { RequestOpts } from '@oazapfts/runtime'
2
2
  import { AccountScmInfoSaveRequest, AccountScmInfoUpdateRequest, AccountScmStatusResponse, GroupsFromResourceResponse, MembersFromResourceResponse } from '../api/account'
3
3
  import { AgentVisibilityLevelEnum, HttpMethod, ListAgentResponse, VisibilityLevelEnum } from '../api/agent-tools'
4
- import { ChatRequest, ChatResponse3, ContentDependencyResponse, ConversationHistoryResponse, ConversationResponse, DependencyResponse } from '../api/ai'
4
+ import { ChatResponse3, ContentDependencyResponse, ConversationHistoryResponse, ConversationResponse, DependencyResponse, SourceKnowledgeSource, SourceProjectFile3, SourceStackAi } from '../api/ai'
5
5
  import { ConnectAccountRequestV2, ManagedAccountProvisionRequest } from '../api/cloudAccount'
6
6
  import { AllocationCostRequest, AllocationCostResponse, ChargePeriod, getAllocationCostFilters, ManagedService, ServiceResource } from '../api/cloudServices'
7
+ import { ChatRequest } from '../api/genAiInference'
7
8
  import { Action } from '../api/workspace-ai'
8
9
  import { ActivityResponse, FullInputContextResponse, InputConditionResponse, InputValuesContextResponse, PaginatedActivityResponse, PluginForAppCreationV2Response, PluginInputValuesInConsolidatedContextResponse, ValueByEnvResponse, WorkflowForCreationResponse } from '../api/workspaceManager'
9
10
 
@@ -172,20 +173,11 @@ export interface FixedPaginatedActivityResponse extends Omit<PaginatedActivityRe
172
173
 
173
174
  export interface FixedChatRequest extends ChatRequest {
174
175
  context?: {
175
- workspace?: string,
176
- conversation_id?: string,
177
- stack_id?: string,
178
- language?: string,
179
- project_recent_files?: string,
180
- knowledge_sources?: string[],
181
- agent_id?: string,
182
- agent_built_in?: boolean,
183
176
  platform?: string,
184
177
  platform_version?: string,
185
178
  stackspot_ai_version?: string,
186
179
  os?: string,
187
- upload_ids?: string[],
188
- selected_model_id?: string,
180
+ agent_id?: string,
189
181
  },
190
182
  }
191
183
 
@@ -247,6 +239,7 @@ export interface ChatAgentTool {
247
239
  input?: string,
248
240
  output?: string,
249
241
  goal?: string,
242
+ status?: 'running' | 'success' | 'error',
250
243
  }
251
244
 
252
245
  export interface ChatStepAttempt {
@@ -308,10 +301,10 @@ export interface AnswerChatStep extends BaseChatStep {
308
301
  export type ChatStep = PlanningChatStep | StepChatStep | AnswerChatStep | ToolChatStep
309
302
 
310
303
  export interface BaseAgentInfo {
311
- type: 'chat' | 'planning' | 'step' | 'tool' | 'final_answer',
304
+ type: 'chat' | 'planning' | 'step' | 'tool' | 'final_answer' | 'tool_calls',
312
305
  action: 'start' | 'end' | 'awaiting_approval',
313
306
  duration?: number,
314
- id: string,
307
+ id?: string,
315
308
  }
316
309
 
317
310
  export interface AgentTool {
@@ -355,11 +348,27 @@ export interface GenericAgentInfo extends BaseAgentInfo {
355
348
  type: 'chat' | 'final_answer',
356
349
  }
357
350
 
358
- export type AgentInfo = GenericAgentInfo | PlanningAgentInfo | StepAgentInfo | ToolAgentInfo
351
+ export interface ToolCallsAgentInfo extends BaseAgentInfo {
352
+ type: 'tool_calls',
353
+ data?: {
354
+ tools?: string[],
355
+ duration?: number,
356
+ },
357
+ }
358
+
359
+ export type AgentInfo = GenericAgentInfo | PlanningAgentInfo | StepAgentInfo | ToolAgentInfo | ToolCallsAgentInfo
360
+
361
+ export type ChatResponse = {
362
+ message: string,
363
+ cross_account_source: SourceKnowledgeSource[],
364
+ source: (SourceStackAi | SourceKnowledgeSource | SourceProjectFile3)[],
365
+ message_id: string | null,
366
+ stop_reason: 'stop',
367
+ };
359
368
 
360
- export interface FixedChatResponse extends ChatResponse3 {
361
- agent_info: AgentInfo,
362
- tools?: string[],
369
+ export interface FixedChatResponse extends ChatResponse {
370
+ agent_info: AgentInfo[],
371
+ tools_id?: string[],
363
372
  }
364
373
  export interface OpportunitiesPMAgent {
365
374
  title: string,
@@ -1,9 +1,10 @@
1
1
  import { HttpError } from '@oazapfts/runtime'
2
- import { AgentResponse } from '../api/agent'
2
+ import { getApiAddresses } from '../api-addresses'
3
3
  import { CustomToolkitResponse } from '../api/agent-tools'
4
4
  import { GetAiStackResponse, KnowledgeSourceItemResponse, QuickCommandResponse } from '../api/ai'
5
5
  import {
6
6
  addContentV1WorkspacesWorkspaceIdContentTypePost,
7
+ addContentV2WorkspacesWorkspaceIdContentTypePost,
7
8
  addFavoriteV1WorkspacesWorkspaceIdFavoritePost,
8
9
  addPermissionV1ResourceTypeResourceTypeResourcesResourceIdentifierPatch,
9
10
  addPermissionV1WorkspacesWorkspaceIdPermissionsPatch,
@@ -24,13 +25,12 @@ import {
24
25
  updateWorkspaceV1WorkspacesWorkspaceIdPatch,
25
26
  useShareableLinkV1ShareShareIdPatch,
26
27
  } from '../api/workspace-ai'
28
+ import { DefaultAPIError } from '../error/DefaultAPIError'
29
+ import { wksAiDictionary } from '../error/dictionary/workspace-ai'
27
30
  import { StackspotAPIError } from '../error/StackspotAPIError'
28
31
  import { ReactQueryNetworkClient } from '../network/ReactQueryNetworkClient'
29
32
  import { removeAuthorizationParam } from '../utils/remove-authorization-param'
30
- import { getApiAddresses } from '../api-addresses'
31
- import { DefaultAPIError } from '../error/DefaultAPIError'
32
- import { wksAiDictionary } from '../error/dictionary/workspace-ai'
33
- import { FixedAddResourceToWorkspaceAi, FixedWorkspaceAiPermissions, ReplaceResult } from './types'
33
+ import { AgentResponseWithBuiltIn, FixedAddResourceToWorkspaceAi, FixedWorkspaceAiPermissions, ReplaceResult } from './types'
34
34
 
35
35
  class WorkspaceAiClient extends ReactQueryNetworkClient {
36
36
  constructor() {
@@ -48,6 +48,7 @@ class WorkspaceAiClient extends ReactQueryNetworkClient {
48
48
  deleteWorkspaceAi = this.mutation(removeAuthorizationParam(deleteWorkspaceV1WorkspacesWorkspaceIdDelete))
49
49
 
50
50
  /**
51
+ * @deprecated
51
52
  * Adds a resource to the Spot.
52
53
  */
53
54
  addResourceTypeToWorkspaceAi = this.mutation({
@@ -61,6 +62,20 @@ class WorkspaceAiClient extends ReactQueryNetworkClient {
61
62
  permission: this.createPermissionFunctionFor(addContentV1WorkspacesWorkspaceIdContentTypePost),
62
63
  })
63
64
 
65
+ /**
66
+ * V2 for adding a resource to the Spot.
67
+ */
68
+ addResourceTypeV2ToSpot = this.mutation({
69
+ name: 'addResourceTypeToWorkspaceAi',
70
+ request: (
71
+ signal,
72
+ variables: Omit<Parameters<typeof addContentV2WorkspacesWorkspaceIdContentTypePost>[0], 'authorization'>,
73
+ ) =>
74
+ addContentV2WorkspacesWorkspaceIdContentTypePost({ ...variables, authorization: '' },
75
+ { signal }) as unknown as Promise<FixedAddResourceToWorkspaceAi>,
76
+ permission: this.createPermissionFunctionFor(addContentV2WorkspacesWorkspaceIdContentTypePost),
77
+ })
78
+
64
79
  /**
65
80
  * Lists all the knowledge sources in a Spot.
66
81
  */
@@ -117,7 +132,7 @@ class WorkspaceAiClient extends ReactQueryNetworkClient {
117
132
  'authorization' | 'contentType'>,
118
133
  ) =>
119
134
  listAllByContentTypeV1WorkspacesWorkspaceIdContentTypeGet({ ...variables, contentType: 'agent', authorization: '' },
120
- { signal }) as unknown as Promise<AgentResponse[]>,
135
+ { signal }) as unknown as Promise<AgentResponseWithBuiltIn[]>,
121
136
  permission: this.createPermissionFunctionFor(listAllByContentTypeV1WorkspacesWorkspaceIdContentTypeGet),
122
137
  })
123
138
 
@@ -21,6 +21,7 @@ import {
21
21
  applicationControllergetApplicationLinks,
22
22
  applicationControllergetApplications,
23
23
  applicationControllerregistryAppDestroy,
24
+ availableConnectionInterfaceControllergetAvailableConnectionInterfaces,
24
25
  contentWorkflowControllercreateApplicationThroughWorkflow,
25
26
  contentWorkflowControllercreateSharedInfraThroughWorkflow,
26
27
  contextActionControllergetStackActionInputsInAccountContext,
@@ -29,6 +30,8 @@ import {
29
30
  contextControllerclearActionContextInWorkspace,
30
31
  contextControllerclearPluginContextInAccount,
31
32
  contextControllerclearPluginContextInWorkspace,
33
+ contextControllerclearWorkflowContextInAccount,
34
+ contextControllerclearWorkflowContextInWorkspace,
32
35
  contextControllerimportContextInAccount,
33
36
  contextControllerimportContextInWorkspace,
34
37
  contextControllerupsertAccountActionsInputContext,
@@ -539,6 +542,17 @@ class WorkspaceManagerClient extends ReactQueryNetworkClient {
539
542
  permission: async ({ stackVersionId, workflowVersionId }: Parameters<typeof contextControllerupsertWorkflowAccountContext>[0]) =>
540
543
  workspaceClient.saveContextInAccount.isAllowed({ $type: 'workflow', stackVersionId, externalId: workflowVersionId }),
541
544
  })
545
+
546
+ /**
547
+ * Clear stack workflow context in account
548
+ */
549
+ clearInputContextWorkflowAccount = this.mutation(contextControllerclearWorkflowContextInAccount)
550
+
551
+ /**
552
+ * Clear stack workflow context in workspace
553
+ */
554
+ clearInputContextWorkflowWorkspace = this.mutation(contextControllerclearWorkflowContextInWorkspace)
555
+
542
556
  /**
543
557
  * Get Stacks with context
544
558
  */
@@ -559,6 +573,10 @@ class WorkspaceManagerClient extends ReactQueryNetworkClient {
559
573
  * Receives a list of workspace id's and returns that workspaces detailed
560
574
  */
561
575
  workspacesFilterById = this.mutation(workspaceControllergetWorkspacesSummary)
576
+ /**
577
+ * Gets available connection interfaces from a workspace
578
+ */
579
+ availableConnectionInterfaces = this.query(availableConnectionInterfaceControllergetAvailableConnectionInterfaces)
562
580
  }
563
581
 
564
582
  export const workspaceManagerClient = new WorkspaceManagerClient()
@@ -0,0 +1,12 @@
1
+ import { Dictionary } from '@stack-spot/portal-translate'
2
+
3
+ export const accountAssetManagerDictionary = {
4
+ en: {
5
+ FOLDER_BAD_REQUEST_ERROR: 'The provided data is invalid or inconsistent.',
6
+ FOLDER_ALREADY_EXISTS: 'A folder with this name already exists.',
7
+ },
8
+ pt: {
9
+ FOLDER_BAD_REQUEST_ERROR: 'Os dados informados estão inválidos ou inconsistentes.',
10
+ FOLDER_ALREADY_EXISTS: 'Já existe uma pasta com esse nome.',
11
+ },
12
+ } satisfies Dictionary
package/src/index.ts CHANGED
@@ -1,6 +1,7 @@
1
1
  export { CancelledError } from '@tanstack/react-query'
2
- export { apiAddresses, getApiAddresses, getApisByTenant, getBaseUrlByTenantWithOverride, setApisOverride } from './api-addresses'
2
+ export { apiAddresses, getApiAddresses, getApisBaseUrlConfig, getBaseUrlByTenantWithOverride } from './api-addresses'
3
3
  export { accountClient } from './client/account'
4
+ export { accountAssetManagerClient } from './client/account-asset-manager'
4
5
  export { agentClient } from './client/agent'
5
6
  export { agentToolsClient } from './client/agent-tools'
6
7
  export { aiClient } from './client/ai'
@@ -15,6 +16,7 @@ export { contentClient } from './client/content'
15
16
  export { dataIntegrationClient } from './client/data-integration'
16
17
  export * from './client/discover'
17
18
  export { discoverClient } from './client/discover'
19
+ export { edpBfaClient } from './client/edp-bfa'
18
20
  export { eventBusClient } from './client/event-bus'
19
21
  export { genAiInferenceClient } from './client/gen-ai-inference'
20
22
  export { insightsClient } from './client/insights'
@@ -41,3 +43,4 @@ export { StreamedArray } from './utils/StreamedArray'
41
43
  export { StreamedJson } from './utils/StreamedJson'
42
44
  export { useExtendedList } from './utils/use-extended-list'
43
45
  export { useStreamedArray } from './utils/use-streamed-array'
46
+
@@ -1,8 +1,9 @@
1
- import { AuthenticationError, SessionExpiredError } from '@stack-spot/auth'
2
- import { requestPermission } from '@stack-spot/opa'
1
+ import { AuthenticationError, Session, SessionExpiredError } from '@stack-spot/auth'
2
+ import { requestPermission, setup as setupPermissions } from '@stack-spot/opa'
3
3
  import { events } from 'fetch-event-stream'
4
- import { getBaseUrlByTenantWithOverride } from '../api-addresses'
4
+ import { getApisBaseUrlConfig, getBaseUrlByTenantWithOverride, getPermissionsAPIMap } from '../api-addresses'
5
5
  import { StackspotAPIError } from '../error/StackspotAPIError'
6
+ import { queryClient } from './react-query-client'
6
7
  import { Env, FetchEventStream, HTTPMethod, SessionManager, Tenant } from './types'
7
8
 
8
9
  /**
@@ -41,6 +42,14 @@ export abstract class NetworkClient {
41
42
  NetworkClient.sessionManager = sessionManager
42
43
  NetworkClient.env = env
43
44
  NetworkClient.tenant = tenant
45
+ const url = getApisBaseUrlConfig(env, tenant).permissionValidation
46
+ const apiMap = getPermissionsAPIMap(env, tenant)
47
+ const onChange = (session?: Session) => {
48
+ queryClient.invalidateQueries()
49
+ session && setupPermissions({ url, session, apiMap })
50
+ }
51
+ sessionManager.onChange?.(onChange)
52
+ if (sessionManager.hasSession()) onChange(sessionManager.getSession())
44
53
  }
45
54
 
46
55
  /**
@@ -65,7 +74,7 @@ export abstract class NetworkClient {
65
74
  * @returns the final baseURL for the current environment, considering overrides if available.
66
75
  */
67
76
  protected getBaseURL(): string {
68
- return getBaseUrlByTenantWithOverride(this.baseURL, NetworkClient.env, NetworkClient.tenant);
77
+ return getBaseUrlByTenantWithOverride(this.baseURL, NetworkClient.env, NetworkClient.tenant)
69
78
  }
70
79
 
71
80
  /**
@@ -8,6 +8,7 @@ export interface SessionManager {
8
8
  hasSession(): boolean,
9
9
  endSession(): void,
10
10
  getSession(): Session,
11
+ onChange?: (listener: (session: Session | undefined) => void) => (() => void),
11
12
  }
12
13
 
13
14
  export type Tenant = 'stackspot' | 'itau'