mitra-interactions-sdk 1.0.60-beta.41 → 1.0.60-beta.43
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 +41 -2
- package/dist/index.d.mts +36 -4
- package/dist/index.d.ts +36 -4
- package/dist/index.js +63 -20
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +63 -20
- package/dist/index.mjs.map +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -87,6 +87,23 @@ const result = await loginWithMicrosoftMitra();
|
|
|
87
87
|
// result: { token, baseURL, refreshToken }
|
|
88
88
|
```
|
|
89
89
|
|
|
90
|
+
`create` separa a intenção do SSO sem quebrar integrações existentes:
|
|
91
|
+
|
|
92
|
+
| Valor | Comportamento |
|
|
93
|
+
| --- | --- |
|
|
94
|
+
| omitido | Fluxo combinado compatível: autentica e cria o vínculo quando o app permite |
|
|
95
|
+
| `false` | Login estrito: exige acesso efetivo existente e nunca cria o vínculo |
|
|
96
|
+
| `true` | Signup explícito: cria o vínculo quando o app permite |
|
|
97
|
+
|
|
98
|
+
```typescript
|
|
99
|
+
await loginWithGoogleMitra({ create: false }); // Entrar
|
|
100
|
+
await loginWithGoogleMitra({ create: true }); // Criar conta
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
O login estrito pode retornar `APP_ACCESS_REQUIRED` quando não existe acesso ou
|
|
104
|
+
`APP_ACCESS_REVOKED` quando o vínculo foi desligado. Signup bloqueado retorna
|
|
105
|
+
`SIGNUP_NOT_ALLOWED`. O mesmo campo é preservado no modo redirect.
|
|
106
|
+
|
|
90
107
|
### Login via Redirect (mobile)
|
|
91
108
|
|
|
92
109
|
No celular o popup vira aba — use `mode: 'redirect'`: a página de auth navega de volta pro app com `#codeMitra`/`#stateMitra` no fragment, e o app conclui com `exchangeSsoCodeMitra`.
|
|
@@ -284,13 +301,24 @@ const existing = getAgentTaskMitra({ taskId: 'uuid-da-task' });
|
|
|
284
301
|
await existing.loadHistory({ limit: 50 });
|
|
285
302
|
```
|
|
286
303
|
|
|
287
|
-
`getAgentTaskMitra({ create: true, agentType?, name?, agentId?, reasoningEffort?, transport? })` ou `getAgentTaskMitra({ taskId, transport? })`.
|
|
304
|
+
`getAgentTaskMitra({ create: true, agentType?, name?, agentId?, reasoningEffort?, transport?, userId? })` ou `getAgentTaskMitra({ taskId, transport?, userId? })`.
|
|
288
305
|
|
|
289
306
|
**Agente autônomo**: a autonomia é **propriedade do AGENTE** (`autonomous` em `createAgentMitra`/`updateAgentMitra`, no `mitra-sdk`) — não existe flag na criação do chat. Ao criar um chat contra um agente autônomo (`getAgentTaskMitra({ create: true, agentId })`), o copilot deriva a autonomia do agente e o chat já nasce **sem dono** (`user_id NULL` — a dona é o agente), usando a connection anexada ao agente como credencial. Exige auth `AGENT_WRITE` (chave de SF ou token de app EDIT) — usuário business comum não abre chat autônomo. Depois de criado, dirigir/listar é igual ao chat normal (`getAgentTaskMitra({ taskId })`, `send`, `manageAgentChatMitra({ list, agentId })`).
|
|
290
307
|
|
|
291
308
|
- `agentType` vem de `manageAgentCredentialMitra({ action: 'list_models' })` — ex.: `'ANTHROPIC_CLAUDE_OPUS'`, `'OPENAI_GPT5'`. Default: `'ANTHROPIC_CLAUDE_OPUS'`.
|
|
292
309
|
- **`agentId`**: id de um agente business (CRUD via `mitra-sdk`: `listAgentsMitra` e família). A sessão sobe com o system prompt do agente e um token escopado — as tools enxergam só as Server Functions dele. **Sem `agentId`: sessão business sem agente** — sem system prompt e sem acesso às Server Functions (as tools recusam); não há adoção automática de agente único. Na prática, sempre passe `agentId`.
|
|
293
310
|
|
|
311
|
+
**Agir em nome do dono (`userId`)**: uma Server Function disparada por webhook/cron pode abrir e dirigir o chat de um usuário específico, em nome dele — o chat é normal, com dono; o turno roda com a identidade e a credencial do dono (connection do agente primeiro, senão a conta dele). Exige `AGENT_WRITE` no app (senão 403); o backend decide a autorização, a SDK só repassa. Tudo opcional: ausente = comportamento de sempre, byte a byte.
|
|
312
|
+
|
|
313
|
+
```typescript
|
|
314
|
+
// SF reagindo a webhook: continua a thread da pessoa atendida
|
|
315
|
+
const task = getAgentTaskMitra({ create: true, agentId, userId: 'uuid-do-usuario' }); // chat nasce DELE
|
|
316
|
+
const dela = await manageAgentChatMitra({ action: 'list', userId: 'uuid-do-usuario' }); // chats DELA
|
|
317
|
+
const mesma = getAgentTaskMitra({ taskId, userId: 'uuid-do-usuario' }); // defensivo: 404 se o chat não for dela
|
|
318
|
+
```
|
|
319
|
+
|
|
320
|
+
Erros nomeados: `403` sem `AGENT_WRITE`; `400 AUTONOMOUS_TASK_HAS_NO_OWNER` (userId + agente autônomo é contradição); `404` quando o `userId` defensivo não bate com o dono real. Nunca invente `userId` de texto do usuário — use o id do vínculo canal→usuário da sua aplicação.
|
|
321
|
+
|
|
294
322
|
#### Propriedades (somente leitura)
|
|
295
323
|
|
|
296
324
|
| Propriedade | Tipo | Descrição |
|
|
@@ -348,7 +376,18 @@ const { providers } = await manageAgentCredentialMitra({ action: 'list_providers
|
|
|
348
376
|
const { models } = await manageAgentCredentialMitra({ action: 'list_models' });
|
|
349
377
|
// AgentModel[]: { model, name, provider, agentType, reasoningOptions }
|
|
350
378
|
// reasoningOptions = registro das intensidades válidas por modelo (variam por
|
|
351
|
-
// harness) — monte o seletor de reasoning a partir DAQUI, nunca hardcode
|
|
379
|
+
// harness) — monte o seletor de reasoning a partir DAQUI, nunca hardcode.
|
|
380
|
+
// Round-trip: os valores vêm em minúsculo e são aceitos na entrada COMO ESTÃO.
|
|
381
|
+
|
|
382
|
+
// Com agentId: o que o PRÓXIMO TURNO daquele agente consegue rodar.
|
|
383
|
+
// Agente com connection → catálogo da connection, SEMPRE (é ela que roda o
|
|
384
|
+
// turno, mesmo que o caller tenha credencial própria). Sem connection →
|
|
385
|
+
// fallback pro catálogo da credencial do usuário.
|
|
386
|
+
const doAgente = await manageAgentCredentialMitra({ action: 'list_models', agentId: 'uuid-do-agente' });
|
|
387
|
+
// Erros nomeados (err.code, HTTP 400 — reaja pelo código):
|
|
388
|
+
// NO_CREDENTIAL_AVAILABLE → nenhuma credencial utilizável (nunca vem lista
|
|
389
|
+
// vazia nesse caso) — mande conectar um provider
|
|
390
|
+
// CONNECTION_NOT_FOUND → a connection do agente não existe mais
|
|
352
391
|
|
|
353
392
|
// API key
|
|
354
393
|
await manageAgentCredentialMitra({ action: 'save', target: 'openai', key: 'sk-...' });
|
package/dist/index.d.mts
CHANGED
|
@@ -10,7 +10,12 @@ interface LoginOptions {
|
|
|
10
10
|
mode?: 'popup' | 'redirect';
|
|
11
11
|
/** URL de retorno após login com mode 'redirect'. A página de auth redirecionará de volta para esta URL com token nos query params. */
|
|
12
12
|
returnTo?: string;
|
|
13
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* Controls the SSO intent sent to POST /auth/{provider}.
|
|
15
|
+
* Omitted preserves the combined legacy behavior. `false` performs a strict
|
|
16
|
+
* login without creating app access. `true` performs signup and may create
|
|
17
|
+
* app access when signup is allowed.
|
|
18
|
+
*/
|
|
14
19
|
create?: boolean;
|
|
15
20
|
/** Título exibido na página de auth (ex: nome da aplicação). */
|
|
16
21
|
title?: string;
|
|
@@ -243,6 +248,11 @@ interface ManageAgentChatListOptions {
|
|
|
243
248
|
projectId?: number | string;
|
|
244
249
|
/** Filtra os chats de um agente business específico. Omitido = todos os chats. */
|
|
245
250
|
agentId?: string;
|
|
251
|
+
/**
|
|
252
|
+
* Em nome de outro usuário (exige AGENT_WRITE no app; senão 403): lista os
|
|
253
|
+
* chats DELE em vez dos do caller. Omitido = chats de quem chama, como sempre.
|
|
254
|
+
*/
|
|
255
|
+
userId?: string;
|
|
246
256
|
/** Inclui só arquivados (true) ou só ativos (false, default). */
|
|
247
257
|
archived?: boolean;
|
|
248
258
|
/** Busca por título. */
|
|
@@ -308,6 +318,17 @@ interface GetAgentTaskCreateOptions {
|
|
|
308
318
|
* automaticamente — não existe flag aqui; exige auth AGENT_WRITE.
|
|
309
319
|
*/
|
|
310
320
|
agentId?: string;
|
|
321
|
+
/**
|
|
322
|
+
* Agir EM NOME do dono do chat (exige AGENT_WRITE no app; senão 403) — o
|
|
323
|
+
* chat nasce pertencendo a esse usuário e o turno roda com a identidade e a
|
|
324
|
+
* credencial DELE (connection do agente primeiro, senão a conta do dono).
|
|
325
|
+
* Uso típico: Server Function reagindo a webhook/cron/canal externo que
|
|
326
|
+
* continua a thread da pessoa atendida. NUNCA invente userId a partir de
|
|
327
|
+
* texto — use o id que a aplicação já tem no vínculo canal→usuário.
|
|
328
|
+
* Omitido = chat do caller, byte a byte como sempre.
|
|
329
|
+
* Com agente AUTÔNOMO é contradição: 400 AUTONOMOUS_TASK_HAS_NO_OWNER.
|
|
330
|
+
*/
|
|
331
|
+
userId?: string;
|
|
311
332
|
/** Transporte do prompt (default 'ws'). */
|
|
312
333
|
transport?: AgentTaskTransport;
|
|
313
334
|
}
|
|
@@ -318,6 +339,12 @@ interface GetAgentTaskOpenOptions {
|
|
|
318
339
|
projectId?: number | string;
|
|
319
340
|
/** Transporte do prompt (default 'ws'). */
|
|
320
341
|
transport?: AgentTaskTransport;
|
|
342
|
+
/**
|
|
343
|
+
* Validação defensiva ao agir em nome do dono (AGENT_WRITE): viaja no
|
|
344
|
+
* readChat e nos inputs — o backend devolve 404 se o chat não pertencer a
|
|
345
|
+
* esse usuário. Omitido = contexto do caller.
|
|
346
|
+
*/
|
|
347
|
+
userId?: string;
|
|
321
348
|
}
|
|
322
349
|
type GetAgentTaskOptions = GetAgentTaskCreateOptions | GetAgentTaskOpenOptions;
|
|
323
350
|
type AgentTaskStatus = 'opening' | 'idle' | 'streaming' | 'cancelled' | 'error' | 'closed';
|
|
@@ -336,8 +363,9 @@ interface SendOptions {
|
|
|
336
363
|
* Intensidade de reasoning DESTA mensagem. Valores válidos vêm SEMPRE do
|
|
337
364
|
* registro `reasoningOptions` do modelo em list_models (variam por harness) —
|
|
338
365
|
* nunca invente: valor fora do registro é recusado pelo copilot
|
|
339
|
-
* (INVALID_REASONING_EFFORT). Sobrescreve o default da session;
|
|
340
|
-
*
|
|
366
|
+
* (INVALID_REASONING_EFFORT). Sobrescreve o default da session; round-trip —
|
|
367
|
+
* a SDK envia o valor COMO ESTÁ (minúsculo), sem normalizar. Omitido = herda
|
|
368
|
+
* o default da abertura (ou o do backend).
|
|
341
369
|
*/
|
|
342
370
|
reasoningEffort?: string;
|
|
343
371
|
/**
|
|
@@ -448,6 +476,8 @@ interface AgentModel {
|
|
|
448
476
|
* ['none','minimal','low','medium','high','xhigh','max','ultra'].
|
|
449
477
|
* A UI monta o seletor a partir DAQUI; valor fora do registro é recusado
|
|
450
478
|
* pelo copilot (INVALID_REASONING_EFFORT).
|
|
479
|
+
* ROUND-TRIP: os valores vêm em minúsculo e são aceitos na entrada COMO
|
|
480
|
+
* ESTÃO — a SDK não normaliza (não maiusculize, não traduza).
|
|
451
481
|
* ATENÇÃO: a lista de models vem VAZIA enquanto nenhuma credencial/connection
|
|
452
482
|
* estiver conectada (o catálogo é escopado pelo que dá pra rodar) — o seletor
|
|
453
483
|
* só existe depois de conectar um provider e escolher um modelo.
|
|
@@ -483,6 +513,7 @@ type ManageAgentCredentialOptions = {
|
|
|
483
513
|
projectId?: number | string;
|
|
484
514
|
} | {
|
|
485
515
|
action: 'list_models';
|
|
516
|
+
agentId?: string;
|
|
486
517
|
projectId?: number | string;
|
|
487
518
|
} | {
|
|
488
519
|
action: 'save';
|
|
@@ -656,7 +687,7 @@ declare function getAgentTaskMitra(options: GetAgentTaskOptions): AgentTaskSessi
|
|
|
656
687
|
* Função ÚNICA `manageAgentCredentialMitra`, toda HTTP pela BFF no baseURL
|
|
657
688
|
* normal (`/agentAiShortcut/*`) — herda fetchWithRefresh e o CORS do BFF:
|
|
658
689
|
* - list_providers → GET /agentAiShortcut/listProviders?projectId=
|
|
659
|
-
* - list_models → GET /agentAiShortcut/listModels?projectId=
|
|
690
|
+
* - list_models → GET /agentAiShortcut/listModels?projectId=&agentId= (agentId opcional)
|
|
660
691
|
* - save → POST /agentAiShortcut/saveCredential {projectId, provider, key}
|
|
661
692
|
* - remove → POST /agentAiShortcut/removeCredential {projectId, provider}
|
|
662
693
|
* - auth → POST /agentAiShortcut/oauthStart {projectId, provider}
|
|
@@ -681,6 +712,7 @@ declare function manageAgentCredentialMitra(options: {
|
|
|
681
712
|
}): Promise<ListAgentProvidersResult>;
|
|
682
713
|
declare function manageAgentCredentialMitra(options: {
|
|
683
714
|
action: 'list_models';
|
|
715
|
+
agentId?: string;
|
|
684
716
|
projectId?: number | string;
|
|
685
717
|
}): Promise<ListAgentModelsResult>;
|
|
686
718
|
declare function manageAgentCredentialMitra(options: {
|
package/dist/index.d.ts
CHANGED
|
@@ -10,7 +10,12 @@ interface LoginOptions {
|
|
|
10
10
|
mode?: 'popup' | 'redirect';
|
|
11
11
|
/** URL de retorno após login com mode 'redirect'. A página de auth redirecionará de volta para esta URL com token nos query params. */
|
|
12
12
|
returnTo?: string;
|
|
13
|
-
/**
|
|
13
|
+
/**
|
|
14
|
+
* Controls the SSO intent sent to POST /auth/{provider}.
|
|
15
|
+
* Omitted preserves the combined legacy behavior. `false` performs a strict
|
|
16
|
+
* login without creating app access. `true` performs signup and may create
|
|
17
|
+
* app access when signup is allowed.
|
|
18
|
+
*/
|
|
14
19
|
create?: boolean;
|
|
15
20
|
/** Título exibido na página de auth (ex: nome da aplicação). */
|
|
16
21
|
title?: string;
|
|
@@ -243,6 +248,11 @@ interface ManageAgentChatListOptions {
|
|
|
243
248
|
projectId?: number | string;
|
|
244
249
|
/** Filtra os chats de um agente business específico. Omitido = todos os chats. */
|
|
245
250
|
agentId?: string;
|
|
251
|
+
/**
|
|
252
|
+
* Em nome de outro usuário (exige AGENT_WRITE no app; senão 403): lista os
|
|
253
|
+
* chats DELE em vez dos do caller. Omitido = chats de quem chama, como sempre.
|
|
254
|
+
*/
|
|
255
|
+
userId?: string;
|
|
246
256
|
/** Inclui só arquivados (true) ou só ativos (false, default). */
|
|
247
257
|
archived?: boolean;
|
|
248
258
|
/** Busca por título. */
|
|
@@ -308,6 +318,17 @@ interface GetAgentTaskCreateOptions {
|
|
|
308
318
|
* automaticamente — não existe flag aqui; exige auth AGENT_WRITE.
|
|
309
319
|
*/
|
|
310
320
|
agentId?: string;
|
|
321
|
+
/**
|
|
322
|
+
* Agir EM NOME do dono do chat (exige AGENT_WRITE no app; senão 403) — o
|
|
323
|
+
* chat nasce pertencendo a esse usuário e o turno roda com a identidade e a
|
|
324
|
+
* credencial DELE (connection do agente primeiro, senão a conta do dono).
|
|
325
|
+
* Uso típico: Server Function reagindo a webhook/cron/canal externo que
|
|
326
|
+
* continua a thread da pessoa atendida. NUNCA invente userId a partir de
|
|
327
|
+
* texto — use o id que a aplicação já tem no vínculo canal→usuário.
|
|
328
|
+
* Omitido = chat do caller, byte a byte como sempre.
|
|
329
|
+
* Com agente AUTÔNOMO é contradição: 400 AUTONOMOUS_TASK_HAS_NO_OWNER.
|
|
330
|
+
*/
|
|
331
|
+
userId?: string;
|
|
311
332
|
/** Transporte do prompt (default 'ws'). */
|
|
312
333
|
transport?: AgentTaskTransport;
|
|
313
334
|
}
|
|
@@ -318,6 +339,12 @@ interface GetAgentTaskOpenOptions {
|
|
|
318
339
|
projectId?: number | string;
|
|
319
340
|
/** Transporte do prompt (default 'ws'). */
|
|
320
341
|
transport?: AgentTaskTransport;
|
|
342
|
+
/**
|
|
343
|
+
* Validação defensiva ao agir em nome do dono (AGENT_WRITE): viaja no
|
|
344
|
+
* readChat e nos inputs — o backend devolve 404 se o chat não pertencer a
|
|
345
|
+
* esse usuário. Omitido = contexto do caller.
|
|
346
|
+
*/
|
|
347
|
+
userId?: string;
|
|
321
348
|
}
|
|
322
349
|
type GetAgentTaskOptions = GetAgentTaskCreateOptions | GetAgentTaskOpenOptions;
|
|
323
350
|
type AgentTaskStatus = 'opening' | 'idle' | 'streaming' | 'cancelled' | 'error' | 'closed';
|
|
@@ -336,8 +363,9 @@ interface SendOptions {
|
|
|
336
363
|
* Intensidade de reasoning DESTA mensagem. Valores válidos vêm SEMPRE do
|
|
337
364
|
* registro `reasoningOptions` do modelo em list_models (variam por harness) —
|
|
338
365
|
* nunca invente: valor fora do registro é recusado pelo copilot
|
|
339
|
-
* (INVALID_REASONING_EFFORT). Sobrescreve o default da session;
|
|
340
|
-
*
|
|
366
|
+
* (INVALID_REASONING_EFFORT). Sobrescreve o default da session; round-trip —
|
|
367
|
+
* a SDK envia o valor COMO ESTÁ (minúsculo), sem normalizar. Omitido = herda
|
|
368
|
+
* o default da abertura (ou o do backend).
|
|
341
369
|
*/
|
|
342
370
|
reasoningEffort?: string;
|
|
343
371
|
/**
|
|
@@ -448,6 +476,8 @@ interface AgentModel {
|
|
|
448
476
|
* ['none','minimal','low','medium','high','xhigh','max','ultra'].
|
|
449
477
|
* A UI monta o seletor a partir DAQUI; valor fora do registro é recusado
|
|
450
478
|
* pelo copilot (INVALID_REASONING_EFFORT).
|
|
479
|
+
* ROUND-TRIP: os valores vêm em minúsculo e são aceitos na entrada COMO
|
|
480
|
+
* ESTÃO — a SDK não normaliza (não maiusculize, não traduza).
|
|
451
481
|
* ATENÇÃO: a lista de models vem VAZIA enquanto nenhuma credencial/connection
|
|
452
482
|
* estiver conectada (o catálogo é escopado pelo que dá pra rodar) — o seletor
|
|
453
483
|
* só existe depois de conectar um provider e escolher um modelo.
|
|
@@ -483,6 +513,7 @@ type ManageAgentCredentialOptions = {
|
|
|
483
513
|
projectId?: number | string;
|
|
484
514
|
} | {
|
|
485
515
|
action: 'list_models';
|
|
516
|
+
agentId?: string;
|
|
486
517
|
projectId?: number | string;
|
|
487
518
|
} | {
|
|
488
519
|
action: 'save';
|
|
@@ -656,7 +687,7 @@ declare function getAgentTaskMitra(options: GetAgentTaskOptions): AgentTaskSessi
|
|
|
656
687
|
* Função ÚNICA `manageAgentCredentialMitra`, toda HTTP pela BFF no baseURL
|
|
657
688
|
* normal (`/agentAiShortcut/*`) — herda fetchWithRefresh e o CORS do BFF:
|
|
658
689
|
* - list_providers → GET /agentAiShortcut/listProviders?projectId=
|
|
659
|
-
* - list_models → GET /agentAiShortcut/listModels?projectId=
|
|
690
|
+
* - list_models → GET /agentAiShortcut/listModels?projectId=&agentId= (agentId opcional)
|
|
660
691
|
* - save → POST /agentAiShortcut/saveCredential {projectId, provider, key}
|
|
661
692
|
* - remove → POST /agentAiShortcut/removeCredential {projectId, provider}
|
|
662
693
|
* - auth → POST /agentAiShortcut/oauthStart {projectId, provider}
|
|
@@ -681,6 +712,7 @@ declare function manageAgentCredentialMitra(options: {
|
|
|
681
712
|
}): Promise<ListAgentProvidersResult>;
|
|
682
713
|
declare function manageAgentCredentialMitra(options: {
|
|
683
714
|
action: 'list_models';
|
|
715
|
+
agentId?: string;
|
|
684
716
|
projectId?: number | string;
|
|
685
717
|
}): Promise<ListAgentModelsResult>;
|
|
686
718
|
declare function manageAgentCredentialMitra(options: {
|
package/dist/index.js
CHANGED
|
@@ -86,11 +86,12 @@ function stripToOriginPath(url) {
|
|
|
86
86
|
return url.split("?")[0].split("#")[0];
|
|
87
87
|
}
|
|
88
88
|
}
|
|
89
|
-
async function exchangeSsoCode(authUrl, provider, code, redirectUri, projectId) {
|
|
89
|
+
async function exchangeSsoCode(authUrl, provider, code, redirectUri, projectId, create) {
|
|
90
90
|
const data = await postBffAuth(buildBffAuthEndpoint(authUrl, `/${provider}`), {
|
|
91
91
|
appId: String(projectId),
|
|
92
92
|
code,
|
|
93
|
-
redirectUri
|
|
93
|
+
redirectUri,
|
|
94
|
+
...create !== void 0 ? { create } : {}
|
|
94
95
|
});
|
|
95
96
|
const response = {
|
|
96
97
|
token: data.token,
|
|
@@ -229,7 +230,10 @@ async function loginWithProvider(provider, options) {
|
|
|
229
230
|
const startUrl = buildStartUrl(authPageUrl, provider, state, appId, authUrl);
|
|
230
231
|
const { code, token } = await openOAuthPopup(startUrl, pageOrigin, state);
|
|
231
232
|
if (code) {
|
|
232
|
-
return await exchangeSsoCode(authUrl, provider, code, redirectUri, projectId);
|
|
233
|
+
return await exchangeSsoCode(authUrl, provider, code, redirectUri, projectId, options == null ? void 0 : options.create);
|
|
234
|
+
}
|
|
235
|
+
if ((options == null ? void 0 : options.create) !== void 0) {
|
|
236
|
+
throw new Error("Explicit SSO intent requires an auth page that returns the authorization code.");
|
|
233
237
|
}
|
|
234
238
|
const response = normalizeResponse(token, authUrl);
|
|
235
239
|
autoConfigureFromLogin(response, authUrl, projectId);
|
|
@@ -246,7 +250,14 @@ async function startSsoRedirect(provider, options) {
|
|
|
246
250
|
const appId = String(projectId);
|
|
247
251
|
const authPageUrl = await fetchSsoAuthPageUrl();
|
|
248
252
|
const redirectUri = stripToOriginPath(authPageUrl);
|
|
249
|
-
persistRedirectContext({
|
|
253
|
+
persistRedirectContext({
|
|
254
|
+
state,
|
|
255
|
+
provider,
|
|
256
|
+
authUrl,
|
|
257
|
+
projectId: appId,
|
|
258
|
+
redirectUri,
|
|
259
|
+
...(options == null ? void 0 : options.create) !== void 0 ? { create: options.create } : {}
|
|
260
|
+
});
|
|
250
261
|
const startUrl = buildStartUrl(authPageUrl, provider, state, appId, authUrl, window.location.href);
|
|
251
262
|
window.location.assign(startUrl);
|
|
252
263
|
return new Promise(() => {
|
|
@@ -258,7 +269,14 @@ async function exchangeSsoCodeMitra(options) {
|
|
|
258
269
|
if (!ctx || ctx.state !== options.state) {
|
|
259
270
|
throw new Error("State inv\xE1lido no retorno do SSO (poss\xEDvel CSRF).");
|
|
260
271
|
}
|
|
261
|
-
return exchangeSsoCode(
|
|
272
|
+
return exchangeSsoCode(
|
|
273
|
+
ctx.authUrl,
|
|
274
|
+
ctx.provider,
|
|
275
|
+
options.code,
|
|
276
|
+
ctx.redirectUri,
|
|
277
|
+
ctx.projectId,
|
|
278
|
+
ctx.create
|
|
279
|
+
);
|
|
262
280
|
}
|
|
263
281
|
async function loginWithGoogleMitra(options) {
|
|
264
282
|
return loginWithProvider("google", options);
|
|
@@ -342,15 +360,18 @@ async function tryRefreshToken() {
|
|
|
342
360
|
}
|
|
343
361
|
}
|
|
344
362
|
async function handleResponse(response) {
|
|
363
|
+
var _a, _b, _c, _d;
|
|
345
364
|
const text = await response.text();
|
|
346
365
|
const { data, isJson } = parseBody(text);
|
|
347
366
|
if (!response.ok) {
|
|
348
367
|
const fallback = !isJson && text ? `HTTP ${response.status} \u2014 ${text}` : `HTTP ${response.status}`;
|
|
349
|
-
const base = isJson && ((data == null ? void 0 : data.message) || (data == null ? void 0 : data.error)) || fallback;
|
|
368
|
+
const base = isJson && ((data == null ? void 0 : data.message) || ((_a = data == null ? void 0 : data.error) == null ? void 0 : _a.message) || (data == null ? void 0 : data.error)) || fallback;
|
|
350
369
|
const msg = isJson && (data == null ? void 0 : data.hint) ? `${base} \u2014 ${data.hint}` : base;
|
|
370
|
+
const code = isJson && ((_d = (_c = data == null ? void 0 : data.error_code) != null ? _c : (_b = data == null ? void 0 : data.error) == null ? void 0 : _b.code) != null ? _d : data == null ? void 0 : data.code) || void 0;
|
|
351
371
|
throw {
|
|
352
|
-
message: msg,
|
|
372
|
+
message: typeof msg === "string" ? msg : fallback,
|
|
353
373
|
status: response.status,
|
|
374
|
+
...code ? { code } : {},
|
|
354
375
|
details: data
|
|
355
376
|
};
|
|
356
377
|
}
|
|
@@ -483,6 +504,7 @@ var AgentTaskSession = class {
|
|
|
483
504
|
this._isNew = init.kind === "new";
|
|
484
505
|
this._transport = (_a = init.transport) != null ? _a : "ws";
|
|
485
506
|
this._projectId = init.projectId;
|
|
507
|
+
this._userId = init.userId;
|
|
486
508
|
if (init.kind === "new") {
|
|
487
509
|
this._agentType = (_b = init.agentType) != null ? _b : DEFAULT_AGENT_TYPE;
|
|
488
510
|
this._initialName = init.name;
|
|
@@ -521,7 +543,7 @@ var AgentTaskSession = class {
|
|
|
521
543
|
// ── Abertura de chat existente ─────────
|
|
522
544
|
async _openExisting(taskId) {
|
|
523
545
|
try {
|
|
524
|
-
const t = await readChatTask(taskId, this._projectId);
|
|
546
|
+
const t = await readChatTask(taskId, this._projectId, this._userId);
|
|
525
547
|
this._task = toAgentChat(t);
|
|
526
548
|
this._agentType = this._task.agentType;
|
|
527
549
|
if (this._status === "opening") this._setStatus("idle");
|
|
@@ -546,9 +568,10 @@ var AgentTaskSession = class {
|
|
|
546
568
|
}
|
|
547
569
|
/**
|
|
548
570
|
* Corpo do input `message` — idêntico no WS e no POST /inputs.
|
|
549
|
-
* reasoningEffort: da mensagem, senão o default da session;
|
|
550
|
-
*
|
|
551
|
-
*
|
|
571
|
+
* reasoningEffort: da mensagem, senão o default da session; round-trip com
|
|
572
|
+
* reasoningOptions do list_models — vai COMO ESTÁ (minúsculo), sem
|
|
573
|
+
* normalizar. agentType por mensagem troca o modelo dentro do mesmo harness
|
|
574
|
+
* (Claude<->Codex é recusado com HARNESS_SWITCH).
|
|
552
575
|
*/
|
|
553
576
|
_buildMessageInput(prompt, options) {
|
|
554
577
|
var _a;
|
|
@@ -556,7 +579,9 @@ var AgentTaskSession = class {
|
|
|
556
579
|
return {
|
|
557
580
|
type: "message",
|
|
558
581
|
content: prompt,
|
|
559
|
-
|
|
582
|
+
// Round-trip com list_models: o valor de reasoningOptions vai COMO ESTÁ
|
|
583
|
+
// (minúsculo) — a SDK não normaliza.
|
|
584
|
+
...effort ? { reasoningEffort: String(effort) } : {},
|
|
560
585
|
...(options == null ? void 0 : options.agentType) ? { agentType: options.agentType } : {}
|
|
561
586
|
};
|
|
562
587
|
}
|
|
@@ -573,7 +598,8 @@ var AgentTaskSession = class {
|
|
|
573
598
|
projectId: this._projectId,
|
|
574
599
|
title: this._initialName,
|
|
575
600
|
agentType: this._agentType,
|
|
576
|
-
agentId: this._agentId
|
|
601
|
+
agentId: this._agentId,
|
|
602
|
+
userId: this._userId
|
|
577
603
|
});
|
|
578
604
|
this._task = toAgentChat(t);
|
|
579
605
|
this._taskId = this._task.id;
|
|
@@ -721,6 +747,7 @@ var AgentTaskSession = class {
|
|
|
721
747
|
throw new Error("AgentTaskSession: sem taskId \u2014 task ainda n\xE3o criada.");
|
|
722
748
|
}
|
|
723
749
|
if (isTokenExpiring()) await tryRefreshToken();
|
|
750
|
+
const payload = this._userId ? { ...body, userId: this._userId } : body;
|
|
724
751
|
const doPost = async () => fetch(
|
|
725
752
|
`${getTaskHttpBase()}/${encodeURIComponent(this._taskId)}/inputs`,
|
|
726
753
|
{
|
|
@@ -729,7 +756,7 @@ var AgentTaskSession = class {
|
|
|
729
756
|
"Content-Type": "application/json",
|
|
730
757
|
Authorization: `Bearer ${getRawToken()}`
|
|
731
758
|
},
|
|
732
|
-
body: JSON.stringify(
|
|
759
|
+
body: JSON.stringify(payload)
|
|
733
760
|
}
|
|
734
761
|
);
|
|
735
762
|
let res = await doPost();
|
|
@@ -1051,14 +1078,23 @@ async function createChatTask(options) {
|
|
|
1051
1078
|
// Autonomia é propriedade do AGENTE (createAgentMitra/updateAgentMitra no
|
|
1052
1079
|
// mitra-sdk): o copilot deriva do agentId — o chat de agente autônomo já
|
|
1053
1080
|
// nasce ownerless sem flag nenhum aqui.
|
|
1054
|
-
...options.agentId ? { agentId: options.agentId } : {}
|
|
1081
|
+
...options.agentId ? { agentId: options.agentId } : {},
|
|
1082
|
+
// Agir EM NOME do dono (SF/webhook/cron com AGENT_WRITE): o chat nasce
|
|
1083
|
+
// pertencendo a esse usuário; o turno roda com a identidade/credencial
|
|
1084
|
+
// DELE. Ausente = chat do caller, byte a byte como sempre.
|
|
1085
|
+
// Erros do backend passam crus: 403 (sem AGENT_WRITE),
|
|
1086
|
+
// 400 AUTONOMOUS_TASK_HAS_NO_OWNER (userId + agente autônomo é contradição).
|
|
1087
|
+
...options.userId ? { userId: options.userId } : {}
|
|
1055
1088
|
});
|
|
1056
1089
|
return env.result;
|
|
1057
1090
|
}
|
|
1058
|
-
async function readChatTask(taskId, projectId) {
|
|
1091
|
+
async function readChatTask(taskId, projectId, userId) {
|
|
1059
1092
|
const env = await http.get("/agentAiShortcut/readChat", {
|
|
1060
1093
|
projectId: resolveProjectId(projectId),
|
|
1061
|
-
taskId
|
|
1094
|
+
taskId,
|
|
1095
|
+
// Validação defensiva: com userId, o backend devolve 404 se o chat não
|
|
1096
|
+
// pertencer àquele dono.
|
|
1097
|
+
...userId ? { userId } : {}
|
|
1062
1098
|
});
|
|
1063
1099
|
return env.result;
|
|
1064
1100
|
}
|
|
@@ -1086,6 +1122,8 @@ async function manageAgentChatMitra(options) {
|
|
|
1086
1122
|
const env = await http.get("/agentAiShortcut/listChats", {
|
|
1087
1123
|
projectId,
|
|
1088
1124
|
agentId: options.agentId,
|
|
1125
|
+
// Em nome de outro usuário (AGENT_WRITE): lista os chats DELE, não os do caller.
|
|
1126
|
+
userId: options.userId,
|
|
1089
1127
|
archived: options.archived,
|
|
1090
1128
|
search: options.search,
|
|
1091
1129
|
page: options.page,
|
|
@@ -1121,7 +1159,8 @@ function getAgentTaskMitra(options) {
|
|
|
1121
1159
|
kind: "existing",
|
|
1122
1160
|
taskId: options.taskId,
|
|
1123
1161
|
projectId: options.projectId,
|
|
1124
|
-
transport: options.transport
|
|
1162
|
+
transport: options.transport,
|
|
1163
|
+
userId: options.userId
|
|
1125
1164
|
});
|
|
1126
1165
|
}
|
|
1127
1166
|
if ("create" in options && options.create) {
|
|
@@ -1132,7 +1171,8 @@ function getAgentTaskMitra(options) {
|
|
|
1132
1171
|
name: options.name,
|
|
1133
1172
|
agentId: options.agentId,
|
|
1134
1173
|
transport: options.transport,
|
|
1135
|
-
reasoningEffort: options.reasoningEffort
|
|
1174
|
+
reasoningEffort: options.reasoningEffort,
|
|
1175
|
+
userId: options.userId
|
|
1136
1176
|
});
|
|
1137
1177
|
}
|
|
1138
1178
|
throw new Error("getAgentTaskMitra: passe { create: true } ou { taskId }.");
|
|
@@ -1158,7 +1198,10 @@ async function manageAgentCredentialMitra(options) {
|
|
|
1158
1198
|
return { providers: (_a = env.result) != null ? _a : [] };
|
|
1159
1199
|
}
|
|
1160
1200
|
case "list_models": {
|
|
1161
|
-
const env = await http.get("/agentAiShortcut/listModels", {
|
|
1201
|
+
const env = await http.get("/agentAiShortcut/listModels", {
|
|
1202
|
+
projectId,
|
|
1203
|
+
...options.agentId ? { agentId: options.agentId } : {}
|
|
1204
|
+
});
|
|
1162
1205
|
return { models: (_b = env.result) != null ? _b : [] };
|
|
1163
1206
|
}
|
|
1164
1207
|
case "save": {
|