hobots 1.9.0 → 1.9.2
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 +9 -7
- package/dist/index.cjs +64 -9
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +38 -43
- package/dist/index.d.ts +38 -43
- package/dist/index.js +64 -9
- package/dist/index.js.map +1 -1
- package/docs/api-reference.md +14 -20
- package/docs/concepts.md +1 -1
- package/docs/getting-started.md +1 -1
- package/docs/tasks.md +21 -13
- package/package.json +1 -1
package/docs/api-reference.md
CHANGED
|
@@ -128,6 +128,19 @@ O teto da fila do transport (200 itens; ao encher, o **mais antigo** é descarta
|
|
|
128
128
|
| `tags` | `Record<string,string>` | tags só deste evento |
|
|
129
129
|
| `extra` | `Record<string,unknown>` | dados extras |
|
|
130
130
|
| `fingerprint` | `string[]` | agrupamento manual |
|
|
131
|
+
| `attachment` | `AttachInput \| CaptureAttachment` | print enviado junto da captura — dentro de uma execução de task, vira anexo da linha de log da run que espelha o evento; fora de uma execução é descartado com aviso. Guia: [Anexos](./tasks.md#anexos-screenshots) |
|
|
132
|
+
|
|
133
|
+
### CaptureAttachment
|
|
134
|
+
|
|
135
|
+
`AttachInput = Uint8Array | ArrayBuffer | string` (bytes ou um caminho de arquivo, só em Node). Para legenda ou content-type, passe o objeto:
|
|
136
|
+
|
|
137
|
+
| Campo | Tipo | Default | O que faz |
|
|
138
|
+
| --- | --- | --- | --- |
|
|
139
|
+
| `image` | `AttachInput` | — | a imagem em si |
|
|
140
|
+
| `caption` | `string` | — | legenda exibida sob a imagem ampliada; truncada em 200 caracteres e passada pelo scrub de segredos |
|
|
141
|
+
| `contentType` | `'image/png' \| 'image/jpeg' \| 'image/webp'` | detectado pelos *magic bytes* | só usado quando a detecção falha; a detecção sempre tem precedência |
|
|
142
|
+
|
|
143
|
+
O texto da linha de log é a mensagem capturada; o nível vem do `level` da captura (`'fatal'` vira `'error'`). O upload roda em segundo plano e **nunca bloqueia nem faz a captura lançar**. Limites (todos aplicados também no servidor): PNG/JPEG/WEBP, **5 MB** por imagem, **20** anexos por execução, **4** por linha de log.
|
|
131
144
|
|
|
132
145
|
`Severity = 'fatal' | 'error' | 'warning' | 'info' | 'debug' | 'success'`. O que cada nível significa (e por que `'success'` existe) em [Level](./concepts.md#level-severity).
|
|
133
146
|
|
|
@@ -159,7 +172,6 @@ interface RunContext {
|
|
|
159
172
|
signal: AbortSignal;
|
|
160
173
|
throwIfCanceled(): void; // lança RunCanceled se o signal já disparou
|
|
161
174
|
sleep(ms: number): Promise<void>; // espera cancelável — rejeita com RunCanceled no abort
|
|
162
|
-
attach(image: Uint8Array | ArrayBuffer | string, options?: AttachOptions): Promise<AttachResult>;
|
|
163
175
|
}
|
|
164
176
|
```
|
|
165
177
|
|
|
@@ -169,26 +181,8 @@ interface RunContext {
|
|
|
169
181
|
- **`signal`** — `AbortSignal` que dispara em cancelamento no app, timeout ou shutdown.
|
|
170
182
|
- **`throwIfCanceled()`** — o ponto de parada de uma linha: lança `RunCanceled` se o `signal` já disparou.
|
|
171
183
|
- **`sleep(ms)`** — espera que respeita o `signal` (rejeita com `RunCanceled` em vez de dormir até o fim). Use no lugar do seu `sleep` em esperas longas.
|
|
172
|
-
- **`attach(image, options?)`** — anexa um print à linha de log. Aceita bytes (`Uint8Array`/`ArrayBuffer`/`Buffer`) ou um caminho de arquivo (só em Node). A linha de log entra na hora; o upload é em segundo plano e **nunca lança**. Guia: [Anexos](./tasks.md#anexos-screenshots).
|
|
173
|
-
|
|
174
|
-
### AttachOptions
|
|
175
|
-
|
|
176
|
-
| Campo | Tipo | Default | O que faz |
|
|
177
|
-
| --- | --- | --- | --- |
|
|
178
|
-
| `caption` | `string` | — | legenda exibida sob a imagem ampliada; truncada em 200 caracteres e passada pelo scrub de segredos |
|
|
179
|
-
| `level` | `RunLogLevel` | `'info'` | nível da linha de log que carrega o anexo |
|
|
180
|
-
| `message` | `string` | `caption` ou `'captura de tela'` | texto da linha de log |
|
|
181
|
-
| `contentType` | `'image/png' \| 'image/jpeg' \| 'image/webp'` | detectado pelos *magic bytes* | só usado quando a detecção falha; a detecção sempre tem precedência |
|
|
182
|
-
|
|
183
|
-
### AttachResult
|
|
184
|
-
|
|
185
|
-
| Campo | Tipo | O que é |
|
|
186
|
-
| --- | --- | --- |
|
|
187
|
-
| `id` | `string` | id do anexo — o mesmo referenciado na linha de log |
|
|
188
|
-
| `ok` | `boolean` | `true` quando o binário chegou ao S3 |
|
|
189
|
-
| `reason` | `AttachFailureReason?` | `'too-large' \| 'quota' \| 'unsupported-format' \| 'read-failed' \| 'unsupported' \| 'upload-failed' \| 'canceled'` |
|
|
190
184
|
|
|
191
|
-
|
|
185
|
+
Para anexar um print a uma linha de log da run, use o campo `attachment` do [`CaptureHint`](#capturehint) em `captureException`/`captureMessage` dentro do handler. Guia: [Anexos](./tasks.md#anexos-screenshots).
|
|
192
186
|
|
|
193
187
|
---
|
|
194
188
|
|
package/docs/concepts.md
CHANGED
|
@@ -369,7 +369,7 @@ Cada run carrega os **`params`** (o JSON validado do formulário) e chega ao seu
|
|
|
369
369
|
|
|
370
370
|
Um **anexo** é uma imagem — na prática, um print da tela — vinculada a uma linha de log de uma [run](#run). Serve para responder "como estava a tela quando isso aconteceu?", pergunta que texto de log sozinho não responde. No app, aparece como miniatura logo abaixo da linha de log correspondente, na aba "logs do agente" da execução.
|
|
371
371
|
|
|
372
|
-
Quem captura é o seu código; o SDK só recebe a imagem pronta via [`
|
|
372
|
+
Quem captura é o seu código; o SDK só recebe a imagem pronta, via o campo [`attachment`](./tasks.md#anexos-screenshots) de `captureException`/`captureMessage`.
|
|
373
373
|
|
|
374
374
|
**O binário não passa pela API do Hobots.** O agente pede uma URL presignada, sobe direto no S3 e depois confirma. Isso mantém a API livre de tráfego pesado e permite imagens bem maiores do que o limite de corpo de um PATCH. O ciclo de vida de um anexo é:
|
|
375
375
|
|
package/docs/getting-started.md
CHANGED
|
@@ -88,7 +88,7 @@ Hobots.init({
|
|
|
88
88
|
|
|
89
89
|
Hobots.register('processar-nfe', async (params, ctx) => {
|
|
90
90
|
ctx.log.info(`processando lote ${params.lote}…`);
|
|
91
|
-
//
|
|
91
|
+
// Hobots.captureMessage('portal após o login', 'info', { attachment: await page.screenshot() }); // print junto do log
|
|
92
92
|
ctx.log.info('12 notas processadas'); // o retorno do handler é ignorado — reporte por log
|
|
93
93
|
});
|
|
94
94
|
Hobots.start(); // mantém o processo vivo até stop()/close()
|
package/docs/tasks.md
CHANGED
|
@@ -52,7 +52,6 @@ interface RunContext {
|
|
|
52
52
|
signal: AbortSignal;
|
|
53
53
|
throwIfCanceled(): void;
|
|
54
54
|
sleep(ms: number): Promise<void>;
|
|
55
|
-
attach(image, options?): Promise<AttachResult>; // anexa um print a uma linha de log
|
|
56
55
|
}
|
|
57
56
|
```
|
|
58
57
|
|
|
@@ -62,7 +61,6 @@ interface RunContext {
|
|
|
62
61
|
- **`ctx.signal`** — `AbortSignal` que dispara quando a run é **cancelada no app**, em **timeout** ou no **shutdown**. Cancelamento é cooperativo (veja abaixo).
|
|
63
62
|
- **`ctx.throwIfCanceled()`** — lança `RunCanceled` se o `signal` já disparou. O ponto de parada de 1 linha para chamar entre as etapas do trabalho.
|
|
64
63
|
- **`ctx.sleep(ms)`** — sleep que respeita o `signal`: rejeita com `RunCanceled` no cancelamento em vez de esperar até o fim. Use no lugar do seu `sleep` em esperas longas.
|
|
65
|
-
- **`ctx.attach(image, options?)`** — anexa um print da tela a uma linha de log (veja [Anexos](#anexos-screenshots) abaixo).
|
|
66
64
|
- **Retorno** — **ignorado**. O SDK não captura nem envia o valor retornado pelo handler ao servidor — resultados de execução podem conter dados sensíveis e não são coletados.
|
|
67
65
|
- **Erro lançado** — a run é reportada como `failed` com tipo/mensagem/stack (mensagem cap 10k, stack 20k).
|
|
68
66
|
|
|
@@ -72,18 +70,22 @@ Você pode tipar os params: `Hobots.register<{ lote: number }>(...)`.
|
|
|
72
70
|
|
|
73
71
|
## Anexos (screenshots)
|
|
74
72
|
|
|
75
|
-
Texto de log conta o que o robô fez; um print conta **como estava a tela**. `
|
|
73
|
+
Texto de log conta o que o robô fez; um print conta **como estava a tela**. Os métodos de captura — `Hobots.captureException(error, hint)` e `Hobots.captureMessage(message, level, hint)` — aceitam um **`attachment`** no hint. Dentro de uma execução de task, a imagem vira anexo da linha de log da run que espelha a captura, e aparece como miniatura logo abaixo dela na aba "logs do agente" da execução — clicável para ampliar.
|
|
76
74
|
|
|
77
75
|
```js
|
|
78
76
|
Hobots.register('processar-nfe', async (params, ctx) => {
|
|
79
77
|
await entrar();
|
|
80
|
-
|
|
78
|
+
Hobots.captureMessage('portal após o login', 'info', {
|
|
79
|
+
attachment: await page.screenshot(),
|
|
80
|
+
});
|
|
81
81
|
|
|
82
82
|
try {
|
|
83
83
|
await emitir(params);
|
|
84
84
|
} catch (erro) {
|
|
85
85
|
// numa falha é justamente quando o print importa
|
|
86
|
-
|
|
86
|
+
Hobots.captureException(erro, {
|
|
87
|
+
attachment: { image: await page.screenshot(), caption: 'tela no momento do erro' },
|
|
88
|
+
});
|
|
87
89
|
throw erro;
|
|
88
90
|
}
|
|
89
91
|
});
|
|
@@ -93,20 +95,22 @@ Hobots.register('processar-nfe', async (params, ctx) => {
|
|
|
93
95
|
|
|
94
96
|
### O que aceita
|
|
95
97
|
|
|
98
|
+
O `attachment` pode ser a imagem direto, ou um objeto com metadados:
|
|
99
|
+
|
|
96
100
|
| Entrada | Exemplo |
|
|
97
101
|
| --- | --- |
|
|
98
102
|
| bytes | `Uint8Array`, `ArrayBuffer` ou `Buffer` — `await page.screenshot()` |
|
|
99
103
|
| caminho de arquivo | `'C:\\prints\\tela.png'` (só em Node) |
|
|
104
|
+
| objeto | `{ image, caption?, contentType? }` |
|
|
100
105
|
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
| Opção | Tipo | Default | O que faz |
|
|
106
|
+
| Campo do objeto | Tipo | Default | O que faz |
|
|
104
107
|
| --- | --- | --- | --- |
|
|
108
|
+
| `image` | bytes ou caminho | — | a imagem em si |
|
|
105
109
|
| `caption` | `string` | — | legenda curta exibida sob a imagem ampliada (máx. 200 caracteres) |
|
|
106
|
-
| `level` | `RunLogLevel` | `'info'` | nível da linha de log que carrega o anexo |
|
|
107
|
-
| `message` | `string` | a legenda, ou `'captura de tela'` | texto da linha de log |
|
|
108
110
|
| `contentType` | `'image/png' \| 'image/jpeg' \| 'image/webp'` | detectado | só é usado quando os *magic bytes* não bastam |
|
|
109
111
|
|
|
112
|
+
O texto da linha de log é a própria mensagem capturada (`message` do `captureMessage`, ou `Nome: mensagem` do erro no `captureException`); o nível vem do `level` da captura (`'fatal'` vira `'error'` no log da run).
|
|
113
|
+
|
|
110
114
|
### Limites
|
|
111
115
|
|
|
112
116
|
| Limite | Valor |
|
|
@@ -121,9 +125,9 @@ Hobots.register('processar-nfe', async (params, ctx) => {
|
|
|
121
125
|
|
|
122
126
|
A linha de log é registrada **na hora**, com o id do anexo; o upload roda em segundo plano. O binário vai direto para o S3 por uma URL presignada — não passa pela API do Hobots. Enquanto o upload não termina, o app mostra a miniatura como "enviando imagem…".
|
|
123
127
|
|
|
124
|
-
|
|
128
|
+
O anexo **nunca faz a captura lançar**. Todo insucesso vira um aviso no log da run:
|
|
125
129
|
|
|
126
|
-
|
|
|
130
|
+
| Motivo | Quando |
|
|
127
131
|
| --- | --- |
|
|
128
132
|
| `too-large` | acima de 5 MB |
|
|
129
133
|
| `quota` | passou de 20 anexos na execução |
|
|
@@ -133,7 +137,9 @@ A linha de log é registrada **na hora**, com o id do anexo; o upload roda em se
|
|
|
133
137
|
| `upload-failed` | falha de rede depois dos retries |
|
|
134
138
|
| `canceled` | a run foi cancelada ou encerrada durante o upload |
|
|
135
139
|
|
|
136
|
-
|
|
140
|
+
O upload é sempre fire-and-forget — a captura retorna na hora. Antes de reportar o desfecho da run, o SDK aguarda os uploads pendentes por até 15 s, para a execução não terminar com miniaturas em "enviando…".
|
|
141
|
+
|
|
142
|
+
> **Fora de uma execução:** `attachment` só funciona dentro de um handler de task — fora dele não existe log de run para pendurar a imagem, e o SDK descarta o anexo com um aviso no console (o evento em si é capturado normalmente).
|
|
137
143
|
|
|
138
144
|
> **Dados sensíveis:** o print é enviado ao servidor **exatamente como está** — o SDK não borra nem recorta nada. Uma tela de portal costuma conter CPF, nome, saldo, número de documento. Capture apenas o necessário e evite prints de telas com dados de terceiros. Solicitantes (papel `requester`) só veem os anexos quando o projeto está com "mostrar logs para solicitantes" ligado, o mesmo gate dos logs.
|
|
139
145
|
|
|
@@ -178,6 +184,8 @@ Hobots.register('processar-nfe', async (params, ctx) => {
|
|
|
178
184
|
|
|
179
185
|
Quando o cancelamento veio do app, a run já está `cancelada` no servidor — o erro `RunCanceled` lançado pelo handler é suprimido, nada é reportado por cima. Para lógica de limpeza antes de parar (fechar navegador, desfazer estado), use `try/finally` ou escute `ctx.signal` diretamente.
|
|
180
186
|
|
|
187
|
+
Se o handler **nunca** checar `ctx.signal` (loop sem `throwIfCanceled()`, `sleep()` genérico em vez de `ctx.sleep()`), o SDK ainda assim não trava o agente: depois de `cancelGraceMs` (default `10_000`) a partir do disparo de `ctx.signal`, o agente desiste de esperar aquele handler e libera o slot de concorrência para novas runs — logando um aviso. Isso não mata o handler (ele pode continuar rodando em segundo plano, sem efeito no app já que a run está cancelada), só evita que uma run "zumbi" trave o agente inteiro num `concurrency` baixo.
|
|
188
|
+
|
|
181
189
|
## Encerramento inesperado
|
|
182
190
|
|
|
183
191
|
Se o processo do agente **morre no meio de uma run**, a solicitação vira **falha** no app com erro `AgentTerminated` ("execução encerrada inesperadamente") — sem re-execução automática. Dois caminhos garantem isso:
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hobots",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.2",
|
|
4
4
|
"description": "SDK JavaScript da Hobots — telemetria (erros, transactions e heartbeats) e execução remota de tarefas sob demanda (tasks) para RPAs e integrações. Um único import e um único init().",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"sideEffects": false,
|