hobots 3.4.0 → 4.0.0
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 +36 -27
- package/dist/index.cjs +96 -208
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +27 -25
- package/dist/index.d.ts +27 -25
- package/dist/index.js +96 -208
- package/dist/index.js.map +1 -1
- package/dist/protocol.cjs.map +1 -1
- package/dist/protocol.d.cts +21 -21
- package/dist/protocol.d.ts +21 -21
- package/docs/README.md +10 -8
- package/docs/api-reference.md +33 -20
- package/docs/concepts.md +19 -19
- package/docs/getting-started.md +14 -12
- package/docs/protocol.md +22 -23
- package/docs/{tasks.md → runs.md} +21 -21
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,9 +1,11 @@
|
|
|
1
1
|
# hobots
|
|
2
2
|
|
|
3
|
-
SDK JavaScript/TypeScript da **Hobots** para robôs (RPAs) e integrações. **
|
|
3
|
+
SDK JavaScript/TypeScript da **Hobots** para robôs (RPAs) e integrações. **O agente é a própria tarefa**: o seu programa é o agente, ele faz uma coisa, e a plataforma passa a receber logs, itens processados, progresso, prints, erros e o "estou vivo" do robô.
|
|
4
4
|
|
|
5
|
-
- **`hobots.register(
|
|
6
|
-
- **`hobots.start(
|
|
5
|
+
- **`hobots.register(handler)`** — **modo sob demanda**: o robô fica online aguardando **solicitações** criadas no app (formulário do agente e agendamentos) e executa o handler a cada uma. Módulo **Trabalhos**.
|
|
6
|
+
- **`hobots.start(handler)`** — **modo sempre ligado**: o robô abre a própria execução ao iniciar e roda o handler (o seu loop) dentro dela; a plataforma só recebe logs, itens e progresso. Sem formulário, sem solicitante.
|
|
7
|
+
|
|
8
|
+
Uma chamada por processo: `register` **ou** `start`. Não há slug nem nome de task — o que o robô faz é o próprio agente, identificado pelo Client Secret.
|
|
7
9
|
|
|
8
10
|
---
|
|
9
11
|
|
|
@@ -33,8 +35,8 @@ export HOBOTS_ENVIRONMENT=staging # opcional — default: production
|
|
|
33
35
|
```js
|
|
34
36
|
import hobots from 'hobots';
|
|
35
37
|
|
|
36
|
-
// sob demanda: uma execução por solicitação do app (
|
|
37
|
-
hobots.register(
|
|
38
|
+
// sob demanda: uma execução por solicitação do app (formulário do agente ou agendamento)
|
|
39
|
+
hobots.register(async params => {
|
|
38
40
|
hobots.log.info(`lote ${params.lote}`);
|
|
39
41
|
hobots.progress.total(params.notas.length);
|
|
40
42
|
for (const nota of params.notas) {
|
|
@@ -44,19 +46,22 @@ hobots.register('processar-nfe', async params => {
|
|
|
44
46
|
}
|
|
45
47
|
});
|
|
46
48
|
|
|
47
|
-
|
|
48
|
-
|
|
49
|
+
process.on('SIGINT', () => void hobots.close(15_000).then(() => process.exit(0)));
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
Um robô que vive rodando usa `start` no lugar de `register` — o handler é o loop:
|
|
53
|
+
|
|
54
|
+
```js
|
|
55
|
+
hobots.start(async () => {
|
|
49
56
|
while (true) {
|
|
50
57
|
await hobots.sleep(60_000); // cancelável
|
|
51
58
|
for (const arquivo of await novosArquivos()) hobots.items.succeeded({ arquivo });
|
|
52
59
|
hobots.log.info('ciclo ok');
|
|
53
60
|
}
|
|
54
61
|
});
|
|
55
|
-
|
|
56
|
-
process.on('SIGINT', () => void hobots.close(15_000).then(() => process.exit(0)));
|
|
57
62
|
```
|
|
58
63
|
|
|
59
|
-
O objeto **`hobots`** é global: `hobots.log`, `hobots.items`, `hobots.progress`, `hobots.transaction`… resolvem a execução **atual** de qualquer módulo do programa — sem passar contexto de mão em mão, mesmo com várias execuções em paralelo. Depois
|
|
64
|
+
O objeto **`hobots`** é global: `hobots.log`, `hobots.items`, `hobots.progress`, `hobots.transaction`… resolvem a execução **atual** de qualquer módulo do programa — sem passar contexto de mão em mão, mesmo com várias execuções em paralelo. Depois do `register()`/`start()` ele também existe como `globalThis.hobots`.
|
|
60
65
|
|
|
61
66
|
---
|
|
62
67
|
|
|
@@ -65,7 +70,7 @@ O objeto **`hobots`** é global: `hobots.log`, `hobots.items`, `hobots.progress`
|
|
|
65
70
|
| Env | Opção | O que é |
|
|
66
71
|
| --- | --- | --- |
|
|
67
72
|
| `HOBOTS_CLIENT_SECRET` | `clientSecret` | O **Client Secret do agente** (`hb_<64 hex>`), copiado em **Configurações → Agentes**. Viaja só no header `Authorization: Bearer`, nunca na URL. Ausente ou inválido → `register()`/`start()` lança na hora, citando a env (sem ecoar o valor). |
|
|
68
|
-
| `HOBOTS_INSTANCE_ID` | `instanceId` | Identidade **estável** desta instância do robô (`vm-cliente-01`). Sem ela, o hostname. Heartbeat e
|
|
73
|
+
| `HOBOTS_INSTANCE_ID` | `instanceId` | Identidade **estável** desta instância do robô (`vm-cliente-01`). Sem ela, o hostname. Heartbeat e execuções convergem nela: **um agente só** no painel. |
|
|
69
74
|
| `HOBOTS_ENVIRONMENT` | `environment` | Ambiente lógico do robô (`development` \| `testing` \| `staging` \| `production`). Sem ela, `production`. |
|
|
70
75
|
| `HOBOTS_API_URL` | — | Só em desenvolvimento: aponta o SDK para outro host (`http://localhost:3001`). Em produção é sempre `https://api2.hobots.app`. |
|
|
71
76
|
|
|
@@ -75,15 +80,16 @@ A opção passada em `register()`/`start()` tem precedência sobre a env — út
|
|
|
75
80
|
|
|
76
81
|
## Os dois modos
|
|
77
82
|
|
|
78
|
-
| | `register(
|
|
83
|
+
| | `register(handler, options?)` | `start(handler, options?)` |
|
|
79
84
|
| --- | --- | --- |
|
|
80
|
-
| Quem dispara | Uma **solicitação** no app (formulário
|
|
85
|
+
| Quem dispara | Uma **solicitação** no app (formulário do agente, ou agendamento) | O próprio robô, ao iniciar |
|
|
81
86
|
| `params` do handler | O JSON validado do formulário | `{}` |
|
|
82
87
|
| Quantas execuções | Uma por solicitação; `concurrency` em paralelo (1..5) | **Uma só** — o handler é o seu loop; quando ele retorna, a execução fecha |
|
|
83
88
|
| O processo | Fica vivo fazendo polling | Fica vivo pelo heartbeat, mesmo depois do handler retornar |
|
|
84
89
|
| Reexecutar pelo app | Sim | Não — só reiniciando o robô |
|
|
90
|
+
| No painel | Instância "sob demanda" | Instância "sempre ligado" |
|
|
85
91
|
|
|
86
|
-
|
|
92
|
+
**Um processo = um agente = uma chamada.** A segunda chamada a `register()`/`start()` lança (`o agente já foi iniciado`). Um robô que precisa monitorar uma pasta *e* atender solicitações são dois agentes — dois processos, cada um com o seu Client Secret.
|
|
87
93
|
|
|
88
94
|
> **Modo start e o limite de logs:** o servidor guarda no máximo **1000 linhas de log por execução**. Num loop que roda por dias, logue o que importa (ciclos com novidade, avisos, erros) e registre o trabalho em `hobots.items` — itens não têm esse teto tão baixo (10.000 por execução).
|
|
89
95
|
|
|
@@ -93,17 +99,17 @@ Os dois podem coexistir no mesmo processo: um monitor sempre ligado + tasks sob
|
|
|
93
99
|
|
|
94
100
|
| Membro | O que faz |
|
|
95
101
|
| --- | --- |
|
|
96
|
-
| `hobots.log.debug/info/warn/error/success(msg, ...rest)` | Log da execução, enviado incrementalmente ao app (e ecoado no terminal). Aceita vários argumentos como `console.log` — `hobots.log.info('nota', numero, 'ok')` — cada um vira texto, unidos por espaço. Um `hobots.image(...)` como **último** argumento pendura um print na linha. **Nunca lança** — pode ir em `finally`. |
|
|
102
|
+
| `hobots.log.debug/info/warn/error/success(msg, ...rest)` | Log da execução, enviado incrementalmente ao app (e ecoado no terminal como `[hobots] INFO …`). Aceita vários argumentos como `console.log` — `hobots.log.info('nota', numero, 'ok')` — cada um vira texto, unidos por espaço. Um `hobots.image(...)` como **último** argumento pendura um print na linha. **Nunca lança** — pode ir em `finally`. |
|
|
97
103
|
| `hobots.items.succeeded(payload?, { id, image }?)` · `.failed(msg, payload?, …)` · `.occurrence(msg, payload?, …)` · `.add({...})` | **A entrega do robô**: cada item processado, com status e atributos (viram colunas no app — declare-as com a opção `items: { columns: [...] }` do `register`/`start`). `image` pendura um print no item. Bufferizado, em lotes. |
|
|
98
104
|
| `hobots.items.each(lista, async (el, item) => …, { id, payload }?)` | **Loop com o contrato garantido**: cada elemento vira step + item; exceção no handler = item `failed` com a mensagem e o loop **segue** até o fim; progresso automático. Só cancelamento/timeout interrompem. |
|
|
99
|
-
| `hobots.progress.total(n)` · `.advance(k = 1)` · `.set(atual, total?)` · `.current` · `.snapshot` | Barra, percentual e tempo restante na
|
|
100
|
-
| `hobots.transaction.startChild(op, descrição)` | Uma **step** no waterfall de performance da execução. A transaction da execução já existe e é finalizada pelo SDK. `step.setStatus(status, msg?, { image })` / `setError(err, msg?, { image })` penduram um print na step. |
|
|
105
|
+
| `hobots.progress.total(n)` · `.advance(k = 1)` · `.set(atual, total?)` · `.current` · `.snapshot` | Barra, percentual e tempo restante na execução. Sem `total()` nada é enviado. |
|
|
106
|
+
| `hobots.transaction.startChild(op, descrição)` | Uma **step** no waterfall de performance da execução. A transaction da execução (`run`) já existe e é finalizada pelo SDK. `step.setStatus(status, msg?, { image })` / `setError(err, msg?, { image })` penduram um print na step. |
|
|
101
107
|
| `hobots.image(bytes \| caminho, { caption?, contentType? })` | Embrulha um **print** (PNG/JPEG/WEBP, até 5 MB, 20 por execução) para ir junto de um log, item ou step. Puro: o upload roda em segundo plano quando o evento é registrado; nunca lança nem bloqueia. |
|
|
102
108
|
| `hobots.captureException(erro, hint?)` | Abre uma **issue** (módulo Issues). `hint.attachment` anexa um print à linha de log correspondente. |
|
|
103
109
|
| `hobots.retry(fn, { retries = 3, delayMs = 1_000, shouldRetry? })` | async-retry ciente do cancelamento da execução. `delayMs` aceita função `(tentativa) => ms`. |
|
|
104
110
|
| `hobots.sleep(ms)` | Espera **cancelável**: rejeita com `RunCanceled` se a execução for cancelada. |
|
|
105
111
|
| `hobots.signal` · `hobots.throwIfCanceled()` | Cancelamento cooperativo manual, para controle fino. |
|
|
106
|
-
| `hobots.runId` · `hobots.
|
|
112
|
+
| `hobots.runId` · `hobots.params` | Identidade da execução atual. |
|
|
107
113
|
| `hobots.register(...)` · `hobots.start(...)` · `hobots.close(timeoutMs?)` | Ciclo de vida do processo. |
|
|
108
114
|
|
|
109
115
|
O handler também recebe o mesmo contexto como 2º argumento (`(params, ctx) => …`), para quem prefere explícito. Fora de qualquer execução (ex.: antes do boot), os membros de contexto caem em fallbacks seguros e avisam uma vez — `hobots.log` continua imprimindo no terminal. Evite `const { log } = hobots` no topo de um módulo: o valor capturado é o de fora de execução; chame `hobots.log.info(...)`.
|
|
@@ -125,10 +131,10 @@ Num loop de itens, isso costuma bastar: registrar o item processado já é o pon
|
|
|
125
131
|
|
|
126
132
|
## Retry
|
|
127
133
|
|
|
128
|
-
Quando o handler lança, o SDK **tenta de novo na mesma execução**: aviso no log (`tentativa 1/2 falhou: … — nova tentativa em 5000ms`), espera cancelável, re-invocação com os mesmos `params`. Default: **1 tentativa extra** com 5 s. Itens e progresso já enviados permanecem — escreva handlers **idempotentes** (use o `id` de negócio nos itens: repetido, o servidor
|
|
134
|
+
Quando o handler lança, o SDK **tenta de novo na mesma execução**: aviso no log (`tentativa 1/2 falhou: … — nova tentativa em 5000ms`), espera cancelável, re-invocação com os mesmos `params`. Default: **1 tentativa extra** com 5 s. Itens e progresso já enviados permanecem — escreva handlers **idempotentes** (use o `id` de negócio nos itens: repetido, o servidor atualiza em vez de duplicar).
|
|
129
135
|
|
|
130
136
|
```js
|
|
131
|
-
hobots.register(
|
|
137
|
+
hobots.register(handler, { retries: 3, retryDelayMs: attempt => attempt * 10_000 });
|
|
132
138
|
```
|
|
133
139
|
|
|
134
140
|
Nunca há nova tentativa em **cancelamento**, **timeout** (`TaskTimeout` é terminal) ou execução já cancelada no app. Para uma chamada instável dentro do handler, use `hobots.retry()`.
|
|
@@ -138,8 +144,8 @@ Nunca há nova tentativa em **cancelamento**, **timeout** (`TaskTimeout` é term
|
|
|
138
144
|
## Opções
|
|
139
145
|
|
|
140
146
|
```ts
|
|
141
|
-
hobots.register(
|
|
142
|
-
hobots.start(
|
|
147
|
+
hobots.register(handler, options?: RegisterOptions);
|
|
148
|
+
hobots.start(handler, options?: StartOptions);
|
|
143
149
|
```
|
|
144
150
|
|
|
145
151
|
| Opção | Default | Descrição |
|
|
@@ -152,14 +158,15 @@ hobots.start(task, handler, options?: StartOptions);
|
|
|
152
158
|
| `debug` | `false` | Loga a atividade do SDK |
|
|
153
159
|
| `machineMetrics` | `true` | CPU/memória/disco no heartbeat e em cada evento |
|
|
154
160
|
| `captureUnhandled` | `true` | `uncaughtException`/`unhandledRejection` viram issues |
|
|
161
|
+
| `items` | — | `{ columns: [...] }` — colunas da aba de itens no app (uma declaração, do agente) |
|
|
155
162
|
| `retries` | `1` | Tentativas extras do handler (0 desliga) |
|
|
156
163
|
| `retryDelayMs` | `5_000` | ms fixo ou `(tentativa) => ms` |
|
|
157
164
|
| `timeoutMs` | — (infinito) | Timeout por tentativa; terminal (`TaskTimeout`). O handler não é morto: o signal dispara e o slot é liberado |
|
|
158
|
-
| `concurrency` (register) | `1` | Execuções simultâneas
|
|
165
|
+
| `concurrency` (register) | `1` | Execuções simultâneas do agente (1..5) |
|
|
159
166
|
| `pollIntervalMs` (register) | `2_000` | Intervalo entre polls sem trabalho (mín. 1_000) |
|
|
160
167
|
| avançadas: `installExitHandlers`, `logFlushIntervalMs`, `cancelCheckIntervalMs`, `cancelGraceMs` | `true`, `2_000`, `5_000`, `10_000` | Ver [Referência de API](./docs/api-reference.md) |
|
|
161
168
|
|
|
162
|
-
|
|
169
|
+
Como só há uma chamada por processo, todas as opções são as **do agente** — não existe "opção de processo" separada da "opção da task".
|
|
163
170
|
|
|
164
171
|
---
|
|
165
172
|
|
|
@@ -181,13 +188,15 @@ Sem handler próprio de sinal, um `SIGINT`/`SIGTERM` (ou erro fatal) com execuç
|
|
|
181
188
|
|
|
182
189
|
## Changelog resumido
|
|
183
190
|
|
|
191
|
+
- **4.0.0** — **o agente é a própria tarefa** (breaking): `register(handler, options?)`/`start(handler, options?)` **sem slug**; **uma chamada por processo** (a segunda lança); `hobots.task`/`ctx.task` removidos; tipos `TaskHandler`→`RunHandler`, `TaskOptions`→`RunOptions`, `TaskItemsOptions`→`ItemsOptions`; wire: `InstanceInfo.mode` (`on_demand` \| `always_on`) e `InstanceInfo.items` no lugar de `tasks`/`task_items`, endpoints em `/v1/runs/*`; eco no terminal `[hobots] INFO …`. Guia de migração no [CHANGELOG](./CHANGELOG.md).
|
|
192
|
+
- **3.4.0** — `hobots.attach()` removido; o print vai junto do evento: `hobots.image(...)` no último argumento de `log.*`, `{ image }` em itens e steps.
|
|
184
193
|
- **3.1.0** — `hobots.log.*` aceita vários argumentos (como `console.log`); `retries` inválido (`NaN`) cai no default em vez de tentar para sempre; 429 de itens e 429/501/503 de anexo são definitivos (sem esperar a ladder — `quota`/`unsupported` passam a funcionar de fato); timeout **por requisição** nos anexos; truncamento nos limites do servidor (tag 512, fingerprint 10×255, nome de transaction 500, 200 steps, `exception.value` 8192, `filename` 1024); PNG acima de 20 000 px não declara dimensões; PATCH terminal nunca passa de 100 logs.
|
|
185
194
|
|
|
186
195
|
## Documentação
|
|
187
196
|
|
|
188
|
-
- [Getting started](./docs/getting-started.md) — instalação, envs,
|
|
189
|
-
- [
|
|
190
|
-
- [Conceitos](./docs/concepts.md) — o vocabulário:
|
|
197
|
+
- [Getting started](./docs/getting-started.md) — instalação, envs, o primeiro agente nos dois modos.
|
|
198
|
+
- [Execuções](./docs/runs.md) — handler, `hobots.*`, itens, progresso, anexos, cancelamento, retry, concorrência, idempotência.
|
|
199
|
+
- [Conceitos](./docs/concepts.md) — o vocabulário: agente, execução, evento, transaction, step, heartbeat, instância, claim…
|
|
191
200
|
- [Referência de API](./docs/api-reference.md) — assinaturas, tabelas de opções e tempos.
|
|
192
201
|
- [Protocolo & transporte](./docs/protocol.md) — endpoints, envelope, retries, claim.
|
|
193
202
|
- Exemplos runnable em [`packages/hobots-sdk-demos`](../hobots-sdk-demos).
|