@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.
- package/CHANGELOG.md +259 -0
- package/dist/api/account.d.ts +344 -91
- package/dist/api/account.d.ts.map +1 -1
- package/dist/api/account.js +203 -46
- package/dist/api/account.js.map +1 -1
- package/dist/api/accountAssetManager.d.ts +309 -0
- package/dist/api/accountAssetManager.d.ts.map +1 -0
- package/dist/api/accountAssetManager.js +169 -0
- package/dist/api/accountAssetManager.js.map +1 -0
- package/dist/api/agent-tools.d.ts +623 -141
- package/dist/api/agent-tools.d.ts.map +1 -1
- package/dist/api/agent-tools.js +168 -45
- package/dist/api/agent-tools.js.map +1 -1
- package/dist/api/ai.d.ts +135 -24
- package/dist/api/ai.d.ts.map +1 -1
- package/dist/api/ai.js +79 -26
- package/dist/api/ai.js.map +1 -1
- package/dist/api/codeShift.d.ts +140 -10
- package/dist/api/codeShift.d.ts.map +1 -1
- package/dist/api/codeShift.js +73 -6
- package/dist/api/codeShift.js.map +1 -1
- package/dist/api/discover.d.ts +9 -6
- package/dist/api/discover.d.ts.map +1 -1
- package/dist/api/discover.js +5 -5
- package/dist/api/discover.js.map +1 -1
- package/dist/api/edpBfa.d.ts +215 -0
- package/dist/api/edpBfa.d.ts.map +1 -0
- package/dist/api/edpBfa.js +87 -0
- package/dist/api/edpBfa.js.map +1 -0
- package/dist/api/genAiInference.d.ts +49 -2
- package/dist/api/genAiInference.d.ts.map +1 -1
- package/dist/api/genAiInference.js +55 -2
- package/dist/api/genAiInference.js.map +1 -1
- package/dist/api/workspace-ai.d.ts +41 -0
- package/dist/api/workspace-ai.d.ts.map +1 -1
- package/dist/api/workspace-ai.js +34 -0
- package/dist/api/workspace-ai.js.map +1 -1
- package/dist/api-addresses.d.ts +13 -20
- package/dist/api-addresses.d.ts.map +1 -1
- package/dist/api-addresses.js +60 -17
- package/dist/api-addresses.js.map +1 -1
- package/dist/apis-itau.json +16 -0
- package/dist/apis.json +16 -0
- package/dist/client/account-asset-manager.d.ts +112 -0
- package/dist/client/account-asset-manager.d.ts.map +1 -0
- package/dist/client/account-asset-manager.js +160 -0
- package/dist/client/account-asset-manager.js.map +1 -0
- package/dist/client/account.d.ts +11 -9
- package/dist/client/account.d.ts.map +1 -1
- package/dist/client/account.js +11 -8
- package/dist/client/account.js.map +1 -1
- package/dist/client/agent-tools.d.ts +122 -3
- package/dist/client/agent-tools.d.ts.map +1 -1
- package/dist/client/agent-tools.js +105 -10
- package/dist/client/agent-tools.js.map +1 -1
- package/dist/client/ai.d.ts +149 -4
- package/dist/client/ai.d.ts.map +1 -1
- package/dist/client/ai.js +93 -208
- package/dist/client/ai.js.map +1 -1
- package/dist/client/code-shift.d.ts +54 -3
- package/dist/client/code-shift.d.ts.map +1 -1
- package/dist/client/code-shift.js +46 -1
- package/dist/client/code-shift.js.map +1 -1
- package/dist/client/data-integration.d.ts.map +1 -1
- package/dist/client/data-integration.js +8 -1
- package/dist/client/data-integration.js.map +1 -1
- package/dist/client/discover.d.ts +3 -3
- package/dist/client/discover.d.ts.map +1 -1
- package/dist/client/discover.js +4 -3
- package/dist/client/discover.js.map +1 -1
- package/dist/client/edp-bfa.d.ts +16 -0
- package/dist/client/edp-bfa.d.ts.map +1 -0
- package/dist/client/edp-bfa.js +24 -0
- package/dist/client/edp-bfa.js.map +1 -0
- package/dist/client/gen-ai-inference.d.ts +4 -0
- package/dist/client/gen-ai-inference.d.ts.map +1 -1
- package/dist/client/gen-ai-inference.js +267 -0
- package/dist/client/gen-ai-inference.js.map +1 -1
- package/dist/client/notification.d.ts +7 -0
- package/dist/client/notification.d.ts.map +1 -1
- package/dist/client/notification.js +10 -1
- package/dist/client/notification.js.map +1 -1
- package/dist/client/types.d.ts +24 -17
- package/dist/client/types.d.ts.map +1 -1
- package/dist/client/workspace-ai.d.ts +13 -3
- package/dist/client/workspace-ai.d.ts.map +1 -1
- package/dist/client/workspace-ai.js +17 -3
- package/dist/client/workspace-ai.js.map +1 -1
- package/dist/client/workspace-manager.d.ts +24 -0
- package/dist/client/workspace-manager.d.ts.map +1 -1
- package/dist/client/workspace-manager.js +28 -1
- package/dist/client/workspace-manager.js.map +1 -1
- package/dist/error/dictionary/accountAssetManager.d.ts +11 -0
- package/dist/error/dictionary/accountAssetManager.d.ts.map +1 -0
- package/dist/error/dictionary/accountAssetManager.js +11 -0
- package/dist/error/dictionary/accountAssetManager.js.map +1 -0
- package/dist/index.d.ts +3 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/network/NetworkClient.d.ts.map +1 -1
- package/dist/network/NetworkClient.js +12 -2
- package/dist/network/NetworkClient.js.map +1 -1
- package/dist/network/types.d.ts +1 -0
- package/dist/network/types.d.ts.map +1 -1
- package/dist/utils/StreamedJson.d.ts +9 -1
- package/dist/utils/StreamedJson.d.ts.map +1 -1
- package/dist/utils/StreamedJson.js +22 -2
- package/dist/utils/StreamedJson.js.map +1 -1
- package/package.json +2 -2
- package/readme.md +39 -1
- package/src/api/account.ts +592 -165
- package/src/api/accountAssetManager.ts +771 -0
- package/src/api/agent-tools.ts +824 -188
- package/src/api/ai.ts +206 -38
- package/src/api/codeShift.ts +246 -13
- package/src/api/discover.ts +10 -10
- package/src/api/edpBfa.ts +472 -0
- package/src/api/genAiInference.ts +119 -3
- package/src/api/workspace-ai.ts +83 -0
- package/src/api-addresses.ts +93 -37
- package/src/apis-itau.json +16 -0
- package/src/apis.json +16 -0
- package/src/client/account-asset-manager.ts +100 -0
- package/src/client/account.ts +11 -7
- package/src/client/agent-tools.ts +69 -16
- package/src/client/ai.ts +60 -213
- package/src/client/code-shift.ts +29 -0
- package/src/client/data-integration.ts +9 -2
- package/src/client/discover.ts +8 -7
- package/src/client/edp-bfa.ts +24 -0
- package/src/client/gen-ai-inference.ts +281 -0
- package/src/client/notification.ts +6 -1
- package/src/client/types.ts +26 -17
- package/src/client/workspace-ai.ts +21 -6
- package/src/client/workspace-manager.ts +18 -0
- package/src/error/dictionary/accountAssetManager.ts +12 -0
- package/src/index.ts +4 -1
- package/src/network/NetworkClient.ts +13 -4
- package/src/network/types.ts +1 -0
- 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()
|
package/src/client/types.ts
CHANGED
|
@@ -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 {
|
|
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
|
-
|
|
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
|
|
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
|
|
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
|
|
361
|
-
agent_info: AgentInfo,
|
|
362
|
-
|
|
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 {
|
|
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 {
|
|
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<
|
|
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,
|
|
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
|
/**
|
package/src/network/types.ts
CHANGED