mitra-interactions-sdk 1.0.65 → 1.0.66

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/README.md CHANGED
@@ -1,725 +1,769 @@
1
- # Mitra Interactions SDK
2
-
3
- SDK para interações com a plataforma Mitra via endpoints `/interactions/`.
4
-
5
- ## Permissões: `dev` vs `business`
6
-
7
- `userType` no token de login:
8
- - `dev` — chama tudo
9
- - `business` — chama apenas execução (SF, Data Loader, upload), auth e chat. Outras chamadas retornam **403**.
10
-
11
- > Não confundir com o pacote `mitra-business-sdk` (SDK separado, usado pelo agente IA).
12
-
13
- **Bloqueado para `business`:** CRUD REST (`*RecordMitra`), Profile Management (`*ProfileMitra`, `setProfile*Mitra`), `listProjectUsersMitra`, `manageUserAccessMitra`.
14
-
15
- > SF tipo JAVASCRIPT herda o `userType` do caller — se chamar funções bloqueadas, retorna 403 para business.
16
-
17
- ---
18
-
19
- ## Instalação
20
-
21
- ```bash
22
- npm install mitra-interactions-sdk
23
- # ou
24
- yarn add mitra-interactions-sdk
25
- # ou
26
- pnpm add mitra-interactions-sdk
27
- ```
28
-
29
- ## Configuração
30
-
31
- Antes de usar qualquer função, configure o SDK. O `token` é **opcional** — Server Functions públicas podem ser chamadas sem autenticação.
32
-
33
- > **Importante:** Quando usado, o token é um JWT de autenticação da plataforma Mitra. **Nunca deixe o token estático no código.** Utilize variáveis de ambiente para armazená-lo de forma segura.
34
-
35
- ```typescript
36
- import { configureSdkMitra } from 'mitra-interactions-sdk';
37
-
38
- // Configuração completa (com autenticação)
39
- const instance = configureSdkMitra({
40
- baseURL: process.env.MITRA_BASE_URL || 'https://api.mitra.com',
41
- token: process.env.MITRA_TOKEN!, // Opcional — necessário apenas para endpoints autenticados
42
- authUrl: 'https://coder.mitralab.io/sdk-auth/', // Opcional — necessário para login e token refresh
43
- projectId: 123, // Opcional — se informado, torna projectId opcional em TODOS os métodos
44
- integrationURL: 'https://api0.mitraecp.com:1003', // Opcional — necessário para integrações
45
- onTokenRefresh: (session) => { // Opcional — chamado quando o token é renovado automaticamente
46
- localStorage.setItem('mitra_session', JSON.stringify(session));
47
- }
48
- });
49
-
50
- // Configuração mínima (sem token — apenas para Server Functions públicas)
51
- const instance = configureSdkMitra({
52
- baseURL: 'https://api.mitra.com',
53
- projectId: 123
54
- });
55
- await instance.executeServerFunction({ serverFunctionId: 42 }); // OK — sem token
56
- ```
57
-
58
- > **`projectId` global:** Se você passar `projectId` no `configureSdkMitra`, ele será usado como fallback em **todos** os métodos do SDK. Assim, não é necessário passar `projectId` em cada chamada individual — basta configurar uma vez.
59
-
60
- `configureSdkMitra` retorna uma `MitraInstance` que também pode ser usada diretamente:
61
-
62
- ```typescript
63
- await instance.executeServerFunction({ serverFunctionId: 42 }); // projectId já vem do configureSdkMitra
64
- ```
65
-
66
- ## Autenticação (Login)
67
-
68
- Login via popup ou redirect seguro hospedado no domínio Mitra. Credenciais nunca passam pelo código do desenvolvedor. O SDK é **auto-configurado** após o login.
69
-
70
- > **Nota:** `authUrl` e `projectId` são **obrigatórios** para login. Porém, se já foram passados no `configureSdkMitra()`, não é necessário repeti-los — o SDK usa os valores configurados como fallback.
71
-
72
- ### Login via Popup (padrão)
73
-
74
- ```typescript
75
- import { loginMitra } from 'mitra-interactions-sdk';
76
-
77
- // Métodos disponíveis: 'email', 'google', 'microsoft', 'mitra'
78
- // Primeira vez — sem configureSdkMitra: authUrl e projectId são obrigatórios
79
- const result = await loginMitra('email', {
80
- authUrl: 'https://coder.mitralab.io/sdk-auth/',
81
- projectId: 123
82
- });
83
-
84
- // Se já chamou configureSdkMitra({ authUrl, projectId }), basta:
85
- const result = await loginMitra('google');
86
- const result = await loginMitra('microsoft');
87
-
88
- // result: { token, baseURL, integrationURL? }
89
- ```
90
-
91
- ### Login Completo (method 'mitra')
92
-
93
- Abre uma tela com todas as opções (Google, Microsoft, Email) e toggle entre Login/Cadastro.
94
-
95
- ```typescript
96
- await loginMitra('mitra', {
97
- authUrl: 'https://coder.mitralab.io/sdk-auth/',
98
- projectId: 123,
99
- title: 'Meu App' // Opcional — título exibido na tela de login (default: "Mitra")
100
- });
101
- ```
102
-
103
- ### Login via Redirect
104
-
105
- Navega o usuário para a página de auth. Após o login, redireciona de volta com token nos query params.
106
-
107
- ```typescript
108
- import { loginMitra } from 'mitra-interactions-sdk';
109
-
110
- // Iniciar login — o navegador navega para fora da página
111
- await loginMitra('google', {
112
- mode: 'redirect',
113
- returnTo: '/dashboard' // Opcional — URL de retorno após login (default: página atual). Só funciona com mode 'redirect'.
114
- });
115
- ```
116
-
117
- ### Fluxo de Criar Conta
118
-
119
- ```typescript
120
- // create funciona tanto em popup quanto redirect
121
- await loginMitra('email', { create: true });
122
-
123
- await loginMitra('mitra', {
124
- mode: 'redirect',
125
- create: true, // Abre direto no modo cadastro
126
- returnTo: '/onboarding',
127
- title: 'Meu App'
128
- });
129
- ```
130
-
131
- ### Token Refresh Automático
132
-
133
- Quando qualquer requisição retorna **403**, o SDK tenta renovar o token automaticamente via iframe invisível (usa o cookie de sessão do provider). Se o refresh funcionar, a requisição é retentada com o novo token — transparente para o desenvolvedor.
134
-
135
- O callback `onTokenRefresh` é chamado após renovação bem-sucedida:
136
-
137
- ```typescript
138
- configureSdkMitra({
139
- baseURL: '...',
140
- token: '...',
141
- authUrl: 'https://coder.mitralab.io/sdk-auth/',
142
- projectId: 123,
143
- onTokenRefresh: (session) => {
144
- // Atualiza o token salvo (ex: localStorage, store, etc.)
145
- localStorage.setItem('mitra_token', session.token);
146
- }
147
- });
148
- ```
149
-
150
- ### Login por Email (iframe silencioso)
151
-
152
- Para quem precisa montar sua **própria tela de login** (sem popup/redirect), o SDK oferece funções que fazem a autenticação via iframe invisível. As credenciais são enviadas ao HTML de auth via `postMessage` — sem CORS, sem expor a API.
153
-
154
- #### emailSignupMitra
155
-
156
- Cria conta. Após sucesso, o usuário recebe um código de verificação por email.
157
-
158
- ```typescript
159
- import { emailSignupMitra } from 'mitra-interactions-sdk';
160
-
161
- await emailSignupMitra({
162
- name: 'João Silva',
163
- email: 'joao@email.com',
164
- password: 'minhasenha123'
165
- });
166
- // Não retorna token — o próximo passo é verificar o código
167
- ```
168
-
169
- #### emailVerifyCodeMitra
170
-
171
- Verifica o código de 6 dígitos e faz login automático. Retorna `LoginResponse` e auto-configura o SDK.
172
-
173
- ```typescript
174
- import { emailVerifyCodeMitra } from 'mitra-interactions-sdk';
175
-
176
- const session = await emailVerifyCodeMitra({
177
- email: 'joao@email.com',
178
- code: '123456',
179
- password: 'minhasenha123' // Necessário para login automático após verificação
180
- });
181
- // session: { token, baseURL, integrationURL? }
182
- ```
183
-
184
- #### emailResendCodeMitra
185
-
186
- Reenvia o código de verificação para o email.
187
-
188
- ```typescript
189
- import { emailResendCodeMitra } from 'mitra-interactions-sdk';
190
-
191
- await emailResendCodeMitra({ email: 'joao@email.com' });
192
- ```
193
-
194
- #### emailLoginMitra
195
-
196
- Login direto com email e senha. Retorna `LoginResponse` e auto-configura o SDK.
197
-
198
- ```typescript
199
- import { emailLoginMitra } from 'mitra-interactions-sdk';
200
-
201
- const session = await emailLoginMitra({
202
- email: 'joao@email.com',
203
- password: 'minhasenha123'
204
- });
205
- // session: { token, baseURL, integrationURL? }
206
- ```
207
-
208
- #### Fluxo completo de signup com email
209
-
210
- ```typescript
211
- // 1. Criar conta
212
- await emailSignupMitra({ name: 'João', email, password });
213
-
214
- // 2. Usuário recebe código por email e digita na tela
215
- const session = await emailVerifyCodeMitra({ email, code: '123456', password });
216
-
217
- // 3. SDK já está configurado — pode chamar qualquer método
218
- await executeDbActionMitra({ dbActionId: 1 });
219
- ```
220
-
221
- > **Nota:** `authUrl` e `projectId` são opcionais em todas as funções de email se já foram configurados via `configureSdkMitra()`.
222
-
223
- ### Reset de Senha (esqueci minha senha)
224
-
225
- Endpoints públicos (sem token) para o fluxo de "esqueci minha senha":
226
-
227
- ```typescript
228
- import {
229
- sendPasswordResetCodeMitra,
230
- validatePasswordResetCodeMitra,
231
- resetPasswordMitra,
232
- emailLoginMitra
233
- } from 'mitra-interactions-sdk';
234
-
235
- // 1. Envia código de 6 dígitos por email
236
- await sendPasswordResetCodeMitra({ email });
237
-
238
- // 2. (opcional) Valida o código antes de pedir a senha nova
239
- await validatePasswordResetCodeMitra({ email, code: '123456' });
240
-
241
- // 3. Troca a senha
242
- await resetPasswordMitra({ email, code: '123456', newPassword: 'novaSenha' });
243
-
244
- // 4. Login com a nova senha
245
- await emailLoginMitra({ email, password: 'novaSenha' });
246
- ```
247
-
248
- > **Nota:** `projectId` é opcional se já configurado via `configureSdkMitra()`.
249
-
250
- ## Métodos Disponíveis
251
-
252
- ### executeServerFunctionMitra
253
-
254
- Executa uma Server Function de forma **síncrona** (timeout de 60s no backend). Retorna o resultado diretamente.
255
-
256
- ```typescript
257
- import { executeServerFunctionMitra } from 'mitra-interactions-sdk';
258
-
259
- const result = await executeServerFunctionMitra({
260
- projectId: 123,
261
- serverFunctionId: 101,
262
- input: { // Opcional - objeto de entrada para a função
263
- arg1: 'valor1'
264
- }
265
- });
266
- // result: { status, result: { executionId, executionStatus, output, logs, error, durationMs } }
267
- ```
268
-
269
- ### executeServerFunctionAsyncMitra
270
-
271
- Executa uma Server Function de forma **assíncrona**. Retorna um `executionId` imediatamente. Use `stopServerFunctionExecutionMitra` para parar ou `getServerFunctionExecutionMitra` (mitra-sdk) para consultar o resultado.
272
-
273
- ```typescript
274
- import { executeServerFunctionAsyncMitra } from 'mitra-interactions-sdk';
275
-
276
- const result = await executeServerFunctionAsyncMitra({
277
- projectId: 123,
278
- serverFunctionId: 101,
279
- input: { // Opcional - objeto de entrada para a função
280
- arg1: 'valor1'
281
- }
282
- });
283
- // result: { status, result: { executionId, executionStatus } }
284
- ```
285
-
286
- ### stopServerFunctionExecutionMitra
287
-
288
- Para a execução de uma Server Function em andamento.
289
-
290
- ```typescript
291
- import { stopServerFunctionExecutionMitra } from 'mitra-interactions-sdk';
292
-
293
- const result = await stopServerFunctionExecutionMitra({
294
- projectId: 123,
295
- executionId: 'exec-uuid-aqui'
296
- });
297
- // result: { status, result: { executionId, executionStatus: "CANCELLED" | "ALREADY_FINISHED" } }
298
- ```
299
-
300
- ### Public Server Functions (sem autenticação)
301
-
302
- Para Server Functions com `publicExecution = true`. Não requerem token.
303
-
304
- ```typescript
305
- import {
306
- executePublicServerFunctionMitra,
307
- executePublicServerFunctionAsyncMitra,
308
- getPublicServerFunctionExecutionMitra
309
- } from 'mitra-interactions-sdk';
310
-
311
- // Sync — retorna resultado inline (timeout 5min)
312
- const result = await executePublicServerFunctionMitra({
313
- projectId: 123,
314
- serverFunctionId: 49,
315
- input: { param1: 'value' }
316
- });
317
- // result: { executionId, status, output, logs, error, durationMs }
318
-
319
- // Async — retorna executionId imediatamente
320
- const { executionId } = await executePublicServerFunctionAsyncMitra({
321
- projectId: 123,
322
- serverFunctionId: 50,
323
- input: { heavyParam: true }
324
- });
325
-
326
- // Polling — consulta status/resultado
327
- const execution = await getPublicServerFunctionExecutionMitra({
328
- projectId: 123,
329
- executionId
330
- });
331
- // execution: { executionId, status, output, logs, error, durationMs }
332
- ```
333
-
334
- ### executeDataLoaderMitra
335
-
336
- Executa um Data Loader cadastrado no projeto.
337
-
338
- ```typescript
339
- import { executeDataLoaderMitra } from 'mitra-interactions-sdk';
340
-
341
- const result = await executeDataLoaderMitra({
342
- projectId: 123,
343
- dataLoaderId: 5,
344
- input: { mes: 1, ano: 2025 } // Opcional — parâmetros {{var}} da query
345
- });
346
- // result: { status, result: { dataLoaderId, executionLog: { timestamp, rowCount, query, status, fileSize?, duration? }, message } }
347
- ```
348
-
349
- ### uploadFilePrivateMitra / uploadFilePublicMitra / uploadFileLoadableMitra
350
-
351
- Faz upload de um arquivo diretamente para a pasta PRIVATE, PUBLIC ou LOADABLE do projeto. Usa `multipart/form-data`.
352
-
353
- > 🔒 **Prefira `uploadFilePrivateMitra`.** O arquivo NÃO fica público no S3; o acesso é por download autenticado. `uploadFilePublicMitra` deixa o arquivo acessível por URL pública use quando isso for realmente desejado.
354
-
355
- ```typescript
356
- import { uploadFilePrivateMitra, uploadFilePublicMitra, uploadFileLoadableMitra } from 'mitra-interactions-sdk';
357
-
358
- // Upload PRIVADO (recomendado): o arquivo não fica público; publicUrl vem null.
359
- const priv = await uploadFilePrivateMitra({
360
- projectId: 123,
361
- file: fileInput.files[0] // File ou Blob
362
- });
363
- // priv: { status, result: { fileName, currentPath, publicUrl: null, message } }
364
- // Guarde `currentPath` (a chave) para baixar (download autenticado) ou excluir depois.
365
-
366
- // Upload para PUBLIC (arquivo fica acessível publicamente via URL)
367
- const result = await uploadFilePublicMitra({
368
- projectId: 123,
369
- file: fileInput.files[0] // File ou Blob
370
- });
371
- // result: { status, result: { fileName, currentPath, publicUrl, message } }
372
-
373
- // Upload para LOADABLE (arquivo disponível para carga via Spark/ETL)
374
- const result2 = await uploadFileLoadableMitra({
375
- projectId: 123,
376
- file: myBlob
377
- });
378
- // result2: { status, result: { fileName, currentPath, publicUrl: null, message } }
379
- ```
380
-
381
- ### downloadFilePrivateMitra / deleteFileMitra
382
-
383
- Baixa (com credencial) ou exclui um arquivo privado. Use a `key` retornada no upload (`result.currentPath`).
384
-
385
- ```typescript
386
- import { uploadFilePrivateMitra, downloadFilePrivateMitra, deleteFileMitra } from 'mitra-interactions-sdk';
387
-
388
- const up = await uploadFilePrivateMitra({ projectId: 123, file: fileInput.files[0] });
389
- const key = up.result.currentPath;
390
-
391
- // Download autenticado — retorna Blob (o backend lê o arquivo privado e faz stream)
392
- const blob = await downloadFilePrivateMitra({ projectId: 123, key });
393
-
394
- // Exclusão
395
- await deleteFileMitra({ projectId: 123, key });
396
- ```
397
-
398
- ### Dynamic Schema CRUD
399
-
400
- > 🔒 `userType=dev` only. Falha 403 para business. Em telas com business, envelopar em SF tipo SQL.
401
-
402
- CRUD completo em tabelas do projeto via Dynamic Schema (usa header `X-TenantID`).
403
-
404
- Todos os endpoints suportam o parâmetro opcional `jdbcConnectionConfigId` para operar em datasources adicionais (PostgreSQL, Oracle, SQL Server, etc.) ao invés do banco principal do tenant.
405
-
406
- - `listRecordsMitra(...)` → `ListRecordsResponse` `{ content, page, size, totalElements, totalPages }` - Lista registros com paginação
407
- - `getRecordMitra(...)` `Record<string, any>` - Busca registro por ID
408
- - `createRecordMitra(...)` `Record<string, any>` - Cria registro (201)
409
- - `updateRecordMitra(...)` `Record<string, any>` - Atualiza registro (PUT)
410
- - `patchRecordMitra(...)` → `Record<string, any>` - Atualiza parcialmente (PATCH)
411
- - `deleteRecordMitra(...)` → `void` - Remove registro (204 No Content)
412
- - `createRecordsBatchMitra(...)` → `Record<string, any>[]` - Cria múltiplos registros (201)
413
-
414
- ```typescript
415
- import { listRecordsMitra, createRecordMitra, updateRecordMitra, deleteRecordMitra } from 'mitra-interactions-sdk';
416
-
417
- // Listar registros
418
- const result = await listRecordsMitra({
419
- projectId: 123,
420
- tableName: 'produtos',
421
- page: 0,
422
- size: 20
423
- });
424
-
425
- // Criar registro
426
- await createRecordMitra({
427
- projectId: 123,
428
- tableName: 'produtos',
429
- data: { nome: 'Produto A', preco: 99.90 }
430
- });
431
-
432
- // Atualizar registro
433
- await updateRecordMitra({
434
- projectId: 123,
435
- tableName: 'produtos',
436
- id: 1,
437
- data: { nome: 'Produto A Atualizado', preco: 89.90, version: 0 }
438
- });
439
-
440
- // Deletar registro
441
- await deleteRecordMitra({ projectId: 123, tableName: 'produtos', id: 1 });
442
-
443
- // Usando datasource adicional (jdbcConnectionConfigId)
444
- const result2 = await listRecordsMitra({
445
- projectId: 123,
446
- tableName: 'clientes',
447
- jdbcConnectionConfigId: 5
448
- });
449
- ```
450
-
451
- ### Profile Management
452
-
453
- > 🔒 `userType=dev` only. Falha 403 para business. Telas de perfis exigem guard de `userType`.
454
-
455
- Gerenciamento de perfis de acesso. Permite gestão de quem pode acessar quais recursos no projeto.
456
-
457
- #### CRUD de Perfis
458
-
459
- - `listProfilesMitra({ projectId? })` `ListProfilesResponse` - Lista todos os perfis do projeto
460
- - `getProfileDetailsMitra({ projectId?, profileId })` → `GetProfileDetailsResponse` - Detalhes de um perfil (usuários, tabelas, actions, screens, server functions)
461
- - `createProfileMitra({ projectId?, name, color?, homeScreenId? })` → `CreateProfileResponse` - Cria um novo perfil
462
- - `updateProfileMitra({ projectId?, profileId, name?, color?, homeScreenId? })` → `UpdateProfileResponse` - Atualiza um perfil existente
463
- - `deleteProfileMitra({ projectId?, profileId })` → `DeleteProfileResponse` - Deleta um perfil
464
-
465
- ```typescript
466
- import { listProfilesMitra, createProfileMitra, getProfileDetailsMitra } from 'mitra-interactions-sdk';
467
-
468
- // Listar perfis
469
- const profiles = await listProfilesMitra({ projectId: 123 });
470
- // { status, projectId, result: [{ id, name, color, homeScreenId }] }
471
-
472
- // Criar perfil
473
- const created = await createProfileMitra({ projectId: 123, name: 'Vendedores', color: '#FF5733' });
474
- // { status, result: { id, name, message } }
475
-
476
- // Detalhes do perfil
477
- const details = await getProfileDetailsMitra({ projectId: 123, profileId: 1 });
478
- // { status, projectId, result: { id, name, users, selectTables, dmlTables, actions, screens, serverFunctions } }
479
- ```
480
-
481
- #### Permissões de Perfil
482
-
483
- Define quais recursos cada perfil pode acessar. Todas substituem a lista atual (não fazem append).
484
-
485
- - `setProfileUsersMitra({ projectId?, profileId, userIds })` - Define os usuários do perfil
486
- - `setProfileSelectTablesMitra({ projectId?, profileId, jdbcConnectionConfigId?, tables })` - Define tabelas SELECT permitidas
487
- - `setProfileDmlTablesMitra({ projectId?, profileId, jdbcConnectionConfigId?, tables })` - Define tabelas DML permitidas
488
- - `setProfileActionsMitra({ projectId?, profileId, actionIds })` - Define actions permitidas
489
- - `setProfileScreensMitra({ projectId?, profileId, screenIds })` - Define screens permitidas
490
- - `setProfileServerFunctionsMitra({ projectId?, profileId, serverFunctionIds })` - Define server functions permitidas
491
-
492
- ```typescript
493
- import { setProfileUsersMitra, setProfileSelectTablesMitra, setProfileServerFunctionsMitra } from 'mitra-interactions-sdk';
494
-
495
- // Definir usuários do perfil
496
- await setProfileUsersMitra({ projectId: 123, profileId: 1, userIds: [10, 20, 30] });
497
-
498
- // Definir tabelas SELECT
499
- await setProfileSelectTablesMitra({
500
- projectId: 123,
501
- profileId: 1,
502
- jdbcConnectionConfigId: 1, // Opcional — ID da conexão JDBC (default: banco principal)
503
- tables: [
504
- { tableName: 'clientes' },
505
- { tableName: 'pedidos' }
506
- ]
507
- });
508
-
509
- // Definir server functions
510
- await setProfileServerFunctionsMitra({ projectId: 123, profileId: 1, serverFunctionIds: [5, 8, 12] });
511
- ```
512
-
513
- ## Agent Chat (embedded)
514
-
515
- Chat com o agente de IA embarcado, sobre um WebSocket compartilhado (`/sdk-ws`). Uma única conexão atende todas as sessions — o roteamento de eventos é feito por `taskId`.
516
-
517
- > ⚙️ Requisitos: roda **apenas em apps publicadas pela plataforma Mitra** (o build-proxy injeta `window.__mitraEnv.agentWsUrl`) e precisa de `token` configurado (faça login antes ou passe em `configureSdkMitra`).
518
-
519
- ### Gerenciar os chats — `manageAgentChatMitra`
520
-
521
- Operações stateless sobre a coleção de chats do usuário: listar, renomear, deletar.
522
-
523
- ```typescript
524
- import { manageAgentChatMitra } from 'mitra-interactions-sdk';
525
-
526
- const chats = await manageAgentChatMitra({ action: 'list' }); // AgentChat[]
527
- const renamed = await manageAgentChatMitra({ action: 'rename', taskId, name: 'Novo nome' });
528
- const deleted = await manageAgentChatMitra({ action: 'delete', taskId });
529
- ```
530
-
531
- - `action: 'list'` → `AgentChat[]` — `{ id, name, agentType?, provider?, createdAt, updatedAt }`. Aceita `projectId?` pra sobrescrever o global.
532
- - `action: 'rename'` `{ taskId, name }`
533
- - `action: 'delete'` `{ taskId, deleted }`
534
-
535
- ### Abrir uma session — `getAgentTaskMitra`
536
-
537
- Retorna uma `AgentTaskSession` que encapsula todo o ciclo de vida de um chat (histórico, streaming, fila, cancel, eventos). Abrir a mesma `taskId` duas vezes devolve a **mesma** instância (cache).
538
-
539
- ```typescript
540
- import { getAgentTaskMitra } from 'mitra-interactions-sdk';
541
-
542
- // Chat novo — taskId é preenchido depois do primeiro send()
543
- const session = getAgentTaskMitra({ create: true, agentType: 'claudecode', modelId: 'openai/gpt-5.5:medium' });
544
-
545
- // Chat existente — detecta automaticamente se já há stream ativo
546
- const existing = getAgentTaskMitra({ taskId: 'abc123' });
547
- await existing.loadHistory({ limit: 50 });
548
- ```
549
-
550
- `getAgentTaskMitra({ create: true, projectId?, agentType?, modelId?, name? })` ou `getAgentTaskMitra({ taskId })`.
551
-
552
- #### Propriedades (somente leitura)
553
-
554
- | Propriedade | Tipo | Descrição |
555
- |-------------|------|-----------|
556
- | `taskId` | `string \| null` | `null` até o primeiro `send()` num chat novo |
557
- | `task` | `AgentChat \| null` | Metadados do chat após criado |
558
- | `isNew` | `boolean` | Se foi aberto via `{ create: true }` |
559
- | `status` | `AgentTaskStatus` | `opening` · `idle` · `uploading` · `streaming` · `cancelled` · `error` · `closed` |
560
- | `history` | `AgentMessage[]` | Histórico carregado |
561
- | `content` | `string` | Conteúdo acumulado do turno atual |
562
- | `queue` | `QueuedItem[]` | Mensagens enfileiradas (enviadas enquanto streamava) |
563
-
564
- #### Métodos
565
-
566
- - `send(prompt, options?)` → `void` — dispara um turno. Se já está streamando, **enfileira** (FIFO, máx 10). `options`: `{ agentType?, modelId?, files? }`.
567
- - `cancel()` → `Promise<void>` — cancela o turno atual; resolve quando o backend confirma (ou safety net de 30s).
568
- - `loadHistory({ limit? })` `Promise<AgentMessage[]>` — carrega o histórico do chat.
569
- - `editQueueItem(id, text)` / `removeQueueItem(id)` / `clearQueue()` — manipulam a fila.
570
- - `on(event, handler)` função de unsubscribe — assina eventos da session.
571
- - `close()` encerra a session e libera os listeners.
572
-
573
- #### Eventos (`session.on`)
574
-
575
- `statusChange` · `historyLoaded` · `taskCreated` · `turnStart` · `delta` · `tool` · `turnEnd` · `cancelled` · `queueChange` · `error`.
576
-
577
- ```typescript
578
- const session = getAgentTaskMitra({ create: true });
579
-
580
- session.on('delta', ({ delta, kind }) => process.stdout.write(delta)); // kind: 'text' | 'tool'
581
- session.on('tool', ({ tool, input }) => console.log('🔧', tool));
582
- session.on('turnEnd', ({ content }) => console.log('\n✓ fim do turno'));
583
- session.on('taskCreated', ({ task }) => console.log('chat criado:', task.id));
584
- session.on('error', ({ error }) => console.error(error));
585
-
586
- session.send('Analise estas vendas e gere um resumo');
587
- ```
588
-
589
- #### Anexos e seleção de modelo
590
-
591
- ```typescript
592
- // Anexos: passe os File crus (drop/input). A SDK sobe cada um (URL pública),
593
- // detecta o tipo e monta os anexos. Status vai pra 'uploading'; falha sai no evento 'error'.
594
- session.send('O que tem nesta planilha?', { files: [xlsxFile, pngFile] });
595
-
596
- // Modelo por turno (sobrescreve o default da session)
597
- session.send('Refaça com mais detalhes', { modelId: 'subscription:anthropic:claude-opus-4-7' });
598
- ```
599
-
600
- ### Credenciais do agente `manageAgentCredentialMitra`
601
-
602
- Função única (sobre `/sdk-ws`) para API keys (8 providers: `anthropic`, `openai`, `gemini`, `kimi`, `minimax`, `glm`, `qwen`, `openrouter`) e subscriptions OAuth (Claude paste-código / OpenAI device flow via Codex).
603
-
604
- > 🔒 Segurança: o token de subscription **nunca volta cru** pro cliente — fica server-side e é injetado no sandbox direto de lá.
605
-
606
- ```typescript
607
- import { manageAgentCredentialMitra } from 'mitra-interactions-sdk';
608
-
609
- // Listar providers + status (pra montar a UI de conexão)
610
- const { providers } = await manageAgentCredentialMitra({ action: 'list_providers' });
611
-
612
- // Listar modelos disponíveis ( dos providers com credencial) → use o modelId em send()/getAgentTaskMitra
613
- const { providers: groups } = await manageAgentCredentialMitra({ action: 'list_models' });
614
-
615
- // API key
616
- await manageAgentCredentialMitra({ action: 'validate', target: 'openai', key: 'sk-...' });
617
- await manageAgentCredentialMitra({ action: 'save', target: 'glm', key: '...' });
618
- await manageAgentCredentialMitra({ action: 'remove', target: 'anthropic' });
619
- ```
620
-
621
- Subscriptions (alto nível, sem redirect/callback page) — `auth` inicia e retorna o que mostrar; `connect` finaliza:
622
-
623
- ```typescript
624
- // Claude abra a authUrl, colete o código que a Anthropic mostra
625
- const { authUrl, state } = await manageAgentCredentialMitra({ action: 'auth', target: 'claude' });
626
- await manageAgentCredentialMitra({ action: 'connect', target: 'claude', code, state });
627
-
628
- // Codex (OpenAI device flow) mostre verificationUrl + userCode; a SDK faz o polling
629
- const { verificationUrl, userCode, pollId } = await manageAgentCredentialMitra({ action: 'auth', target: 'codex' });
630
- await manageAgentCredentialMitra({ action: 'connect', target: 'codex', pollId });
631
- ```
632
-
633
- ## Tipos TypeScript
634
-
635
- Todos os tipos estão incluídos:
636
-
637
- ```typescript
638
- import type {
639
- MitraConfig,
640
- // Login
641
- LoginOptions,
642
- LoginResponse,
643
- // Email Auth
644
- EmailSignupOptions,
645
- EmailLoginOptions,
646
- EmailVerifyCodeOptions,
647
- EmailResendCodeOptions,
648
- // Options
649
- ExecuteServerFunctionOptions,
650
- ExecuteServerFunctionAsyncOptions,
651
- UploadFileOptions,
652
- StopServerFunctionExecutionOptions,
653
- ListRecordsOptions,
654
- GetRecordOptions,
655
- CreateRecordOptions,
656
- UpdateRecordOptions,
657
- PatchRecordOptions,
658
- DeleteRecordOptions,
659
- CreateRecordsBatchOptions,
660
- // Responses
661
- ExecuteServerFunctionResponse,
662
- ExecuteServerFunctionAsyncResponse,
663
- UploadFileResponse,
664
- StopServerFunctionExecutionResponse,
665
- ListRecordsResponse,
666
- // Profile Management
667
- ListProfilesOptions,
668
- ListProfilesResponse,
669
- GetProfileDetailsOptions,
670
- GetProfileDetailsResponse,
671
- CreateProfileOptions,
672
- CreateProfileResponse,
673
- UpdateProfileOptions,
674
- UpdateProfileResponse,
675
- DeleteProfileOptions,
676
- DeleteProfileResponse,
677
- SetProfileUsersOptions,
678
- SetProfileSelectTablesOptions,
679
- SetProfileDmlTablesOptions,
680
- SetProfileActionsOptions,
681
- SetProfileScreensOptions,
682
- SetProfileServerFunctionsOptions,
683
- ProfileTableRef,
684
- SetProfilePermissionResponse,
685
- // Agent Chat
686
- AgentChat,
687
- AgentMessage,
688
- AgentType,
689
- AgentTaskSession,
690
- AgentTaskStatus,
691
- AgentTaskEventMap,
692
- AgentAttachment,
693
- QueuedItem,
694
- SendOptions,
695
- GetAgentTaskOptions,
696
- ManageAgentChatOptions,
697
- // Agent Credentials
698
- CredentialTarget,
699
- CredentialAction,
700
- ManageAgentCredentialOptions,
701
- AuthAgentCredentialOptions,
702
- ConnectAgentCredentialOptions,
703
- ListAgentModelsResult,
704
- ListAgentProvidersResult
705
- } from 'mitra-interactions-sdk';
706
- ```
707
-
708
- ## Tratamento de Erros
709
-
710
- ```typescript
711
- try {
712
- const result = await executeDbActionMitra({
713
- projectId: 123,
714
- dbActionId: 456
715
- });
716
- } catch (error) {
717
- console.log('Erro:', error.message);
718
- console.log('Status:', error.status);
719
- console.log('Detalhes:', error.details);
720
- }
721
- ```
722
-
723
- ## Licença
724
-
725
- MIT
1
+ # Mitra Interactions SDK
2
+
3
+ SDK para interações com a plataforma Mitra via endpoints `/interactions/`.
4
+
5
+ ## Permissões: `dev` vs `business`
6
+
7
+ `userType` no token de login:
8
+ - `dev` — chama tudo
9
+ - `business` — chama apenas execução (SF, Data Loader, upload), auth e chat. Outras chamadas retornam **403**.
10
+
11
+ > Não confundir com o pacote `mitra-business-sdk` (SDK separado, usado pelo agente IA).
12
+
13
+ **Bloqueado para `business`:** CRUD REST (`*RecordMitra`), Profile Management (`*ProfileMitra`, `setProfile*Mitra`), `listProjectUsersMitra`, `manageUserAccessMitra`.
14
+
15
+ > SF tipo JAVASCRIPT herda o `userType` do caller — se chamar funções bloqueadas, retorna 403 para business.
16
+
17
+ ---
18
+
19
+ ## Instalação
20
+
21
+ ```bash
22
+ npm install mitra-interactions-sdk
23
+ # ou
24
+ yarn add mitra-interactions-sdk
25
+ # ou
26
+ pnpm add mitra-interactions-sdk
27
+ ```
28
+
29
+ ## Configuração
30
+
31
+ Antes de usar qualquer função, configure o SDK. O `token` é **opcional** — Server Functions públicas podem ser chamadas sem autenticação.
32
+
33
+ > **Importante:** Quando usado, o token é um JWT de autenticação da plataforma Mitra. **Nunca deixe o token estático no código.** Utilize variáveis de ambiente para armazená-lo de forma segura.
34
+
35
+ ```typescript
36
+ import { configureSdkMitra } from 'mitra-interactions-sdk';
37
+
38
+ // Configuração completa (com autenticação)
39
+ const instance = configureSdkMitra({
40
+ baseURL: process.env.MITRA_BASE_URL || 'https://api.mitra.com',
41
+ token: process.env.MITRA_TOKEN!, // Opcional — necessário apenas para endpoints autenticados
42
+ authUrl: 'https://coder.mitralab.io/sdk-auth/', // Opcional — necessário para login e token refresh
43
+ projectId: 123, // Opcional — se informado, torna projectId opcional em TODOS os métodos
44
+ integrationURL: 'https://api0.mitraecp.com:1003', // Opcional — necessário para integrações
45
+ onTokenRefresh: (session) => { // Opcional — chamado quando o token é renovado automaticamente
46
+ localStorage.setItem('mitra_session', JSON.stringify(session));
47
+ }
48
+ });
49
+
50
+ // Configuração mínima (sem token — apenas para Server Functions públicas)
51
+ const instance = configureSdkMitra({
52
+ baseURL: 'https://api.mitra.com',
53
+ projectId: 123
54
+ });
55
+ await instance.executeServerFunction({ serverFunctionId: 42 }); // OK — sem token
56
+ ```
57
+
58
+ > **`projectId` global:** Se você passar `projectId` no `configureSdkMitra`, ele será usado como fallback em **todos** os métodos do SDK. Assim, não é necessário passar `projectId` em cada chamada individual — basta configurar uma vez.
59
+
60
+ `configureSdkMitra` retorna uma `MitraInstance` que também pode ser usada diretamente:
61
+
62
+ ```typescript
63
+ await instance.executeServerFunction({ serverFunctionId: 42 }); // projectId já vem do configureSdkMitra
64
+ ```
65
+
66
+ ## Autenticação (Login)
67
+
68
+ Login via popup ou redirect seguro hospedado no domínio Mitra. Credenciais nunca passam pelo código do desenvolvedor. O SDK é **auto-configurado** após o login.
69
+
70
+ > **Nota:** `authUrl` e `projectId` são **obrigatórios** para login. Porém, se já foram passados no `configureSdkMitra()`, não é necessário repeti-los — o SDK usa os valores configurados como fallback.
71
+
72
+ ### Login via Popup (padrão)
73
+
74
+ ```typescript
75
+ import { loginMitra } from 'mitra-interactions-sdk';
76
+
77
+ // Métodos disponíveis: 'email', 'google', 'microsoft', 'mitra'
78
+ // Primeira vez — sem configureSdkMitra: authUrl e projectId são obrigatórios
79
+ const result = await loginMitra('email', {
80
+ authUrl: 'https://coder.mitralab.io/sdk-auth/',
81
+ projectId: 123
82
+ });
83
+
84
+ // Se já chamou configureSdkMitra({ authUrl, projectId }), basta:
85
+ const result = await loginMitra('google');
86
+ const result = await loginMitra('microsoft');
87
+
88
+ // result: { token, baseURL, integrationURL? }
89
+ ```
90
+
91
+ ### Login Completo (method 'mitra')
92
+
93
+ Abre uma tela com todas as opções (Google, Microsoft, Email) e toggle entre Login/Cadastro.
94
+
95
+ ```typescript
96
+ await loginMitra('mitra', {
97
+ authUrl: 'https://coder.mitralab.io/sdk-auth/',
98
+ projectId: 123,
99
+ title: 'Meu App' // Opcional — título exibido na tela de login (default: "Mitra")
100
+ });
101
+ ```
102
+
103
+ ### Login via Redirect
104
+
105
+ Navega o usuário para a página de auth. Após o login, redireciona de volta com token nos query params.
106
+
107
+ ```typescript
108
+ import { loginMitra } from 'mitra-interactions-sdk';
109
+
110
+ // Iniciar login — o navegador navega para fora da página
111
+ await loginMitra('google', {
112
+ mode: 'redirect',
113
+ returnTo: '/dashboard' // Opcional — URL de retorno após login (default: página atual). Só funciona com mode 'redirect'.
114
+ });
115
+ ```
116
+
117
+ ### Fluxo de Criar Conta
118
+
119
+ ```typescript
120
+ // create funciona tanto em popup quanto redirect
121
+ await loginMitra('email', { create: true });
122
+
123
+ await loginMitra('mitra', {
124
+ mode: 'redirect',
125
+ create: true, // Abre direto no modo cadastro
126
+ returnTo: '/onboarding',
127
+ title: 'Meu App'
128
+ });
129
+ ```
130
+
131
+ ### Token Refresh Automático
132
+
133
+ Quando qualquer requisição retorna **403**, o SDK tenta renovar o token automaticamente via iframe invisível (usa o cookie de sessão do provider). Se o refresh funcionar, a requisição é retentada com o novo token — transparente para o desenvolvedor.
134
+
135
+ O callback `onTokenRefresh` é chamado após renovação bem-sucedida:
136
+
137
+ ```typescript
138
+ configureSdkMitra({
139
+ baseURL: '...',
140
+ token: '...',
141
+ authUrl: 'https://coder.mitralab.io/sdk-auth/',
142
+ projectId: 123,
143
+ onTokenRefresh: (session) => {
144
+ // Atualiza o token salvo (ex: localStorage, store, etc.)
145
+ localStorage.setItem('mitra_token', session.token);
146
+ }
147
+ });
148
+ ```
149
+
150
+ ### Login por Email (iframe silencioso)
151
+
152
+ Para quem precisa montar sua **própria tela de login** (sem popup/redirect), o SDK oferece funções que fazem a autenticação via iframe invisível. As credenciais são enviadas ao HTML de auth via `postMessage` — sem CORS, sem expor a API.
153
+
154
+ #### emailSignupMitra
155
+
156
+ Cria conta. Após sucesso, o usuário recebe um código de verificação por email.
157
+
158
+ ```typescript
159
+ import { emailSignupMitra } from 'mitra-interactions-sdk';
160
+
161
+ await emailSignupMitra({
162
+ name: 'João Silva',
163
+ email: 'joao@email.com',
164
+ password: 'minhasenha123'
165
+ });
166
+ // Não retorna token — o próximo passo é verificar o código
167
+ ```
168
+
169
+ #### emailVerifyCodeMitra
170
+
171
+ Verifica o código de 6 dígitos e faz login automático. Retorna `LoginResponse` e auto-configura o SDK.
172
+
173
+ ```typescript
174
+ import { emailVerifyCodeMitra } from 'mitra-interactions-sdk';
175
+
176
+ const session = await emailVerifyCodeMitra({
177
+ email: 'joao@email.com',
178
+ code: '123456',
179
+ password: 'minhasenha123' // Necessário para login automático após verificação
180
+ });
181
+ // session: { token, baseURL, integrationURL? }
182
+ ```
183
+
184
+ #### emailResendCodeMitra
185
+
186
+ Reenvia o código de verificação para o email.
187
+
188
+ ```typescript
189
+ import { emailResendCodeMitra } from 'mitra-interactions-sdk';
190
+
191
+ await emailResendCodeMitra({ email: 'joao@email.com' });
192
+ ```
193
+
194
+ #### emailLoginMitra
195
+
196
+ Login direto com email e senha. Retorna `LoginResponse` e auto-configura o SDK.
197
+
198
+ ```typescript
199
+ import { emailLoginMitra } from 'mitra-interactions-sdk';
200
+
201
+ const session = await emailLoginMitra({
202
+ email: 'joao@email.com',
203
+ password: 'minhasenha123'
204
+ });
205
+ // session: { token, baseURL, integrationURL? }
206
+ ```
207
+
208
+ #### Fluxo completo de signup com email
209
+
210
+ ```typescript
211
+ // 1. Criar conta
212
+ await emailSignupMitra({ name: 'João', email, password });
213
+
214
+ // 2. Usuário recebe código por email e digita na tela
215
+ const session = await emailVerifyCodeMitra({ email, code: '123456', password });
216
+
217
+ // 3. SDK já está configurado — pode chamar qualquer método
218
+ await executeDbActionMitra({ dbActionId: 1 });
219
+ ```
220
+
221
+ > **Nota:** `authUrl` e `projectId` são opcionais em todas as funções de email se já foram configurados via `configureSdkMitra()`.
222
+
223
+ ### Reset de Senha (esqueci minha senha)
224
+
225
+ Endpoints públicos (sem token) para o fluxo de "esqueci minha senha":
226
+
227
+ ```typescript
228
+ import {
229
+ sendPasswordResetCodeMitra,
230
+ validatePasswordResetCodeMitra,
231
+ resetPasswordMitra,
232
+ emailLoginMitra
233
+ } from 'mitra-interactions-sdk';
234
+
235
+ // 1. Envia código de 6 dígitos por email
236
+ await sendPasswordResetCodeMitra({ email });
237
+
238
+ // 2. (opcional) Valida o código antes de pedir a senha nova
239
+ await validatePasswordResetCodeMitra({ email, code: '123456' });
240
+
241
+ // 3. Troca a senha
242
+ await resetPasswordMitra({ email, code: '123456', newPassword: 'novaSenha' });
243
+
244
+ // 4. Login com a nova senha
245
+ await emailLoginMitra({ email, password: 'novaSenha' });
246
+ ```
247
+
248
+ > **Nota:** `projectId` é opcional se já configurado via `configureSdkMitra()`.
249
+
250
+ ## Métodos Disponíveis
251
+
252
+ ### executeServerFunctionMitra
253
+
254
+ Executa uma Server Function de forma **síncrona** (timeout de 60s no backend). Retorna o resultado diretamente.
255
+
256
+ ```typescript
257
+ import { executeServerFunctionMitra } from 'mitra-interactions-sdk';
258
+
259
+ const result = await executeServerFunctionMitra({
260
+ projectId: 123,
261
+ serverFunctionId: 101,
262
+ input: { // Opcional - objeto de entrada para a função
263
+ arg1: 'valor1'
264
+ }
265
+ });
266
+ // result: { status, result: { executionId, executionStatus, output, logs, error, durationMs } }
267
+ ```
268
+
269
+ ### executeServerFunctionAsyncMitra
270
+
271
+ Executa uma Server Function de forma **assíncrona**. Retorna um `executionId` imediatamente. Use `stopServerFunctionExecutionMitra` para parar ou `getServerFunctionExecutionMitra` (mitra-sdk) para consultar o resultado.
272
+
273
+ ```typescript
274
+ import { executeServerFunctionAsyncMitra } from 'mitra-interactions-sdk';
275
+
276
+ const result = await executeServerFunctionAsyncMitra({
277
+ projectId: 123,
278
+ serverFunctionId: 101,
279
+ input: { // Opcional - objeto de entrada para a função
280
+ arg1: 'valor1'
281
+ }
282
+ });
283
+ // result: { status, result: { executionId, executionStatus } }
284
+ ```
285
+
286
+ ### stopServerFunctionExecutionMitra
287
+
288
+ Para a execução de uma Server Function em andamento.
289
+
290
+ ```typescript
291
+ import { stopServerFunctionExecutionMitra } from 'mitra-interactions-sdk';
292
+
293
+ const result = await stopServerFunctionExecutionMitra({
294
+ projectId: 123,
295
+ executionId: 'exec-uuid-aqui'
296
+ });
297
+ // result: { status, result: { executionId, executionStatus: "CANCELLED" | "ALREADY_FINISHED" } }
298
+ ```
299
+
300
+ ### Public Server Functions (sem autenticação)
301
+
302
+ Para Server Functions com `publicExecution = true`. Não requerem token.
303
+
304
+ ```typescript
305
+ import {
306
+ executePublicServerFunctionMitra,
307
+ executePublicServerFunctionAsyncMitra,
308
+ getPublicServerFunctionExecutionMitra
309
+ } from 'mitra-interactions-sdk';
310
+
311
+ // Sync — retorna resultado inline (timeout 5min)
312
+ const result = await executePublicServerFunctionMitra({
313
+ projectId: 123,
314
+ serverFunctionId: 49,
315
+ input: { param1: 'value' }
316
+ });
317
+ // result: { executionId, status, output, logs, error, durationMs }
318
+
319
+ // Async — retorna executionId imediatamente
320
+ const { executionId } = await executePublicServerFunctionAsyncMitra({
321
+ projectId: 123,
322
+ serverFunctionId: 50,
323
+ input: { heavyParam: true }
324
+ });
325
+
326
+ // Polling — consulta status/resultado
327
+ const execution = await getPublicServerFunctionExecutionMitra({
328
+ projectId: 123,
329
+ executionId
330
+ });
331
+ // execution: { executionId, status, output, logs, error, durationMs }
332
+ ```
333
+
334
+ ### executeDataLoaderMitra
335
+
336
+ Executa um Data Loader cadastrado no projeto.
337
+
338
+ ```typescript
339
+ import { executeDataLoaderMitra } from 'mitra-interactions-sdk';
340
+
341
+ const result = await executeDataLoaderMitra({
342
+ projectId: 123,
343
+ dataLoaderId: 5,
344
+ input: { mes: 1, ano: 2025 } // Opcional — parâmetros {{var}} da query
345
+ });
346
+ // result: { status, result: { dataLoaderId, executionLog: { timestamp, rowCount, query, status, fileSize?, duration? }, message } }
347
+ ```
348
+
349
+ ### uploadFilePrivateMitra / uploadFilePublicMitra / uploadFileLoadableMitra
350
+
351
+ Faz upload de um arquivo diretamente para a pasta PRIVATE, PUBLIC ou LOADABLE do projeto. Usa `multipart/form-data`.
352
+
353
+ > 🔒 **Privado é o padrão.** `uploadFilePrivateMitra` guarda o arquivo em bucket sem leitura pública, com chave aleatória; o acesso é sempre autenticado e autorizado pela aplicação. `uploadFilePublicMitra` cria uma URL permanente e irreversível — só para conteúdo que precisa abrir sem sessão (logo, imagem em e-mail, tela pública), nunca para dado de cliente.
354
+
355
+ ```typescript
356
+ import { uploadFilePrivateMitra, uploadFilePublicMitra, uploadFileLoadableMitra } from 'mitra-interactions-sdk';
357
+
358
+ // Upload PRIVADO (recomendado): o arquivo não fica público; publicUrl vem null.
359
+ const priv = await uploadFilePrivateMitra({
360
+ projectId: 123,
361
+ file: fileInput.files[0] // File ou Blob
362
+ });
363
+ // priv: { status, result: { fileName, currentPath, key, publicUrl: null, message } }
364
+ // key = ai-files/private/{24 chars aleatórios}/nome guarde na linha do registro dono.
365
+ // Quem lê é a Server Function, depois de validar o registro (ver "Anexos privados — o padrão").
366
+
367
+ // Upload para PUBLIC (arquivo fica acessível publicamente via URL)
368
+ const result = await uploadFilePublicMitra({
369
+ projectId: 123,
370
+ file: fileInput.files[0] // File ou Blob
371
+ });
372
+ // result: { status, result: { fileName, currentPath, key, publicUrl, message } }
373
+ // No PUBLIC, `currentPath` é a URL completa; `key` é a chave relativa (ai-files/public/...).
374
+
375
+ // Upload para LOADABLE (arquivo disponível para carga via Spark/ETL)
376
+ const result2 = await uploadFileLoadableMitra({
377
+ projectId: 123,
378
+ file: myBlob
379
+ });
380
+ // result2: { status, result: { fileName, currentPath, publicUrl: null, message } }
381
+ ```
382
+
383
+ ### Anexos privados o padrão (contrato TKT-000a0394)
384
+
385
+ A plataforma só sabe "esta pessoa pertence a este projeto". Quem sabe "o anexo X é da solicitação Y,
386
+ que é do usuário Z" é a aplicação. Por isso o acesso a um arquivo privado **pela chave** é restrito
387
+ a usuário DEV do projeto ou a uma Server Function em execução; **a tela de usuário final nunca manda
388
+ a chave** ela pede o anexo **pelo registro** a uma SF, que confere a regra e devolve um link
389
+ temporário.
390
+
391
+ ```typescript
392
+ import { uploadFilePrivateMitra, executeServerFunctionMitra } from 'mitra-interactions-sdk';
393
+
394
+ // 1) Tela de formulário: sobe privado e guarda a CHAVE na linha do registro
395
+ const up = await uploadFilePrivateMitra({ projectId: 123, file: fileInput.files[0] });
396
+ const key = up.result.key; // ai-files/private/{24 chars aleatórios}/comprovante.pdf
397
+ await executeServerFunctionMitra({ projectId: 123, serverFunctionId: SF_SALVAR_SOLICITACAO,
398
+ input: { descricao, anexoKey: key } });
399
+
400
+ // 2) Tela que exibe: pede pelo REGISTRO, nunca pela chave
401
+ const res = await executeServerFunctionMitra({ projectId: 123, serverFunctionId: SF_ANEXO_DA_SOLICITACAO,
402
+ input: { solicitacaoId: 482 } });
403
+ // a SF conferiu que o usuário pode ver a solicitação 482 e devolveu { url, expiresAt } (link de ~5 min)
404
+ window.open(res.result.output.url);
405
+ ```
406
+
407
+ Do lado da SF (backend), depois da regra de negócio, a chave vira link temporário via
408
+ `GET {MITRA_BASE_URL}/agentAiShortcut/fileLink?projectId&key&ttlSeconds` exemplos completos em
409
+ `mitraapi/docs/SERVER_FUNCTIONS_API.md`, seção "Arquivos privados a partir de uma Server Function".
410
+
411
+ **Regras**
412
+
413
+ - **`key` só é aceita dentro das pastas do projeto** (`ai-files/private/`, `ai-files/public/`, `ai-files/loadable/`). Chave iniciada em `tenant_` ou `/`, com `..` ou terminada em `/` é recusada (HTTP 400 `INVALID_KEY`). É isso que isola um projeto do outro.
414
+ - **A chave privada tem um segmento aleatório** de 24 caracteres: não é adivinhável e dois uploads com o mesmo nome não se sobrescrevem. Guarde-a como qualquer outra coluna do registro.
415
+ - **Privado fica em bucket próprio, sem URL pública.** Público é permanente e irreversível; nunca é o lugar de dado de cliente.
416
+ - **Todo acesso é registrado** (`INT_FILEACCESSLOG` do tenant): quem baixou, gerou link ou excluiu, e quando.
417
+
418
+ ### downloadFilePrivateMitra / getFileLinkMitra / deleteFileMitra (DEV e Server Function)
419
+
420
+ Acesso **pela chave**. Permissão: usuário **DEV** do projeto (sem API key BUSINESS) ou **Server
421
+ Function em execução**. Usuário final recebe HTTP 403 `ACCESS_DENIED` — para ele, use o padrão acima.
422
+
423
+ ```typescript
424
+ import { downloadFilePrivateMitra, getFileLinkMitra, deleteFileMitra } from 'mitra-interactions-sdk';
425
+
426
+ // Download autenticado — retorna Blob
427
+ const blob = await downloadFilePrivateMitra({ projectId: 123, key });
428
+
429
+ // Link temporário (assinado); padrão 300 s, máximo definido no backend
430
+ const link = await getFileLinkMitra({ projectId: 123, key, ttlSeconds: 300 });
431
+ // link.result: { key, url, expiresAt, expiresInSeconds }
432
+
433
+ // Exclusão — apaga exatamente esse objeto
434
+ const del = await deleteFileMitra({ projectId: 123, key });
435
+ // erros: 400 INVALID_KEY | 403 ACCESS_DENIED | 404 FILE_NOT_FOUND
436
+ ```
437
+
438
+ - O delete nunca apaga por prefixo/pasta, e chave inexistente devolve `FILE_NOT_FOUND`.
439
+ - Quando o registro é apagado, apague o anexo dele na mesma SF — senão sobra documento de cliente
440
+ sem nada apontando para ele.
441
+
442
+ ### Dynamic Schema CRUD
443
+
444
+ > 🔒 `userType=dev` only. Falha 403 para business. Em telas com business, envelopar em SF tipo SQL.
445
+
446
+ CRUD completo em tabelas do projeto via Dynamic Schema (usa header `X-TenantID`).
447
+
448
+ Todos os endpoints suportam o parâmetro opcional `jdbcConnectionConfigId` para operar em datasources adicionais (PostgreSQL, Oracle, SQL Server, etc.) ao invés do banco principal do tenant.
449
+
450
+ - `listRecordsMitra(...)` → `ListRecordsResponse` `{ content, page, size, totalElements, totalPages }` - Lista registros com paginação
451
+ - `getRecordMitra(...)` → `Record<string, any>` - Busca registro por ID
452
+ - `createRecordMitra(...)` → `Record<string, any>` - Cria registro (201)
453
+ - `updateRecordMitra(...)` `Record<string, any>` - Atualiza registro (PUT)
454
+ - `patchRecordMitra(...)` → `Record<string, any>` - Atualiza parcialmente (PATCH)
455
+ - `deleteRecordMitra(...)` `void` - Remove registro (204 No Content)
456
+ - `createRecordsBatchMitra(...)` → `Record<string, any>[]` - Cria múltiplos registros (201)
457
+
458
+ ```typescript
459
+ import { listRecordsMitra, createRecordMitra, updateRecordMitra, deleteRecordMitra } from 'mitra-interactions-sdk';
460
+
461
+ // Listar registros
462
+ const result = await listRecordsMitra({
463
+ projectId: 123,
464
+ tableName: 'produtos',
465
+ page: 0,
466
+ size: 20
467
+ });
468
+
469
+ // Criar registro
470
+ await createRecordMitra({
471
+ projectId: 123,
472
+ tableName: 'produtos',
473
+ data: { nome: 'Produto A', preco: 99.90 }
474
+ });
475
+
476
+ // Atualizar registro
477
+ await updateRecordMitra({
478
+ projectId: 123,
479
+ tableName: 'produtos',
480
+ id: 1,
481
+ data: { nome: 'Produto A Atualizado', preco: 89.90, version: 0 }
482
+ });
483
+
484
+ // Deletar registro
485
+ await deleteRecordMitra({ projectId: 123, tableName: 'produtos', id: 1 });
486
+
487
+ // Usando datasource adicional (jdbcConnectionConfigId)
488
+ const result2 = await listRecordsMitra({
489
+ projectId: 123,
490
+ tableName: 'clientes',
491
+ jdbcConnectionConfigId: 5
492
+ });
493
+ ```
494
+
495
+ ### Profile Management
496
+
497
+ > 🔒 `userType=dev` only. Falha 403 para business. Telas de perfis exigem guard de `userType`.
498
+
499
+ Gerenciamento de perfis de acesso. Permite gestão de quem pode acessar quais recursos no projeto.
500
+
501
+ #### CRUD de Perfis
502
+
503
+ - `listProfilesMitra({ projectId? })` → `ListProfilesResponse` - Lista todos os perfis do projeto
504
+ - `getProfileDetailsMitra({ projectId?, profileId })` → `GetProfileDetailsResponse` - Detalhes de um perfil (usuários, tabelas, actions, screens, server functions)
505
+ - `createProfileMitra({ projectId?, name, color?, homeScreenId? })` → `CreateProfileResponse` - Cria um novo perfil
506
+ - `updateProfileMitra({ projectId?, profileId, name?, color?, homeScreenId? })` → `UpdateProfileResponse` - Atualiza um perfil existente
507
+ - `deleteProfileMitra({ projectId?, profileId })` → `DeleteProfileResponse` - Deleta um perfil
508
+
509
+ ```typescript
510
+ import { listProfilesMitra, createProfileMitra, getProfileDetailsMitra } from 'mitra-interactions-sdk';
511
+
512
+ // Listar perfis
513
+ const profiles = await listProfilesMitra({ projectId: 123 });
514
+ // { status, projectId, result: [{ id, name, color, homeScreenId }] }
515
+
516
+ // Criar perfil
517
+ const created = await createProfileMitra({ projectId: 123, name: 'Vendedores', color: '#FF5733' });
518
+ // { status, result: { id, name, message } }
519
+
520
+ // Detalhes do perfil
521
+ const details = await getProfileDetailsMitra({ projectId: 123, profileId: 1 });
522
+ // { status, projectId, result: { id, name, users, selectTables, dmlTables, actions, screens, serverFunctions } }
523
+ ```
524
+
525
+ #### Permissões de Perfil
526
+
527
+ Define quais recursos cada perfil pode acessar. Todas substituem a lista atual (não fazem append).
528
+
529
+ - `setProfileUsersMitra({ projectId?, profileId, userIds })` - Define os usuários do perfil
530
+ - `setProfileSelectTablesMitra({ projectId?, profileId, jdbcConnectionConfigId?, tables })` - Define tabelas SELECT permitidas
531
+ - `setProfileDmlTablesMitra({ projectId?, profileId, jdbcConnectionConfigId?, tables })` - Define tabelas DML permitidas
532
+ - `setProfileActionsMitra({ projectId?, profileId, actionIds })` - Define actions permitidas
533
+ - `setProfileScreensMitra({ projectId?, profileId, screenIds })` - Define screens permitidas
534
+ - `setProfileServerFunctionsMitra({ projectId?, profileId, serverFunctionIds })` - Define server functions permitidas
535
+
536
+ ```typescript
537
+ import { setProfileUsersMitra, setProfileSelectTablesMitra, setProfileServerFunctionsMitra } from 'mitra-interactions-sdk';
538
+
539
+ // Definir usuários do perfil
540
+ await setProfileUsersMitra({ projectId: 123, profileId: 1, userIds: [10, 20, 30] });
541
+
542
+ // Definir tabelas SELECT
543
+ await setProfileSelectTablesMitra({
544
+ projectId: 123,
545
+ profileId: 1,
546
+ jdbcConnectionConfigId: 1, // Opcional — ID da conexão JDBC (default: banco principal)
547
+ tables: [
548
+ { tableName: 'clientes' },
549
+ { tableName: 'pedidos' }
550
+ ]
551
+ });
552
+
553
+ // Definir server functions
554
+ await setProfileServerFunctionsMitra({ projectId: 123, profileId: 1, serverFunctionIds: [5, 8, 12] });
555
+ ```
556
+
557
+ ## Agent Chat (embedded)
558
+
559
+ Chat com o agente de IA embarcado, sobre um WebSocket compartilhado (`/sdk-ws`). Uma única conexão atende todas as sessions — o roteamento de eventos é feito por `taskId`.
560
+
561
+ > ⚙️ Requisitos: roda **apenas em apps publicadas pela plataforma Mitra** (o build-proxy injeta `window.__mitraEnv.agentWsUrl`) e precisa de `token` configurado (faça login antes ou passe em `configureSdkMitra`).
562
+
563
+ ### Gerenciar os chats — `manageAgentChatMitra`
564
+
565
+ Operações stateless sobre a coleção de chats do usuário: listar, renomear, deletar.
566
+
567
+ ```typescript
568
+ import { manageAgentChatMitra } from 'mitra-interactions-sdk';
569
+
570
+ const chats = await manageAgentChatMitra({ action: 'list' }); // AgentChat[]
571
+ const renamed = await manageAgentChatMitra({ action: 'rename', taskId, name: 'Novo nome' });
572
+ const deleted = await manageAgentChatMitra({ action: 'delete', taskId });
573
+ ```
574
+
575
+ - `action: 'list'` `AgentChat[]` `{ id, name, agentType?, provider?, createdAt, updatedAt }`. Aceita `projectId?` pra sobrescrever o global.
576
+ - `action: 'rename'` → `{ taskId, name }`
577
+ - `action: 'delete'` → `{ taskId, deleted }`
578
+
579
+ ### Abrir uma session — `getAgentTaskMitra`
580
+
581
+ Retorna uma `AgentTaskSession` que encapsula todo o ciclo de vida de um chat (histórico, streaming, fila, cancel, eventos). Abrir a mesma `taskId` duas vezes devolve a **mesma** instância (cache).
582
+
583
+ ```typescript
584
+ import { getAgentTaskMitra } from 'mitra-interactions-sdk';
585
+
586
+ // Chat novo taskId é preenchido depois do primeiro send()
587
+ const session = getAgentTaskMitra({ create: true, agentType: 'claudecode', modelId: 'openai/gpt-5.5:medium' });
588
+
589
+ // Chat existente detecta automaticamente se já há stream ativo
590
+ const existing = getAgentTaskMitra({ taskId: 'abc123' });
591
+ await existing.loadHistory({ limit: 50 });
592
+ ```
593
+
594
+ `getAgentTaskMitra({ create: true, projectId?, agentType?, modelId?, name? })` ou `getAgentTaskMitra({ taskId })`.
595
+
596
+ #### Propriedades (somente leitura)
597
+
598
+ | Propriedade | Tipo | Descrição |
599
+ |-------------|------|-----------|
600
+ | `taskId` | `string \| null` | `null` até o primeiro `send()` num chat novo |
601
+ | `task` | `AgentChat \| null` | Metadados do chat após criado |
602
+ | `isNew` | `boolean` | Se foi aberto via `{ create: true }` |
603
+ | `status` | `AgentTaskStatus` | `opening` · `idle` · `uploading` · `streaming` · `cancelled` · `error` · `closed` |
604
+ | `history` | `AgentMessage[]` | Histórico carregado |
605
+ | `content` | `string` | Conteúdo acumulado do turno atual |
606
+ | `queue` | `QueuedItem[]` | Mensagens enfileiradas (enviadas enquanto streamava) |
607
+
608
+ #### Métodos
609
+
610
+ - `send(prompt, options?)` `void` dispara um turno. Se já está streamando, **enfileira** (FIFO, máx 10). `options`: `{ agentType?, modelId?, files? }`.
611
+ - `cancel()` → `Promise<void>` — cancela o turno atual; resolve quando o backend confirma (ou safety net de 30s).
612
+ - `loadHistory({ limit? })``Promise<AgentMessage[]>` — carrega o histórico do chat.
613
+ - `editQueueItem(id, text)` / `removeQueueItem(id)` / `clearQueue()` manipulam a fila.
614
+ - `on(event, handler)` → função de unsubscribe — assina eventos da session.
615
+ - `close()` — encerra a session e libera os listeners.
616
+
617
+ #### Eventos (`session.on`)
618
+
619
+ `statusChange` · `historyLoaded` · `taskCreated` · `turnStart` · `delta` · `tool` · `turnEnd` · `cancelled` · `queueChange` · `error`.
620
+
621
+ ```typescript
622
+ const session = getAgentTaskMitra({ create: true });
623
+
624
+ session.on('delta', ({ delta, kind }) => process.stdout.write(delta)); // kind: 'text' | 'tool'
625
+ session.on('tool', ({ tool, input }) => console.log('🔧', tool));
626
+ session.on('turnEnd', ({ content }) => console.log('\n✓ fim do turno'));
627
+ session.on('taskCreated', ({ task }) => console.log('chat criado:', task.id));
628
+ session.on('error', ({ error }) => console.error(error));
629
+
630
+ session.send('Analise estas vendas e gere um resumo');
631
+ ```
632
+
633
+ #### Anexos e seleção de modelo
634
+
635
+ ```typescript
636
+ // Anexos: passe os File crus (drop/input). A SDK sobe cada um (URL pública),
637
+ // detecta o tipo e monta os anexos. Status vai pra 'uploading'; falha sai no evento 'error'.
638
+ session.send('O que tem nesta planilha?', { files: [xlsxFile, pngFile] });
639
+
640
+ // Modelo por turno (sobrescreve o default da session)
641
+ session.send('Refaça com mais detalhes', { modelId: 'subscription:anthropic:claude-opus-4-7' });
642
+ ```
643
+
644
+ ### Credenciais do agente — `manageAgentCredentialMitra`
645
+
646
+ Função única (sobre `/sdk-ws`) para API keys (8 providers: `anthropic`, `openai`, `gemini`, `kimi`, `minimax`, `glm`, `qwen`, `openrouter`) e subscriptions OAuth (Claude paste-código / OpenAI device flow via Codex).
647
+
648
+ > 🔒 Segurança: o token de subscription **nunca volta cru** pro cliente — fica server-side e é injetado no sandbox direto de lá.
649
+
650
+ ```typescript
651
+ import { manageAgentCredentialMitra } from 'mitra-interactions-sdk';
652
+
653
+ // Listar providers + status (pra montar a UI de conexão)
654
+ const { providers } = await manageAgentCredentialMitra({ action: 'list_providers' });
655
+
656
+ // Listar modelos disponíveis (só dos providers com credencial) → use o modelId em send()/getAgentTaskMitra
657
+ const { providers: groups } = await manageAgentCredentialMitra({ action: 'list_models' });
658
+
659
+ // API key
660
+ await manageAgentCredentialMitra({ action: 'validate', target: 'openai', key: 'sk-...' });
661
+ await manageAgentCredentialMitra({ action: 'save', target: 'glm', key: '...' });
662
+ await manageAgentCredentialMitra({ action: 'remove', target: 'anthropic' });
663
+ ```
664
+
665
+ Subscriptions (alto nível, sem redirect/callback page) — `auth` inicia e retorna o que mostrar; `connect` finaliza:
666
+
667
+ ```typescript
668
+ // Claude — abra a authUrl, colete o código que a Anthropic mostra
669
+ const { authUrl, state } = await manageAgentCredentialMitra({ action: 'auth', target: 'claude' });
670
+ await manageAgentCredentialMitra({ action: 'connect', target: 'claude', code, state });
671
+
672
+ // Codex (OpenAI device flow) — mostre verificationUrl + userCode; a SDK faz o polling
673
+ const { verificationUrl, userCode, pollId } = await manageAgentCredentialMitra({ action: 'auth', target: 'codex' });
674
+ await manageAgentCredentialMitra({ action: 'connect', target: 'codex', pollId });
675
+ ```
676
+
677
+ ## Tipos TypeScript
678
+
679
+ Todos os tipos estão incluídos:
680
+
681
+ ```typescript
682
+ import type {
683
+ MitraConfig,
684
+ // Login
685
+ LoginOptions,
686
+ LoginResponse,
687
+ // Email Auth
688
+ EmailSignupOptions,
689
+ EmailLoginOptions,
690
+ EmailVerifyCodeOptions,
691
+ EmailResendCodeOptions,
692
+ // Options
693
+ ExecuteServerFunctionOptions,
694
+ ExecuteServerFunctionAsyncOptions,
695
+ UploadFileOptions,
696
+ StopServerFunctionExecutionOptions,
697
+ ListRecordsOptions,
698
+ GetRecordOptions,
699
+ CreateRecordOptions,
700
+ UpdateRecordOptions,
701
+ PatchRecordOptions,
702
+ DeleteRecordOptions,
703
+ CreateRecordsBatchOptions,
704
+ // Responses
705
+ ExecuteServerFunctionResponse,
706
+ ExecuteServerFunctionAsyncResponse,
707
+ UploadFileResponse,
708
+ StopServerFunctionExecutionResponse,
709
+ ListRecordsResponse,
710
+ // Profile Management
711
+ ListProfilesOptions,
712
+ ListProfilesResponse,
713
+ GetProfileDetailsOptions,
714
+ GetProfileDetailsResponse,
715
+ CreateProfileOptions,
716
+ CreateProfileResponse,
717
+ UpdateProfileOptions,
718
+ UpdateProfileResponse,
719
+ DeleteProfileOptions,
720
+ DeleteProfileResponse,
721
+ SetProfileUsersOptions,
722
+ SetProfileSelectTablesOptions,
723
+ SetProfileDmlTablesOptions,
724
+ SetProfileActionsOptions,
725
+ SetProfileScreensOptions,
726
+ SetProfileServerFunctionsOptions,
727
+ ProfileTableRef,
728
+ SetProfilePermissionResponse,
729
+ // Agent Chat
730
+ AgentChat,
731
+ AgentMessage,
732
+ AgentType,
733
+ AgentTaskSession,
734
+ AgentTaskStatus,
735
+ AgentTaskEventMap,
736
+ AgentAttachment,
737
+ QueuedItem,
738
+ SendOptions,
739
+ GetAgentTaskOptions,
740
+ ManageAgentChatOptions,
741
+ // Agent Credentials
742
+ CredentialTarget,
743
+ CredentialAction,
744
+ ManageAgentCredentialOptions,
745
+ AuthAgentCredentialOptions,
746
+ ConnectAgentCredentialOptions,
747
+ ListAgentModelsResult,
748
+ ListAgentProvidersResult
749
+ } from 'mitra-interactions-sdk';
750
+ ```
751
+
752
+ ## Tratamento de Erros
753
+
754
+ ```typescript
755
+ try {
756
+ const result = await executeDbActionMitra({
757
+ projectId: 123,
758
+ dbActionId: 456
759
+ });
760
+ } catch (error) {
761
+ console.log('Erro:', error.message);
762
+ console.log('Status:', error.status);
763
+ console.log('Detalhes:', error.details);
764
+ }
765
+ ```
766
+
767
+ ## Licença
768
+
769
+ MIT