@stack-spot/portal-network 0.196.0 → 0.197.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 (104) hide show
  1. package/CHANGELOG.md +124 -0
  2. package/dist/api/agent-tools.d.ts +139 -148
  3. package/dist/api/agent-tools.d.ts.map +1 -1
  4. package/dist/api/agent-tools.js +41 -4
  5. package/dist/api/agent-tools.js.map +1 -1
  6. package/dist/api/agent.d.ts +55 -55
  7. package/dist/api/agent.d.ts.map +1 -1
  8. package/dist/api/ai.d.ts +288 -19
  9. package/dist/api/ai.d.ts.map +1 -1
  10. package/dist/api/ai.js +196 -11
  11. package/dist/api/ai.js.map +1 -1
  12. package/dist/api/cloudPlatformHorizon.d.ts +178 -9
  13. package/dist/api/cloudPlatformHorizon.d.ts.map +1 -1
  14. package/dist/api/cloudPlatformHorizon.js +69 -1
  15. package/dist/api/cloudPlatformHorizon.js.map +1 -1
  16. package/dist/api/codeShift.d.ts +316 -32
  17. package/dist/api/codeShift.d.ts.map +1 -1
  18. package/dist/api/codeShift.js +172 -8
  19. package/dist/api/codeShift.js.map +1 -1
  20. package/dist/api/dataIntegration.d.ts +291 -1
  21. package/dist/api/dataIntegration.d.ts.map +1 -1
  22. package/dist/api/dataIntegration.js +254 -0
  23. package/dist/api/dataIntegration.js.map +1 -1
  24. package/dist/api/discover.d.ts +95 -12
  25. package/dist/api/discover.d.ts.map +1 -1
  26. package/dist/api/discover.js +78 -2
  27. package/dist/api/discover.js.map +1 -1
  28. package/dist/api-addresses.d.ts.map +1 -1
  29. package/dist/client/account.d.ts +233 -233
  30. package/dist/client/account.d.ts.map +1 -1
  31. package/dist/client/agent-tools.d.ts +159 -126
  32. package/dist/client/agent-tools.d.ts.map +1 -1
  33. package/dist/client/agent-tools.js +35 -4
  34. package/dist/client/agent-tools.js.map +1 -1
  35. package/dist/client/agent.d.ts +46 -46
  36. package/dist/client/agent.d.ts.map +1 -1
  37. package/dist/client/ai.d.ts +134 -108
  38. package/dist/client/ai.d.ts.map +1 -1
  39. package/dist/client/ai.js +29 -2
  40. package/dist/client/ai.js.map +1 -1
  41. package/dist/client/api-management.d.ts +2 -2
  42. package/dist/client/cloud-account.d.ts +13 -13
  43. package/dist/client/cloud-platform-horizon.d.ts +38 -19
  44. package/dist/client/cloud-platform-horizon.d.ts.map +1 -1
  45. package/dist/client/cloud-platform-horizon.js +19 -1
  46. package/dist/client/cloud-platform-horizon.js.map +1 -1
  47. package/dist/client/cloud-platform.d.ts +50 -50
  48. package/dist/client/cloud-runtimes.d.ts +4 -4
  49. package/dist/client/cloud-services.d.ts +17 -17
  50. package/dist/client/cloud-services.d.ts.map +1 -1
  51. package/dist/client/code-shift.d.ts +338 -265
  52. package/dist/client/code-shift.d.ts.map +1 -1
  53. package/dist/client/code-shift.js +64 -1
  54. package/dist/client/code-shift.js.map +1 -1
  55. package/dist/client/content.d.ts +127 -132
  56. package/dist/client/content.d.ts.map +1 -1
  57. package/dist/client/data-integration.d.ts +85 -55
  58. package/dist/client/data-integration.d.ts.map +1 -1
  59. package/dist/client/data-integration.js +22 -2
  60. package/dist/client/data-integration.js.map +1 -1
  61. package/dist/client/discover.d.ts +29 -9
  62. package/dist/client/discover.d.ts.map +1 -1
  63. package/dist/client/discover.js +236 -1
  64. package/dist/client/discover.js.map +1 -1
  65. package/dist/client/event-bus.d.ts.map +1 -1
  66. package/dist/client/gen-ai-inference.d.ts +20 -20
  67. package/dist/client/insights.d.ts +7 -7
  68. package/dist/client/notification.d.ts +10 -10
  69. package/dist/client/runtime-manager.d.ts +8 -8
  70. package/dist/client/secrets.d.ts.map +1 -1
  71. package/dist/client/secrets.js +1 -1
  72. package/dist/client/secrets.js.map +1 -1
  73. package/dist/client/types.d.ts +14 -0
  74. package/dist/client/types.d.ts.map +1 -1
  75. package/dist/client/workflow.d.ts +10 -10
  76. package/dist/client/workspace-ai.d.ts +53 -53
  77. package/dist/client/workspace-manager.d.ts +77 -77
  78. package/dist/client/workspace-search.d.ts +2 -2
  79. package/dist/client/workspace.d.ts +58 -105
  80. package/dist/client/workspace.d.ts.map +1 -1
  81. package/dist/error/dictionary/cloud-platform.d.ts +6 -0
  82. package/dist/error/dictionary/cloud-platform.d.ts.map +1 -1
  83. package/dist/error/dictionary/cloud-platform.js +6 -0
  84. package/dist/error/dictionary/cloud-platform.js.map +1 -1
  85. package/dist/utils/StreamedJson.d.ts.map +1 -1
  86. package/dist/utils/StreamedJson.js +9 -1
  87. package/dist/utils/StreamedJson.js.map +1 -1
  88. package/package.json +2 -2
  89. package/src/api/agent-tools.ts +186 -150
  90. package/src/api/ai.ts +521 -24
  91. package/src/api/cloudPlatformHorizon.ts +412 -9
  92. package/src/api/codeShift.ts +631 -37
  93. package/src/api/dataIntegration.ts +635 -1
  94. package/src/api/discover.ts +180 -14
  95. package/src/client/agent-tools.ts +26 -4
  96. package/src/client/ai.ts +25 -10
  97. package/src/client/cloud-platform-horizon.ts +12 -4
  98. package/src/client/code-shift.ts +40 -1
  99. package/src/client/data-integration.ts +15 -1
  100. package/src/client/discover.ts +233 -3
  101. package/src/client/secrets.ts +1 -1
  102. package/src/client/types.ts +17 -2
  103. package/src/error/dictionary/cloud-platform.ts +6 -0
  104. package/src/utils/StreamedJson.tsx +9 -2
@@ -1,12 +1,17 @@
1
1
  import { HttpError } from '@oazapfts/runtime'
2
+ import { findLast, last } from 'lodash'
2
3
  import { getApiAddresses } from '../api-addresses'
3
4
  import { ConversationResponse } from '../api/ai'
4
- import { create, create1, create2, defaults, deleteById, deleteById1, deleteById2, getAll, getAll1, getAll2, getAllByHypothesis, getById, getById1, getById2, GetOpportunityResponse } from '../api/discover'
5
+ import { create, create1, create2, defaults, deleteById, deleteById1, deleteById2, fetchInsights, getAll, getAll1, getAll2, getAllByHypothesis, getById, getById1, getById2, getInsightById, GetOpportunityResponse, MessageRequest, refreshInsights } from '../api/discover'
5
6
  import { DefaultAPIError } from '../error/DefaultAPIError'
6
7
  import { StackspotAPIError } from '../error/StackspotAPIError'
8
+ import { StreamedJson } from '../utils/StreamedJson'
7
9
  import { baseDictionary } from '../error/dictionary/base'
10
+ import { formatJson } from '../utils/string'
8
11
  import { ReactQueryNetworkClient } from '../network/ReactQueryNetworkClient'
9
12
  import { aiClient } from './ai'
13
+ import { ChatAgentTool, ChatResponseWithSteps, FixedChatResponse, StepChatStep } from './types'
14
+ import { agentToolsClient } from './agent-tools'
10
15
 
11
16
  export interface ChatConversionDetails extends ConversationResponse {
12
17
  opportunityName?: string,
@@ -48,6 +53,19 @@ class DiscoverClient extends ReactQueryNetworkClient {
48
53
 
49
54
  deleteDocument = this.mutation(deleteById2)
50
55
 
56
+ /**
57
+ * Fetch insights
58
+ */
59
+ insights = this.query(fetchInsights)
60
+ /**
61
+ * Refresh insights
62
+ */
63
+ refreshInsights = this.mutation(refreshInsights)
64
+ /**
65
+ * Get Insight by Id
66
+ */
67
+ insightById = this.query(getInsightById)
68
+
51
69
  chats = this.query({
52
70
  name: 'chats',
53
71
  request: async (_signal, variables: { filter?: string, page?: number, size?: number }) => {
@@ -67,8 +85,8 @@ class DiscoverClient extends ReactQueryNetworkClient {
67
85
  { ...variables, page: variables.page, size: variables.size ?? 40 },
68
86
  )
69
87
 
70
- const filteredItems = variables.filter
71
- ? chatsHistory.filter((chat) => chat.title.toLowerCase().includes(variables.filter!.toLowerCase()))
88
+ const filteredItems = variables.filter
89
+ ? chatsHistory.filter((chat) => chat.title.toLowerCase().includes(variables.filter!.toLowerCase()))
72
90
  : chatsHistory
73
91
 
74
92
  const enrichedChats = filteredItems?.map(chat => {
@@ -84,6 +102,218 @@ class DiscoverClient extends ReactQueryNetworkClient {
84
102
  return enrichedChats as ChatConversionDetails[]
85
103
  },
86
104
  })
105
+
106
+ private static async toolsOfAgent(agentId?: string) {
107
+ try {
108
+ const agent = agentId ? await agentToolsClient.agent.query({ agentId }) : undefined
109
+ if (!agent) return []
110
+ const tools: (Omit<ChatAgentTool, 'duration' | 'prompt' | 'output'>)[] = []
111
+ agent.toolkits?.builtin_toolkits?.forEach(kit => kit.tools?.forEach(({ id, name, description }) => {
112
+ if (id) tools.push({ image: kit.image_url, id, name: name || id, description })
113
+ }))
114
+ agent.toolkits?.custom_toolkits?.forEach(kit => kit.tools?.forEach(({ id, name, description }) => {
115
+ if (id) tools.push({ image: kit.avatar ?? undefined, id, name: name || id, description })
116
+ }))
117
+ return tools
118
+ } catch {
119
+ return []
120
+ }
121
+ }
122
+
123
+
124
+ sendChatMessage(request: MessageRequest & { agentId: string }, minChangeIntervalMS?: number): StreamedJson<ChatResponseWithSteps> {
125
+ const abortController = new AbortController()
126
+ const headers = {
127
+ 'Content-Type': 'application/json',
128
+ 'Accept': 'text/event-stream',
129
+ }
130
+ const events = this.stream(
131
+ this.resolveURL('/v2/ai/chat'),
132
+ { method: 'post', body: JSON.stringify(request), headers, signal: abortController.signal },
133
+ )
134
+ /**
135
+ * This function treats events in the streaming that deals with the execution of tools. Since these events are not concatenated like
136
+ * normal streamings of data, we need this separate function to deal with them. It transforms the internal data model of the
137
+ * StreamedJson object whenever an event is triggered.
138
+ */
139
+ async function transform(event: Partial<FixedChatResponse>, data: Partial<ChatResponseWithSteps>) {
140
+ const info = event.agent_info
141
+
142
+ if (!info) return
143
+
144
+ const tools = await DiscoverClient.toolsOfAgent(request.agentId)
145
+ data.steps = data.steps ? [...data.steps] : []
146
+
147
+ if (info.type === 'planning' && info.action === 'end') {
148
+ data.steps.push({
149
+ id: 'planning',
150
+ type: 'planning',
151
+ status: 'success',
152
+ duration: info.duration || 0,
153
+ steps: info.data?.steps?.map(s => s.goal) ?? [],
154
+ goal: info.data?.plan_goal ?? '',
155
+ })
156
+
157
+ info.data?.steps.forEach(s => data.steps?.push({
158
+ id: s.id,
159
+ type: 'step',
160
+ status: 'pending',
161
+ input: s.goal,
162
+ attempts: [{
163
+ tools: s.tools?.map(t => ({
164
+ ...(tools.find(({ id }) => id === t.tool_id) ?? { id: t.tool_id, name: t.tool_id }),
165
+ executionId: t.tool_execution_id,
166
+ goal: t.goal,
167
+ })),
168
+ }],
169
+ }))
170
+ data.steps.push({ id: 'answer', type: 'answer', status: 'pending' })
171
+ }
172
+
173
+ if (info.type === 'planning' && info.action === 'awaiting_approval') {
174
+ data.steps.push({
175
+ id: 'planning',
176
+ type: 'planning',
177
+ status: 'awaiting_approval',
178
+ user_question: info.data?.user_question,
179
+ duration: info.duration || 0,
180
+ steps: info.data?.steps?.map(s => s.goal) ?? [],
181
+ goal: info.data?.plan_goal ?? '',
182
+ })
183
+ info.data?.steps.forEach(s => data.steps?.push({
184
+ id: s.id,
185
+ type: 'step',
186
+ status: 'pending',
187
+ input: s.goal,
188
+ attempts: [{
189
+ tools: s.tools?.map(t => ({
190
+ ...(tools.find(({ id }) => id === t.tool_id) ?? { id: t.tool_id, name: t.tool_id }),
191
+ executionId: t.tool_execution_id,
192
+ goal: t.goal,
193
+ })),
194
+ }],
195
+ }))
196
+ data.steps.push({ id: 'answer', type: 'answer', status: 'pending' })
197
+ }
198
+
199
+ if (info.type === 'step' && info.action === 'start') {
200
+ const step = data.steps.find(s => s.id === info.id)
201
+ if (step) step.status = 'running'
202
+ }
203
+
204
+ if (info.type === 'step' && info.action === 'end') {
205
+ const step = data.steps.find(s => s.id === info.id) as StepChatStep
206
+ if (step) {
207
+ step.status = 'success'
208
+ step.duration = info.duration
209
+ const lastToolId = last(step.attempts[0].tools)?.id
210
+ const lastAttemptOfLastTool = findLast(step.attempts.map(a => a.tools).flat(), t => t?.id === lastToolId)
211
+ step.output = lastAttemptOfLastTool?.output
212
+ }
213
+ }
214
+
215
+ if (info.type === 'tool' && info.action === 'awaiting_approval') {
216
+ const tool = tools.find(({ id }) => id === info.data?.tool_id)
217
+ data.steps.push({
218
+ id: info.id,
219
+ type: 'tool',
220
+ status: 'awaiting_approval',
221
+ duration: info.duration || 0,
222
+ input: info.data?.input,
223
+ user_question: info.data?.user_question,
224
+ attempts: [{
225
+ tools: [{
226
+ executionId: info.id,
227
+ id: info.data?.tool_id ?? '',
228
+ name: tool?.name ?? '',
229
+ goal: tool?.goal,
230
+ ...tool,
231
+ }],
232
+ }],
233
+ })
234
+ data.steps.push({ id: 'answer', type: 'answer', status: 'pending' })
235
+ }
236
+
237
+ if (info.type === 'tool' && info.action === 'start') {
238
+ const currentStep = data.steps.find(s => s.status === 'running') as StepChatStep
239
+ if (!info.data) return
240
+
241
+ //There might be a tool with status awaiting_approval, so we want to inform tool has already started
242
+ if (!currentStep || !currentStep.attempts[0].tools) {
243
+ const input = formatJson(info.data.input)
244
+ const tool = tools.find(({ id }) => id === info.data?.tool_id) ?? { id: info.data?.tool_id, name: info.data?.tool_id }
245
+ data.steps.push({
246
+ id: info.id,
247
+ type: 'tool',
248
+ status: 'running',
249
+ duration: info.duration || 0,
250
+ input: info.data?.input,
251
+ user_question: info.data?.user_question,
252
+ attempts: [{
253
+ tools: [{ ...tool, executionId: info.id, input }],
254
+ }],
255
+ })
256
+ } else {
257
+ const toolInFirstAttempt = currentStep.attempts[0].tools?.find(t => t.executionId === info.id)
258
+ //One step might have multiple tools. When in an approval mode, we might not have all the tools in the array yet.
259
+ //So we make sure to add any tools that are not in there.
260
+ if (!toolInFirstAttempt) {
261
+ const input = formatJson(info.data.input)
262
+ const tool = tools?.find(({ id }) => id === info.data?.tool_id) ?? { id: info.data?.tool_id, name: info.data?.tool_id }
263
+ currentStep.attempts[info.data.attempt - 1].tools?.push({
264
+ ...tool,
265
+ executionId: info.id,
266
+ input,
267
+ })
268
+ } else {
269
+ const input = formatJson(info.data.input)
270
+ if (info.data.attempt === 1) {
271
+ toolInFirstAttempt.input = input
272
+ } else {
273
+ const tool = tools.find(({ id }) => id === info.data?.tool_id) ?? { id: info.data?.tool_id, name: info.data?.tool_id }
274
+ currentStep.attempts[info.data.attempt - 1] ??= { tools: [] }
275
+ currentStep.attempts[info.data.attempt - 1].tools?.push({
276
+ ...tool,
277
+ executionId: info.id,
278
+ input,
279
+ })
280
+ }
281
+ }
282
+ }
283
+ }
284
+
285
+ if (info.type === 'tool' && info.action === 'end') {
286
+ const currentStep = data.steps.find(s => s.status === 'running') as StepChatStep
287
+ if (!currentStep || !info.data) return
288
+ const tool = currentStep.attempts[info.data.attempt - 1]?.tools?.find(t => t.executionId === info.id)
289
+ if (tool) {
290
+ tool.output = formatJson(info.data.output)
291
+ tool.duration = info.duration
292
+ }
293
+ }
294
+
295
+ if (info.type === 'final_answer' && info.action === 'start') {
296
+ const answerStep = last(data.steps)
297
+ if (answerStep) answerStep.status = 'running'
298
+ }
299
+
300
+ if (info.type === 'chat' && info.action === 'end') {
301
+ const answerStep = last(data.steps)
302
+ if (answerStep) {
303
+ answerStep.status = 'success'
304
+ answerStep.duration = info.duration
305
+ }
306
+ }
307
+ }
308
+
309
+ return new StreamedJson({
310
+ eventsPromise: events,
311
+ abortController,
312
+ minChangeIntervalMS,
313
+ ignoreKeys: ['agent_info'],
314
+ transform,
315
+ })
316
+ }
87
317
  }
88
318
 
89
319
  export const discoverClient = new DiscoverClient()
@@ -1,11 +1,11 @@
1
1
  import { HttpError } from '@oazapfts/runtime'
2
2
 
3
+ import { getApiAddresses } from '../api-addresses'
3
4
  import { createKey, defaults, deleteKey, deleteSecretValue, editKey, encrypt, getAll1, getAvailability, updateSecretValue } from '../api/secrets'
4
5
  import { DefaultAPIError } from '../error/DefaultAPIError'
5
6
  import { secretsDictionary } from '../error/dictionary/secrets'
6
7
  import { StackspotAPIError } from '../error/StackspotAPIError'
7
8
  import { ReactQueryNetworkClient } from '../network/ReactQueryNetworkClient'
8
- import { getApiAddresses } from '../api-addresses'
9
9
 
10
10
  class SecretClient extends ReactQueryNetworkClient {
11
11
  constructor() {
@@ -361,10 +361,25 @@ export interface FixedChatResponse extends ChatResponse3 {
361
361
  agent_info: AgentInfo,
362
362
  tools?: string[],
363
363
  }
364
+ export interface OpportunitiesPMAgent {
365
+ title: string,
366
+ description: string,
367
+ }
368
+
369
+ export type HypothesisPMAgent = OpportunitiesPMAgent
364
370
 
371
+ export type PrfaqPMAgent = {
372
+ title: string,
373
+ content: string,
374
+ }
365
375
  export interface ChatResponseWithSteps extends FixedChatResponse {
366
376
  steps: ChatStep[],
367
377
  }
378
+ export interface ChatResponseWithPMResources {
379
+ opportunities?: OpportunitiesPMAgent[],
380
+ hypothesis?: HypothesisPMAgent[],
381
+ prfaq?: PrfaqPMAgent,
382
+ }
368
383
 
369
384
  export type OazapftsFunction<Variables = any, Result = any> = (variables: Variables, opts?: RequestOpts) => Promise<Result>
370
385
 
@@ -380,12 +395,12 @@ export type FixVariables<
380
395
 
381
396
  export type ReplaceResult<T extends (...args: any[]) => Promise<any>, Fix> = (...args: Parameters<T>) => Promise<Fix>
382
397
 
383
- export interface AgentResponseWithBuiltIn extends Omit<ListAgentResponse, 'conversation_starter' | 'avatar'> {
398
+ export interface AgentResponseWithBuiltIn extends Omit<ListAgentResponse, 'conversation_starter' | 'avatar'> {
384
399
  builtIn?: boolean,
385
400
  spaceName?: string,
386
401
  conversation_starter?: string[] | null,
387
402
  avatar?: string | null | undefined,
388
- }
403
+ }
389
404
 
390
405
  export type AgentVisibilityLevel = AgentVisibilityLevelEnum | VisibilityLevelEnum
391
406
 
@@ -39,6 +39,9 @@ export const scfDictionary = {
39
39
  SCF_VPN_ERROR: 'VPN operation failed.',
40
40
  SCF_VPN_NOT_FOUND_ERROR: 'VPN with ID {1} not found.',
41
41
  SCF_VPN_NOT_READY_ERROR: 'VPN with ID {1} not ready.',
42
+ SCF_DNS_ZONE_NOT_EMPTY_ERROR: 'DNS Zone with ID {1} is not empty.',
43
+ SCF_FOLDER_NOT_EMPTY_ERROR: 'Folder with ID {1} is not empty.',
44
+ SCF_PROJECT_NOT_EMPTY_ERROR: 'Project with ID {1} is not empty.',
42
45
  },
43
46
  pt: {
44
47
  SCF_CERTIFICATE_ERROR: 'Falha na operação de Certificado.',
@@ -78,5 +81,8 @@ export const scfDictionary = {
78
81
  SCF_VPN_ERROR: 'Falha na operação de VPN.',
79
82
  SCF_VPN_NOT_FOUND_ERROR: 'VPN com ID {1} não encontrada.',
80
83
  SCF_VPN_NOT_READY_ERROR: 'VPN com ID {1} não está pronta.',
84
+ SCF_DNS_ZONE_NOT_EMPTY_ERROR: 'DNS Zone com ID {1} não está vazia.',
85
+ SCF_FOLDER_NOT_EMPTY_ERROR: 'Folder com ID {1} não está vazia.',
86
+ SCF_PROJECT_NOT_EMPTY_ERROR: 'Project com ID {1} não está vazia.',
81
87
  },
82
88
  } satisfies Dictionary
@@ -64,7 +64,14 @@ export class StreamedJson<T> {
64
64
  for await (const event of events) {
65
65
  if (this.error) return
66
66
  if (event.data) {
67
- const json = JSON.parse(event.data)
67
+ let json
68
+ try {
69
+ json = JSON.parse(event.data)
70
+ } catch (e) {
71
+ // eslint-disable-next-line no-console
72
+ console.warn('Mal formed JSON in streaming:', event.data)
73
+ continue
74
+ }
68
75
  await this.transform?.(json, this.data)
69
76
  this.merge(json, this.data)
70
77
  if (new Date().getTime() - lastChangeCall >= minChangeIntervalMS) {
@@ -138,7 +145,7 @@ export class StreamedJson<T> {
138
145
  onChange(listener: (value: Partial<T>) => void) {
139
146
  if (this.fullPromise.resolved) {
140
147
  listener(this.data)
141
- return () => {}
148
+ return () => { }
142
149
  }
143
150
  this.onChangeListeners.push(listener)
144
151
  return () => {