hobots 1.5.1 → 1.7.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 +46 -74
- package/dist/index.cjs +267 -144
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +31 -123
- package/dist/index.d.ts +31 -123
- package/dist/index.js +267 -144
- package/dist/index.js.map +1 -1
- package/dist/protocol.cjs.map +1 -1
- package/dist/protocol.d.cts +73 -4
- package/dist/protocol.d.ts +73 -4
- package/docs/README.md +8 -8
- package/docs/api-reference.md +40 -44
- package/docs/concepts.md +67 -52
- package/docs/getting-started.md +17 -17
- package/docs/monitor.md +8 -8
- package/docs/protocol.md +21 -25
- package/docs/{manager.md → tasks.md} +18 -18
- package/package.json +3 -7
- package/dist/manager/protocol.cjs +0 -19
- package/dist/manager/protocol.cjs.map +0 -1
- package/dist/manager/protocol.d.cts +0 -72
- package/dist/manager/protocol.d.ts +0 -72
- package/dist/manager/protocol.js +0 -1
- package/dist/manager/protocol.js.map +0 -1
package/dist/protocol.d.cts
CHANGED
|
@@ -1,7 +1,76 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Tipos do protocolo de tasks do Hobots (agente SDK ↔ servidor).
|
|
3
|
+
*
|
|
4
|
+
* Este arquivo é a fonte de verdade do wire format e não pode importar nada:
|
|
5
|
+
* o app valida os payloads com zod e trava o drift via `satisfies z.ZodType<...>`
|
|
6
|
+
* contra estes tipos (reexportados por `hobots/protocol`).
|
|
7
|
+
*/
|
|
8
|
+
/** Ciclo de vida completo de uma run no servidor. */
|
|
9
|
+
type RunStatus = 'pending' | 'claimed' | 'running' | 'succeeded' | 'failed' | 'canceled';
|
|
10
|
+
/** Subconjunto que o agente pode enviar no PATCH. */
|
|
11
|
+
type RunUpdateStatus = 'running' | 'succeeded' | 'failed';
|
|
12
|
+
type RunLogLevel = 'debug' | 'info' | 'warning' | 'error' | 'success';
|
|
13
|
+
interface RunLogEntry {
|
|
14
|
+
/** ISO 8601 — relógio do agente, apenas para exibição */
|
|
15
|
+
ts: string;
|
|
16
|
+
level: RunLogLevel;
|
|
17
|
+
message: string;
|
|
18
|
+
}
|
|
19
|
+
interface AgentInfo {
|
|
20
|
+
/** Identidade canônica do agente — correlaciona com o heartbeat de telemetria */
|
|
21
|
+
instance_id: string;
|
|
22
|
+
name?: string;
|
|
23
|
+
/** Versão do SDK */
|
|
24
|
+
version?: string;
|
|
25
|
+
/** Hostname da máquina */
|
|
26
|
+
host?: string;
|
|
27
|
+
/** Tasks registradas no agente */
|
|
28
|
+
tasks?: string[];
|
|
29
|
+
}
|
|
30
|
+
/** POST /v1/tasks/poll */
|
|
31
|
+
interface PollRequest {
|
|
32
|
+
agent?: AgentInfo;
|
|
33
|
+
/** Quantas runs reivindicar de uma vez (1..5). Default: 1 */
|
|
34
|
+
max?: number;
|
|
35
|
+
/** Só entrega runs destas tasks (nomes registrados no agente) */
|
|
36
|
+
tasks?: string[];
|
|
37
|
+
}
|
|
38
|
+
interface RunDescriptor {
|
|
39
|
+
id: string;
|
|
40
|
+
task: string;
|
|
41
|
+
params: Record<string, unknown>;
|
|
42
|
+
form: {
|
|
43
|
+
id: string;
|
|
44
|
+
name: string;
|
|
45
|
+
} | null;
|
|
46
|
+
/** Origem da run: 'hobots' | 'link' | 'schedule' (informativo) */
|
|
47
|
+
source: string;
|
|
48
|
+
/** ISO 8601 (relógio do servidor) */
|
|
49
|
+
created_at: string;
|
|
50
|
+
}
|
|
51
|
+
interface PollResponse {
|
|
52
|
+
runs: RunDescriptor[];
|
|
53
|
+
}
|
|
54
|
+
interface RunError {
|
|
55
|
+
/** ex.: nome da classe do erro */
|
|
56
|
+
type?: string;
|
|
57
|
+
message: string;
|
|
58
|
+
stack?: string;
|
|
59
|
+
}
|
|
60
|
+
/** PATCH /v1/tasks/runs/{id} — 'running' pode repetir com logs incrementais */
|
|
61
|
+
interface RunUpdateRequest {
|
|
62
|
+
status: RunUpdateStatus;
|
|
63
|
+
/** Apenas com status 'failed' */
|
|
64
|
+
error?: RunError;
|
|
65
|
+
/** Delta desde o último envio — o servidor concatena */
|
|
66
|
+
logs?: RunLogEntry[];
|
|
67
|
+
}
|
|
68
|
+
interface RunUpdateResponse {
|
|
69
|
+
ok: true;
|
|
70
|
+
}
|
|
2
71
|
|
|
3
72
|
/**
|
|
4
|
-
* Tipos do protocolo
|
|
73
|
+
* Tipos do protocolo do Hobots (SDK → servidor).
|
|
5
74
|
*
|
|
6
75
|
* Este arquivo é a fonte de verdade do wire format e só pode reexportar tipos:
|
|
7
76
|
* o app valida os payloads com zod e trava o drift via `satisfies z.ZodType<...>`
|
|
@@ -82,7 +151,7 @@ interface TransactionPayload {
|
|
|
82
151
|
tags?: Record<string, string>;
|
|
83
152
|
release?: string;
|
|
84
153
|
environment?: string;
|
|
85
|
-
/** Correlaciona esta transaction a uma execução
|
|
154
|
+
/** Correlaciona esta transaction a uma execução de task (ctx.tx dentro de um task handler) */
|
|
86
155
|
run_id?: string;
|
|
87
156
|
}
|
|
88
157
|
type CheckInStatus = 'in_progress' | 'ok' | 'error';
|
|
@@ -130,4 +199,4 @@ interface Envelope {
|
|
|
130
199
|
items: EnvelopeItem[];
|
|
131
200
|
}
|
|
132
201
|
|
|
133
|
-
export type { Breadcrumb, CheckInPayload, CheckInStatus, Envelope, EnvelopeItem, EventPayload, EventUser, ExceptionData, HeartbeatPayload, Severity, SpanData, SpanStatus, StackFrame, TransactionPayload };
|
|
202
|
+
export type { AgentInfo, Breadcrumb, CheckInPayload, CheckInStatus, Envelope, EnvelopeItem, EventPayload, EventUser, ExceptionData, HeartbeatPayload, PollRequest, PollResponse, RunDescriptor, RunError, RunLogEntry, RunLogLevel, RunStatus, RunUpdateRequest, RunUpdateResponse, RunUpdateStatus, Severity, SpanData, SpanStatus, StackFrame, TransactionPayload };
|
package/dist/protocol.d.ts
CHANGED
|
@@ -1,7 +1,76 @@
|
|
|
1
|
-
|
|
1
|
+
/**
|
|
2
|
+
* Tipos do protocolo de tasks do Hobots (agente SDK ↔ servidor).
|
|
3
|
+
*
|
|
4
|
+
* Este arquivo é a fonte de verdade do wire format e não pode importar nada:
|
|
5
|
+
* o app valida os payloads com zod e trava o drift via `satisfies z.ZodType<...>`
|
|
6
|
+
* contra estes tipos (reexportados por `hobots/protocol`).
|
|
7
|
+
*/
|
|
8
|
+
/** Ciclo de vida completo de uma run no servidor. */
|
|
9
|
+
type RunStatus = 'pending' | 'claimed' | 'running' | 'succeeded' | 'failed' | 'canceled';
|
|
10
|
+
/** Subconjunto que o agente pode enviar no PATCH. */
|
|
11
|
+
type RunUpdateStatus = 'running' | 'succeeded' | 'failed';
|
|
12
|
+
type RunLogLevel = 'debug' | 'info' | 'warning' | 'error' | 'success';
|
|
13
|
+
interface RunLogEntry {
|
|
14
|
+
/** ISO 8601 — relógio do agente, apenas para exibição */
|
|
15
|
+
ts: string;
|
|
16
|
+
level: RunLogLevel;
|
|
17
|
+
message: string;
|
|
18
|
+
}
|
|
19
|
+
interface AgentInfo {
|
|
20
|
+
/** Identidade canônica do agente — correlaciona com o heartbeat de telemetria */
|
|
21
|
+
instance_id: string;
|
|
22
|
+
name?: string;
|
|
23
|
+
/** Versão do SDK */
|
|
24
|
+
version?: string;
|
|
25
|
+
/** Hostname da máquina */
|
|
26
|
+
host?: string;
|
|
27
|
+
/** Tasks registradas no agente */
|
|
28
|
+
tasks?: string[];
|
|
29
|
+
}
|
|
30
|
+
/** POST /v1/tasks/poll */
|
|
31
|
+
interface PollRequest {
|
|
32
|
+
agent?: AgentInfo;
|
|
33
|
+
/** Quantas runs reivindicar de uma vez (1..5). Default: 1 */
|
|
34
|
+
max?: number;
|
|
35
|
+
/** Só entrega runs destas tasks (nomes registrados no agente) */
|
|
36
|
+
tasks?: string[];
|
|
37
|
+
}
|
|
38
|
+
interface RunDescriptor {
|
|
39
|
+
id: string;
|
|
40
|
+
task: string;
|
|
41
|
+
params: Record<string, unknown>;
|
|
42
|
+
form: {
|
|
43
|
+
id: string;
|
|
44
|
+
name: string;
|
|
45
|
+
} | null;
|
|
46
|
+
/** Origem da run: 'hobots' | 'link' | 'schedule' (informativo) */
|
|
47
|
+
source: string;
|
|
48
|
+
/** ISO 8601 (relógio do servidor) */
|
|
49
|
+
created_at: string;
|
|
50
|
+
}
|
|
51
|
+
interface PollResponse {
|
|
52
|
+
runs: RunDescriptor[];
|
|
53
|
+
}
|
|
54
|
+
interface RunError {
|
|
55
|
+
/** ex.: nome da classe do erro */
|
|
56
|
+
type?: string;
|
|
57
|
+
message: string;
|
|
58
|
+
stack?: string;
|
|
59
|
+
}
|
|
60
|
+
/** PATCH /v1/tasks/runs/{id} — 'running' pode repetir com logs incrementais */
|
|
61
|
+
interface RunUpdateRequest {
|
|
62
|
+
status: RunUpdateStatus;
|
|
63
|
+
/** Apenas com status 'failed' */
|
|
64
|
+
error?: RunError;
|
|
65
|
+
/** Delta desde o último envio — o servidor concatena */
|
|
66
|
+
logs?: RunLogEntry[];
|
|
67
|
+
}
|
|
68
|
+
interface RunUpdateResponse {
|
|
69
|
+
ok: true;
|
|
70
|
+
}
|
|
2
71
|
|
|
3
72
|
/**
|
|
4
|
-
* Tipos do protocolo
|
|
73
|
+
* Tipos do protocolo do Hobots (SDK → servidor).
|
|
5
74
|
*
|
|
6
75
|
* Este arquivo é a fonte de verdade do wire format e só pode reexportar tipos:
|
|
7
76
|
* o app valida os payloads com zod e trava o drift via `satisfies z.ZodType<...>`
|
|
@@ -82,7 +151,7 @@ interface TransactionPayload {
|
|
|
82
151
|
tags?: Record<string, string>;
|
|
83
152
|
release?: string;
|
|
84
153
|
environment?: string;
|
|
85
|
-
/** Correlaciona esta transaction a uma execução
|
|
154
|
+
/** Correlaciona esta transaction a uma execução de task (ctx.tx dentro de um task handler) */
|
|
86
155
|
run_id?: string;
|
|
87
156
|
}
|
|
88
157
|
type CheckInStatus = 'in_progress' | 'ok' | 'error';
|
|
@@ -130,4 +199,4 @@ interface Envelope {
|
|
|
130
199
|
items: EnvelopeItem[];
|
|
131
200
|
}
|
|
132
201
|
|
|
133
|
-
export type { Breadcrumb, CheckInPayload, CheckInStatus, Envelope, EnvelopeItem, EventPayload, EventUser, ExceptionData, HeartbeatPayload, Severity, SpanData, SpanStatus, StackFrame, TransactionPayload };
|
|
202
|
+
export type { AgentInfo, Breadcrumb, CheckInPayload, CheckInStatus, Envelope, EnvelopeItem, EventPayload, EventUser, ExceptionData, HeartbeatPayload, PollRequest, PollResponse, RunDescriptor, RunError, RunLogEntry, RunLogLevel, RunStatus, RunUpdateRequest, RunUpdateResponse, RunUpdateStatus, Severity, SpanData, SpanStatus, StackFrame, TransactionPayload };
|
package/docs/README.md
CHANGED
|
@@ -1,22 +1,22 @@
|
|
|
1
1
|
# Documentação — hobots
|
|
2
2
|
|
|
3
|
-
SDK JavaScript da **Hobots** para instrumentar funcionários digitais (RPAs) e integrações. Cliente HTTP puro, sem dependências de runtime, para Node 18+ (
|
|
3
|
+
SDK JavaScript da **Hobots** para instrumentar funcionários digitais (RPAs) e integrações. Cliente HTTP puro, sem dependências de runtime, para Node 18+ (a telemetria também roda no browser para captura de erros).
|
|
4
4
|
|
|
5
5
|
O SDK expõe **duas capabilities** autenticadas pelo **mesmo Client Secret do projeto**, configuradas em **um único `init()`** com **um único import** (`import * as Hobots from 'hobots'`):
|
|
6
6
|
|
|
7
7
|
| Capability | Como habilita | Para quê |
|
|
8
8
|
| --- | --- | --- |
|
|
9
|
-
| **
|
|
10
|
-
| **
|
|
9
|
+
| **Telemetria** | sempre ativa no `init()` | O que o programa **emite** sozinho: erros com stack trace (módulo **Issues**), performance (transactions/spans) e heartbeats de uptime (módulo **Agentes**), check-ins de cron (módulo **Monitores**). Instala handlers globais de erro; os timers são `unref`'d, então nunca seguram o processo vivo. |
|
|
10
|
+
| **Tasks** | `tasks: true` (ou opções) no `init()` | Execução **sob demanda**: o agente faz polling no app, executa handlers registrados e reporta status/logs — o módulo **Solicitações**. `start()` **mantém o processo vivo** até `stop()`/`close()`. |
|
|
11
11
|
|
|
12
12
|
## Páginas
|
|
13
13
|
|
|
14
14
|
Se termos como transaction, span, breadcrumb, tag, context, extra, flush e close ainda não são familiares, comece por **Conceitos** — as outras páginas assumem esse vocabulário.
|
|
15
15
|
|
|
16
16
|
- [Conceitos](./concepts.md) — o vocabulário: o que cada coisa é, por que existe e quando escolher uma em vez da outra.
|
|
17
|
-
- [Getting started](./getting-started.md) — instalação, Client Secret, o `init` único,
|
|
18
|
-
- [
|
|
19
|
-
- [
|
|
17
|
+
- [Getting started](./getting-started.md) — instalação, Client Secret, o `init` único, telemetria e tasks.
|
|
18
|
+
- [Telemetria](./monitor.md) — erros, breadcrumbs, escopo, transactions/spans, crons e heartbeat.
|
|
19
|
+
- [Tasks](./tasks.md) — registro de handlers, `RunContext`, cancelamento, concorrência, idempotência.
|
|
20
20
|
- [Referência de API](./api-reference.md) — todas as funções e tabelas de opções com defaults.
|
|
21
21
|
- [Protocolo & transporte](./protocol.md) — o Client Secret, endpoints, envelope, retries e onde vive o claim atômico.
|
|
22
22
|
|
|
@@ -28,13 +28,13 @@ import * as Hobots from 'hobots';
|
|
|
28
28
|
// O Client Secret do projeto — copie em Configurações → Projetos no app
|
|
29
29
|
const clientSecret = 'hb_<64 hex>';
|
|
30
30
|
|
|
31
|
-
// Um init só: telemetria sempre ativa;
|
|
31
|
+
// Um init só: telemetria sempre ativa; tasks habilita a execução sob demanda.
|
|
32
32
|
// O instanceId é a identidade única — o robô aparece como um agente só no painel.
|
|
33
33
|
Hobots.init({
|
|
34
34
|
clientSecret,
|
|
35
35
|
instanceId: 'vm-cliente-01',
|
|
36
36
|
heartbeat: true,
|
|
37
|
-
|
|
37
|
+
tasks: true,
|
|
38
38
|
});
|
|
39
39
|
|
|
40
40
|
Hobots.register('processar-nfe', async (params, ctx) => {
|
package/docs/api-reference.md
CHANGED
|
@@ -4,14 +4,12 @@
|
|
|
4
4
|
|
|
5
5
|
| Import | Conteúdo |
|
|
6
6
|
| --- | --- |
|
|
7
|
-
| `hobots` | Tudo: `init` único, funções
|
|
8
|
-
| `hobots/protocol` | Tipos do wire format (
|
|
9
|
-
|
|
10
|
-
`hobots/manager/protocol` segue existindo como alias transitório dos tipos do wire format do Manager.
|
|
7
|
+
| `hobots` | Tudo: `init` único, funções de telemetria, `register`/`start`/`stop` de tasks, `close`, classes (`Client`, `Scope`, `Transaction`, `Span`), `DEFAULT_BASE_URL`, `scrubSecrets` e tipos. |
|
|
8
|
+
| `hobots/protocol` | Tipos do wire format (telemetria e tasks). |
|
|
11
9
|
|
|
12
10
|
---
|
|
13
11
|
|
|
14
|
-
##
|
|
12
|
+
## Telemetria — funções
|
|
15
13
|
|
|
16
14
|
| Função | Assinatura | Retorno |
|
|
17
15
|
| --- | --- | --- |
|
|
@@ -25,18 +23,18 @@
|
|
|
25
23
|
| `setContext` | `setContext(name: string, ctx: Record<string,unknown> \| null): void` | — |
|
|
26
24
|
| `setExtra` | `setExtra(key: string, value: unknown): void` | — |
|
|
27
25
|
| `withScope` | `withScope<T>(cb: (scope: Scope) => T): T` | retorno do callback |
|
|
28
|
-
| `startTransaction` | `startTransaction(name: string, op?: string): Transaction` | transaction |
|
|
26
|
+
| `startTransaction` | `startTransaction(name: string, op?: string): Transaction` | transaction (dentro de um handler de task, a própria `ctx.tx`) |
|
|
29
27
|
| `checkIn` | `checkIn(options: CheckInOptions): string \| undefined` | check_in_id |
|
|
30
28
|
| `withMonitor` | `withMonitor<T>(slug: string, fn: () => T \| Promise<T>, options?: WithMonitorOptions): Promise<T>` | retorno de `fn` |
|
|
31
29
|
| `flush` | `flush(timeoutMs = 5_000): Promise<boolean>` | enviou tudo dentro do prazo? |
|
|
32
|
-
| `close` | `close(timeoutMs = 5_000): Promise<boolean>` | para o
|
|
30
|
+
| `close` | `close(timeoutMs = 5_000): Promise<boolean>` | para o polling de tasks (aguarda runs) + heartbeat + flush final do transport |
|
|
33
31
|
|
|
34
32
|
### O que cada função faz
|
|
35
33
|
|
|
36
34
|
Os conceitos por trás dessas chamadas estão em [Conceitos](./concepts.md); aqui está o que cada uma **faz** e o que **devolve**.
|
|
37
35
|
|
|
38
|
-
- **`init(options)`** — cria o cliente, instala os handlers globais de erro (a menos que `captureUnhandled: false`), inicia o heartbeat se configurado e cria o agente
|
|
39
|
-
- **`getClient()`** — devolve o cliente atual ou `undefined` se o `init()` nunca rodou. Útil para checar se o SDK está ativo.
|
|
36
|
+
- **`init(options)`** — cria o cliente, instala os handlers globais de erro (a menos que `captureUnhandled: false`), inicia o heartbeat se configurado e cria o agente de tasks se `tasks` foi passado. Chamar de novo **substitui** o cliente e o agente (os handlers registrados com `register` são preservados; o [scope](./concepts.md#scope) **não** é limpo). Chame uma vez, o mais cedo possível.
|
|
37
|
+
- **`getClient()`** — devolve o cliente atual ou `undefined` se o `init()` nunca rodou. Útil para checar se o SDK está ativo. A config resolvida (URL base e endpoints) é acessível via `getClient()?.config` (veja abaixo).
|
|
40
38
|
- **`captureException(error, hint?)`** — monta um [evento](./concepts.md#evento) a partir da exceção (tipo, mensagem, stack trace), mescla o scope e enfileira. O `level` é `error` a menos que você passe outro no `hint`.
|
|
41
39
|
- **`captureMessage(message, level = 'info', hint?)`** — mesma coisa, sem exceção: um evento só com texto. Bom para marcos (`'success'`) e avisos que não são erro.
|
|
42
40
|
> **Atenção:** as duas devolvem um `event_id` **mesmo quando o evento foi descartado** por [amostragem](./concepts.md#amostragem-samplerate-e-tracessamplerate) ou por [`beforeSend`](./concepts.md#beforesend). O retorno não prova que algo foi enviado — só é `undefined` quando o `init()` não foi chamado.
|
|
@@ -46,21 +44,21 @@ Os conceitos por trás dessas chamadas estão em [Conceitos](./concepts.md); aqu
|
|
|
46
44
|
- **`setContext(name, ctx | null)`** — define um [context](./concepts.md#context) nomeado. Passar `null` **apaga o grupo inteiro**. Os grupos `runtime` e `os` são injetados pelo SDK em todo evento.
|
|
47
45
|
- **`setExtra(key, value)`** — anexa um dado livre, sem estrutura e sem índice. Conceito e critério de escolha em [Extra](./concepts.md#extra).
|
|
48
46
|
- **`withScope(cb)`** — roda o callback com um **clone** do scope e restaura o original no fim; devolve o que o callback devolver. É **síncrono** — um `await` dentro do callback não isola de código concorrente. Conceito: [withScope](./concepts.md#withscope).
|
|
49
|
-
- **`startTransaction(name, op?)`** — abre uma [transaction](./concepts.md#transaction) de performance. A decisão de [amostragem](./concepts.md#amostragem-samplerate-e-tracessamplerate) acontece **aqui**, não no `finish()`. Nada é enviado até o `finish()`. Dentro de um handler
|
|
47
|
+
- **`startTransaction(name, op?)`** — abre uma [transaction](./concepts.md#transaction) de performance. A decisão de [amostragem](./concepts.md#amostragem-samplerate-e-tracessamplerate) acontece **aqui**, não no `finish()`. Nada é enviado até o `finish()`. **Dentro de um handler de task**, devolve a [transaction da própria run](./concepts.md#transaction-de-run-ctxtx) (`ctx.tx`) em vez de criar uma segunda — cada execução tem exatamente uma transaction; fora de um handler, cria uma transaction nova, sem `run_id`.
|
|
50
48
|
- **`checkIn(options)`** — envia um [check-in](./concepts.md#check-in) avulso e devolve o `check_in_id`. Reaproveite o id do `in_progress` para fechar a execução com `ok`/`error`.
|
|
51
49
|
- **`withMonitor(slug, fn, options?)`** — envolve `fn` no par de check-ins (`in_progress` → `ok`/`error`) medindo a duração, e devolve o que `fn` devolver. Em caso de erro, fecha como `error`, captura o evento com a tag `monitor: <slug>` e **relança** a exceção. Passe `schedule` para o servidor criar/atualizar o monitor sozinho e detectar execução perdida.
|
|
52
50
|
- **`flush(timeoutMs = 5_000)`** → `Promise<boolean>` — empurra a fila do transport e aguarda os envios em andamento. `true` = tudo saiu no prazo; `false` = o SDK parou de esperar (os envios em voo seguem tentando). O SDK **continua utilizável** depois. Conceito: [Fila, flush e close](./concepts.md#fila-flush-e-close).
|
|
53
51
|
- **`close(timeoutMs = 5_000)`** → `Promise<boolean>` — encerra tudo na ordem agente → heartbeat → flush final. O `timeoutMs` é gasto **duas vezes** (espera das runs, depois flush). Depois do `close()` o transport está fechado e todo item novo é descartado com aviso no console; não há `reopen()`. Conceito: [Fila, flush e close](./concepts.md#fila-flush-e-close).
|
|
54
52
|
|
|
55
|
-
Classes exportadas: `Client`, `Scope`, `Transaction`, `Span`.
|
|
53
|
+
Classes exportadas: `Client`, `Scope`, `Transaction`, `Span`. A resolução da credencial nos endpoints é interna ao `init()` (constante `DEFAULT_BASE_URL = 'https://api2.hobots.app'`, exportada; em desenvolvimento a env `HOBOTS_API_URL` sobrescreve a URL base). A config resolvida fica acessível em `getClient()?.config`:
|
|
56
54
|
|
|
57
55
|
```ts
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
}
|
|
56
|
+
getClient()?.config; // {
|
|
57
|
+
// key: string; — Client Secret do projeto (vai no Authorization: Bearer, nunca na URL)
|
|
58
|
+
// baseUrl: string; — DEFAULT_BASE_URL, ou HOBOTS_API_URL em desenvolvimento
|
|
59
|
+
// ingestEndpoint: string; — <baseUrl>/v1/ingest
|
|
60
|
+
// tasksBaseUrl: string; — <baseUrl>/v1/tasks
|
|
61
|
+
// }
|
|
64
62
|
```
|
|
65
63
|
|
|
66
64
|
### Métodos de `Transaction` / `Span` / `Scope`
|
|
@@ -74,25 +72,23 @@ Todos encadeáveis, exceto `finish()` e `toJSON()`.
|
|
|
74
72
|
|
|
75
73
|
---
|
|
76
74
|
|
|
77
|
-
##
|
|
75
|
+
## Tasks — funções
|
|
78
76
|
|
|
79
|
-
|
|
77
|
+
Habilitadas com `tasks: true` (ou `TasksOptions`) no `init()` único. Todas exportadas do import raiz `hobots`:
|
|
80
78
|
|
|
81
79
|
| Função | Assinatura |
|
|
82
80
|
| --- | --- |
|
|
83
|
-
| `register` | `register<P>(task: string, handler:
|
|
84
|
-
| `start` | `start(): void` — lança se o `init()` não configurou `
|
|
85
|
-
| `stop` | `stop(timeoutMs = 30_000): Promise<boolean>` — para só o
|
|
81
|
+
| `register` | `register<P>(task: string, handler: TaskHandler<P>): void` |
|
|
82
|
+
| `start` | `start(): void` — lança se o `init()` não configurou `tasks` ou sem tasks registradas |
|
|
83
|
+
| `stop` | `stop(timeoutMs = 30_000): Promise<boolean>` — para só o polling de tasks; a telemetria continua |
|
|
86
84
|
|
|
87
85
|
### O que cada função faz
|
|
88
86
|
|
|
89
|
-
- **`register(task, handler)`** — associa um handler ao `task_slug` configurado no formulário do app. Registre **antes** de `start()`; pode ser chamado antes do `init()`. Registrar o mesmo `task` duas vezes **sobrescreve** o handler (com aviso no console). Se o `init()` não habilitou
|
|
90
|
-
- **`start()`** — começa o polling. **Mantém o processo vivo** até `stop()`/`close()` — o timer não é `unref`'d, ao contrário dos
|
|
91
|
-
- **`stop(timeoutMs = 30_000)`** → `Promise<boolean>` — encerra o polling e aguarda as [runs](./concepts.md#run) ativas terminarem. Para **só
|
|
92
|
-
|
|
93
|
-
Classes/erros exportados: `ManagerAgent`, `ManagerApi`, `ManagerApiError`.
|
|
87
|
+
- **`register(task, handler)`** — associa um handler ao `task_slug` configurado no formulário do app (**Configurações → Formulários**). Registre **antes** de `start()`; pode ser chamado antes do `init()`. Registrar o mesmo `task` duas vezes **sobrescreve** o handler (com aviso no console). Se o `init()` não habilitou as tasks, o SDK avisa e não faz nada. Tipagem dos params: `register<{ lote: number }>(…)`.
|
|
88
|
+
- **`start()`** — começa o polling. **Mantém o processo vivo** até `stop()`/`close()` — o timer não é `unref`'d, ao contrário dos da telemetria. Lança se o `init()` não configurou `tasks` ou se nenhuma task foi registrada. Também instala os handlers de saída (SIGINT/SIGTERM/erro fatal) que reportam as runs ativas como `AgentTerminated`, a menos que `installExitHandlers: false`.
|
|
89
|
+
- **`stop(timeoutMs = 30_000)`** → `Promise<boolean>` — encerra o polling e aguarda as [runs](./concepts.md#run) ativas terminarem. Para **só as tasks**: a telemetria (heartbeat, captura de erros) continua funcionando. Devolve `false` se estourou o timeout — as runs que ainda estavam rodando são reportadas como `AgentTerminated`. Para encerrar tudo, use [`close()`](./concepts.md#fila-flush-e-close).
|
|
94
90
|
|
|
95
|
-
No poll, o agente se identifica com `
|
|
91
|
+
No poll, o agente se identifica com `AgentInfo` (`hobots/protocol`): o campo `instance_id` (o `instanceId` do `init()`) é a identidade canônica do agente — a mesma do heartbeat de telemetria, então os dois canais convergem em um agente no painel.
|
|
96
92
|
|
|
97
93
|
---
|
|
98
94
|
|
|
@@ -105,14 +101,14 @@ No poll, o agente se identifica com `ManagerAgentInfo` (`hobots/protocol`): o ca
|
|
|
105
101
|
| `clientSecret` | `string` | — | **obrigatório**; o Client Secret do projeto (`hb_<64 hex>`), copiado em **Configurações → Projetos** |
|
|
106
102
|
| `environment` | `string` | `'production'` | ambiente lógico |
|
|
107
103
|
| `release` | `string` | — | versão do programa, ex. `robo-nfe@1.4.2` |
|
|
108
|
-
| `instanceId` | `string` | **obrigatório** | identidade única da instância; heartbeat
|
|
104
|
+
| `instanceId` | `string` | **obrigatório** | identidade única da instância; heartbeat e poll de tasks convergem nela |
|
|
109
105
|
| `tags` | `Record<string,string>` | — | tags aplicadas a todos os eventos |
|
|
110
106
|
| `sampleRate` | `number` | `1` | amostragem de erros (0..1) |
|
|
111
107
|
| `tracesSampleRate` | `number` | `1` | amostragem de transactions (0..1) |
|
|
112
108
|
| `maxBreadcrumbs` | `number` | `100` | tamanho do buffer de breadcrumbs |
|
|
113
109
|
| `captureUnhandled` | `boolean` | `true` | handlers globais de erro |
|
|
114
110
|
| `heartbeat` | `boolean \| HeartbeatOptions` | `false` | heartbeat periódico |
|
|
115
|
-
| `
|
|
111
|
+
| `tasks` | `boolean \| TasksOptions` | `false` | habilita a execução sob demanda (`true` usa defaults) |
|
|
116
112
|
| `beforeSend` | `(event) => event \| null` | — | edita/descarta evento (retorne `null` para descartar) |
|
|
117
113
|
| `debug` | `boolean` | `false` | loga atividade do SDK |
|
|
118
114
|
| `flushIntervalMs` | `number` | `2000` | intervalo do flush automático do transport |
|
|
@@ -157,9 +153,9 @@ O teto da fila do transport (200 itens; ao encher, o **mais antigo** é descarta
|
|
|
157
153
|
| `schedule` | `string` | expressão cron (upsert do monitor) |
|
|
158
154
|
| `timezone` | `string` | fuso do `schedule` |
|
|
159
155
|
|
|
160
|
-
###
|
|
156
|
+
### TasksOptions
|
|
161
157
|
|
|
162
|
-
Valor do campo `
|
|
158
|
+
Valor do campo `tasks` do `InitOptions`. O Client Secret, o `debug` e a identidade (`instanceId`) vêm do `init()`.
|
|
163
159
|
|
|
164
160
|
| Opção | Tipo | Default | Descrição |
|
|
165
161
|
| --- | --- | --- | --- |
|
|
@@ -170,17 +166,17 @@ Valor do campo `manager` do `InitOptions`. O Client Secret, o `debug` e a identi
|
|
|
170
166
|
| `cancelCheckIntervalMs` | `number` | `5000` | heartbeat de cancelamento por run (clamp 1000..15000) — também é o sinal de vida da run (servidor marca `AgentTerminated` após ~60s sem reporte) |
|
|
171
167
|
| `installExitHandlers` | `boolean` | `true` | handlers de SIGINT/SIGTERM/uncaughtException que reportam as runs ativas como `AgentTerminated` antes do processo morrer; nunca interferem quando o programa tem handler próprio |
|
|
172
168
|
|
|
173
|
-
###
|
|
169
|
+
### TaskHandler / RunContext
|
|
174
170
|
|
|
175
171
|
```ts
|
|
176
172
|
// o retorno do handler é ignorado — nada além de status/logs/erro é enviado ao servidor
|
|
177
|
-
type
|
|
173
|
+
type TaskHandler<P = Record<string, unknown>> =
|
|
178
174
|
(params: P, ctx: RunContext) => void | Promise<void>;
|
|
179
175
|
|
|
180
176
|
interface RunContext {
|
|
181
177
|
runId: string;
|
|
182
178
|
task: string;
|
|
183
|
-
log
|
|
179
|
+
log: RunLogger; // ctx.log.debug/info/warn/error/success(message)
|
|
184
180
|
tx: Transaction; // transaction desta run — correlacionada e finalizada pelo SDK
|
|
185
181
|
signal: AbortSignal;
|
|
186
182
|
throwIfCanceled(): void; // lança RunCanceled se o signal já disparou
|
|
@@ -189,8 +185,8 @@ interface RunContext {
|
|
|
189
185
|
```
|
|
190
186
|
|
|
191
187
|
- **`runId` / `task`** — identificam a execução; úteis para correlacionar com os seus próprios logs.
|
|
192
|
-
- **`log(
|
|
193
|
-
- **`tx`** — a [transaction de performance da run](./concepts.md#transaction-de-run-ctxtx). Use `ctx.tx.startChild(op, description)` para medir as etapas; **não** chame `finish()` nela
|
|
188
|
+
- **`log.<level>(message)`** — níveis `debug`, `info`, `warn`, `error` e `success`; enfileira uma linha de log enviada ao app em PATCHes incrementais, e **também imprime no terminal local**. Conceito: [Run](./concepts.md#run).
|
|
189
|
+
- **`tx`** — a [transaction de performance da run](./concepts.md#transaction-de-run-ctxtx). Use `ctx.tx.startChild(op, description)` para medir as etapas; **não** chame `finish()` nela. `startTransaction()` dentro do handler devolve essa mesma transaction.
|
|
194
190
|
- **`signal`** — `AbortSignal` que dispara em cancelamento no app, timeout ou shutdown.
|
|
195
191
|
- **`throwIfCanceled()`** — o ponto de parada de uma linha: lança `RunCanceled` se o `signal` já disparou.
|
|
196
192
|
- **`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.
|
|
@@ -201,7 +197,7 @@ interface RunContext {
|
|
|
201
197
|
|
|
202
198
|
Todos os prazos do SDK num lugar só. A coluna **Onde configura** diz se o valor é seu ou fixo — o que está com `—` é comportamento do SDK ou do servidor e não se muda pelo `init()`.
|
|
203
199
|
|
|
204
|
-
###
|
|
200
|
+
### Telemetria — envio
|
|
205
201
|
|
|
206
202
|
| Tempo | Default | Onde configura | O que acontece |
|
|
207
203
|
| --- | --- | --- | --- |
|
|
@@ -213,20 +209,20 @@ Todos os prazos do SDK num lugar só. A coluna **Onde configura** diz se o valor
|
|
|
213
209
|
| ladder de retry | `1s, 4s, 16s` | — (fixo) | 3 tentativas por envelope; depois ele é descartado. 4xx (exceto 429) não tem retry |
|
|
214
210
|
| heartbeat | `30000` ms | `init({ heartbeat: { intervalMs } })` | bate **imediatamente** no `init()` e depois a cada intervalo; o valor vai no payload e define quanto silêncio o servidor tolera antes de marcar offline |
|
|
215
211
|
|
|
216
|
-
###
|
|
212
|
+
### Tasks — polling e runs
|
|
217
213
|
|
|
218
214
|
| Tempo | Default | Onde configura | O que acontece |
|
|
219
215
|
| --- | --- | --- | --- |
|
|
220
|
-
| poll sem trabalho | `5000` ms (mín. `1000`) | `
|
|
221
|
-
| flush de logs da run | `2000` ms | `
|
|
222
|
-
| heartbeat de cancelamento | `5000` ms (clamp `1000`..`15000`) | `
|
|
223
|
-
| timeout por run | sem timeout | `
|
|
216
|
+
| poll sem trabalho | `5000` ms (mín. `1000`) | `tasks: { pollIntervalMs }` | é só o **teto da espera quando não há nada**: com trabalho na fila o próximo poll é imediato ([drain mode](./concepts.md#drain-mode)) |
|
|
217
|
+
| flush de logs da run | `2000` ms | `tasks: { logFlushIntervalMs }` | ou na hora, ao acumular 20 linhas |
|
|
218
|
+
| heartbeat de cancelamento | `5000` ms (clamp `1000`..`15000`) | `tasks: { cancelCheckIntervalMs }` | detecta cancelamento feito no app **e** é o sinal de vida da run (veja a nota 2) |
|
|
219
|
+
| timeout por run | sem timeout | `tasks: { taskTimeoutMs }` | no estouro dispara `ctx.signal`, libera o slot de concorrência e reporta `TaskTimeout` — **não mata** o handler |
|
|
224
220
|
| `stop(timeoutMs)` | `30000` ms | argumento | espera as runs ativas; no estouro elas são reportadas como `AgentTerminated` |
|
|
225
221
|
| retry do poll | `1s, 4s, 16s` | — (fixo) | erros de rede/5xx |
|
|
226
222
|
| retry com chave rejeitada (401) | `30000` ms | — (fixo) | segue tentando devagar, com log throttled |
|
|
227
223
|
| PATCH do caminho de saída | `~2500` ms | — (fixo) | melhor esforço, sem retry, ao morrer com run ativa |
|
|
228
224
|
| sweep do servidor | `~60000` ms | — (servidor) | run `running` sem reporte por esse tempo vira `failed`/`AgentTerminated`, sem re-entrega |
|
|
229
225
|
|
|
230
|
-
**Nota 1 — `close(timeoutMs)` gasta o tempo duas vezes.** Ele espera as runs
|
|
226
|
+
**Nota 1 — `close(timeoutMs)` gasta o tempo duas vezes.** Ele espera as runs de tasks (`timeoutMs`) e **depois** faz o flush final (`timeoutMs`), em sequência. Pior caso ≈ `2 × timeoutMs`; `close()` sem argumento pode levar até ~35s (30s aguardando runs + 5s de flush). Se o seu SIGTERM tem prazo curto (Kubernetes, systemd), dimensione por aí.
|
|
231
227
|
|
|
232
228
|
**Nota 2 — o teto de 15s do `cancelCheckIntervalMs` existe por causa do sweep de 60s.** Esse heartbeat é o que mantém o `last_report_at` da run atualizado; o clamp garante que o intervalo nunca chegue perto do prazo em que o servidor declara a run morta.
|