hobots 2.2.0 → 2.4.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 +14 -2
- package/dist/index.cjs +216 -46
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +57 -6
- package/dist/index.d.ts +57 -6
- package/dist/index.js +216 -46
- package/dist/index.js.map +1 -1
- package/dist/protocol.cjs.map +1 -1
- package/dist/protocol.d.cts +85 -3
- package/dist/protocol.d.ts +85 -3
- package/docs/api-reference.md +4 -1
- package/docs/concepts.md +5 -1
- package/docs/protocol.md +23 -0
- package/docs/telemetry.md +11 -0
- package/package.json +5 -3
package/dist/protocol.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/protocol.ts"],"sourcesContent":["/**\n * Tipos do protocolo do Hobots (SDK → servidor).\n *\n * Este arquivo é a fonte de verdade do wire format e só pode reexportar tipos:\n * o app valida os payloads com zod e trava o drift via `satisfies z.ZodType<...>`\n * contra estes tipos (importados de `hobots/protocol`).\n */\n\n// Wire format de tasks (agente ↔ servidor) — reexportado aqui para o app\n// consumir tudo de `hobots/protocol`.\nexport type {\n RunStatus,\n RunUpdateStatus,\n RunLogLevel,\n RunLogEntry,\n InstanceInfo,\n PollRequest,\n RunDescriptor,\n PollResponse,\n RunError,\n RunProgress,\n RunUpdateRequest,\n RunUpdateResponse,\n RunItemStatus,\n RunItemInput,\n RunItemsCreateRequest,\n RunItemsCreateResponse,\n RunAttachmentContentType,\n RunAttachmentCreateRequest,\n RunAttachmentCreateResponse,\n RunAttachmentConfirmRequest,\n RunAttachmentConfirmResponse,\n} from './tasks/protocol';\n\n/**\n * Tipo de um evento — o que ele é, não o quanto ele fala. Só 'fatal', 'error' e\n * 'warning' viram issue; 'success' é ingerido e nunca abre issue.\n * Ruído de log não é evento: para isso existem os logs da execução (RunLogLevel)\n * e as breadcrumbs, que têm níveis próprios com 'debug'/'info'.\n */\nexport type EventType = 'fatal' | 'error' | 'warning' | 'success';\n\n/** Nível de uma breadcrumb — trilha do que aconteceu antes, aqui log é bem-vindo. */\nexport type BreadcrumbLevel = 'debug' | 'info' | 'warning' | 'error' | 'fatal';\n\n/** Frames em ordem innermost-first (mesma ordem impressa pelo V8). */\nexport interface StackFrame {\n function?: string;\n filename?: string;\n lineno?: number;\n colno?: number;\n in_app: boolean;\n}\n\nexport interface Breadcrumb {\n /** ISO 8601 */\n timestamp: string;\n type?: string;\n category?: string;\n message?: string;\n level?: BreadcrumbLevel;\n data?: Record<string, unknown>;\n}\n\nexport interface ExceptionData {\n type: string;\n value: string;\n stacktrace?: { frames: StackFrame[] };\n}\n\nexport interface EventUser {\n id?: string;\n username?: string;\n email?: string;\n}\n\nexport interface EventPayload {\n /** uuid v4 sem hífens (32 hex), gerado pelo SDK */\n event_id: string;\n /** ISO 8601 */\n timestamp: string;\n type: EventType;\n message?: string;\n exception?: ExceptionData;\n /** Override de agrupamento; quando ausente o servidor calcula pelo stack trace */\n fingerprint?: string[];\n breadcrumbs?: Breadcrumb[];\n tags?: Record<string, string>;\n user?: EventUser;\n contexts?: Record<string, Record<string, unknown>>;\n extra?: Record<string, unknown>;\n release?: string;\n environment?:
|
|
1
|
+
{"version":3,"sources":["../src/protocol.ts"],"sourcesContent":["/**\n * Tipos do protocolo do Hobots (SDK → servidor).\n *\n * Este arquivo é a fonte de verdade do wire format e só pode reexportar tipos:\n * o app valida os payloads com zod e trava o drift via `satisfies z.ZodType<...>`\n * contra estes tipos (importados de `hobots/protocol`).\n */\n\nimport type { EnvironmentInput } from './environment-protocol';\nimport type { MachineSnapshot } from './machine-protocol';\n\n// Wire format de tasks (agente ↔ servidor) — reexportado aqui para o app\n// consumir tudo de `hobots/protocol`.\nexport type {\n RunStatus,\n RunUpdateStatus,\n RunLogLevel,\n RunLogEntry,\n InstanceInfo,\n PollRequest,\n RunDescriptor,\n PollResponse,\n RunError,\n RunProgress,\n RunUpdateRequest,\n RunUpdateResponse,\n RunItemStatus,\n RunItemInput,\n RunItemsCreateRequest,\n RunItemsCreateResponse,\n RunAttachmentContentType,\n RunAttachmentCreateRequest,\n RunAttachmentCreateResponse,\n RunAttachmentConfirmRequest,\n RunAttachmentConfirmResponse,\n} from './tasks/protocol';\n\n// Snapshot de recursos da máquina — usado no heartbeat, no poll e em contexts.machine.\nexport type { MachineProcess, MachineSnapshot } from './machine-protocol';\nexport type { Environment, EnvironmentInput } from './environment-protocol';\n\n/**\n * Tipo de um evento — o que ele é, não o quanto ele fala. Só 'fatal', 'error' e\n * 'warning' viram issue; 'success' é ingerido e nunca abre issue.\n * Ruído de log não é evento: para isso existem os logs da execução (RunLogLevel)\n * e as breadcrumbs, que têm níveis próprios com 'debug'/'info'.\n */\nexport type EventType = 'fatal' | 'error' | 'warning' | 'success';\n\n/** Nível de uma breadcrumb — trilha do que aconteceu antes, aqui log é bem-vindo. */\nexport type BreadcrumbLevel = 'debug' | 'info' | 'warning' | 'error' | 'fatal';\n\n/** Frames em ordem innermost-first (mesma ordem impressa pelo V8). */\nexport interface StackFrame {\n function?: string;\n filename?: string;\n lineno?: number;\n colno?: number;\n in_app: boolean;\n}\n\nexport interface Breadcrumb {\n /** ISO 8601 */\n timestamp: string;\n type?: string;\n category?: string;\n message?: string;\n level?: BreadcrumbLevel;\n data?: Record<string, unknown>;\n}\n\nexport interface ExceptionData {\n type: string;\n value: string;\n stacktrace?: { frames: StackFrame[] };\n}\n\nexport interface EventUser {\n id?: string;\n username?: string;\n email?: string;\n}\n\nexport interface EventPayload {\n /** uuid v4 sem hífens (32 hex), gerado pelo SDK */\n event_id: string;\n /** ISO 8601 */\n timestamp: string;\n type: EventType;\n message?: string;\n exception?: ExceptionData;\n /** Override de agrupamento; quando ausente o servidor calcula pelo stack trace */\n fingerprint?: string[];\n breadcrumbs?: Breadcrumb[];\n tags?: Record<string, string>;\n user?: EventUser;\n contexts?: Record<string, Record<string, unknown>>;\n extra?: Record<string, unknown>;\n release?: string;\n environment?: EnvironmentInput;\n}\n\n/** Status de uma step (etapa). `warning` = terminou, mas merece atenção (não é falha). */\nexport type StepStatus = 'ok' | 'warning' | 'error' | 'cancelled';\n\nexport interface StepData {\n /** 16 hex */\n step_id: string;\n parent_step_id?: string;\n op?: string;\n description?: string;\n status?: StepStatus;\n /** ISO 8601 */\n start_timestamp: string;\n /** ISO 8601 (fim da step) */\n timestamp: string;\n data?: Record<string, unknown>;\n}\n\nexport interface TransactionPayload {\n event_id: string;\n name: string;\n op?: string;\n status: string;\n start_timestamp: string;\n timestamp: string;\n steps: StepData[];\n tags?: Record<string, string>;\n release?: string;\n environment?: EnvironmentInput;\n /** Correlaciona esta transaction a uma execução de task (ctx.tx dentro de um task handler) */\n run_id?: string;\n}\n\nexport interface HeartbeatPayload {\n instance_id: string;\n name?: string;\n interval_ms: number;\n /** ISO 8601 */\n timestamp: string;\n metadata?: Record<string, unknown>;\n release?: string;\n /** Ambiente da instância — é ele que o app exibe e que as regras de alerta filtram */\n environment?: EnvironmentInput;\n /** Recursos da máquina no momento do beat (CPU, memória, disco, processo) */\n machine?: MachineSnapshot;\n}\n\nexport type EnvelopeItem =\n | { type: 'event'; payload: EventPayload }\n | { type: 'transaction'; payload: TransactionPayload }\n | { type: 'heartbeat'; payload: HeartbeatPayload };\n\nexport interface Envelope {\n sdk: { name: string; version: string };\n /** ISO 8601 */\n sent_at: string;\n items: EnvelopeItem[];\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAAA;AAAA;","names":[]}
|
package/dist/protocol.d.cts
CHANGED
|
@@ -1,3 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ambiente lógico onde o robô roda.
|
|
3
|
+
*
|
|
4
|
+
* Arquivo-folha do protocolo (não importa nada): referenciado pelo heartbeat, pelo
|
|
5
|
+
* poll de tasks (`InstanceInfo.environment`) e pelos eventos/transactions, e
|
|
6
|
+
* reexportado por `hobots/protocol`.
|
|
7
|
+
*
|
|
8
|
+
* A fonte única do vocabulário (rótulos em pt-BR, apelidos legados aceitos e a
|
|
9
|
+
* normalização) vive no servidor, em packages/utils/src/environments.ts — o SDK é
|
|
10
|
+
* publicado sozinho no npm e não depende do monorepo, então o union é redeclarado
|
|
11
|
+
* aqui. O servidor normaliza o que chega: valores antigos de texto livre ('prod',
|
|
12
|
+
* 'qa', 'homologacao') continuam sendo aceitos e classificados.
|
|
13
|
+
*/
|
|
14
|
+
type Environment = 'development' | 'testing' | 'staging' | 'production';
|
|
15
|
+
/**
|
|
16
|
+
* O que o wire realmente aceita: o ambiente canônico ou uma string legada que o
|
|
17
|
+
* servidor normaliza ('prod', 'qa', 'homologacao'...). O `string & {}` preserva o
|
|
18
|
+
* autocomplete dos quatro valores sem fechar a porta para o que já roda em campo
|
|
19
|
+
* — e mantém os `satisfies z.ZodType<...>` da api fechando contra `z.string()`.
|
|
20
|
+
*/
|
|
21
|
+
type EnvironmentInput = Environment | (string & {});
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Snapshot dos recursos da máquina onde a instância roda.
|
|
25
|
+
*
|
|
26
|
+
* Arquivo-folha do protocolo (não importa nada): reexportado por `hobots/protocol`
|
|
27
|
+
* e referenciado pelo heartbeat, pelo poll de tasks (`InstanceInfo.machine`) e por
|
|
28
|
+
* `contexts.machine` nos eventos. Bytes em bytes; percentuais 0..100. Campo ausente =
|
|
29
|
+
* não mensurável nesta plataforma/runtime.
|
|
30
|
+
*/
|
|
31
|
+
interface MachineProcess {
|
|
32
|
+
pid: number;
|
|
33
|
+
/** segundos desde o `init()` do SDK (Python) / início do processo (Node) */
|
|
34
|
+
uptime_s: number;
|
|
35
|
+
/** memória residente do processo do bot */
|
|
36
|
+
rss_bytes?: number;
|
|
37
|
+
/** CPU do processo, 0..100 normalizado pelo número de cores (delta entre coletas); null até haver 2 amostras */
|
|
38
|
+
cpu_percent?: number | null;
|
|
39
|
+
/** só Node: `process.memoryUsage().heapUsed` */
|
|
40
|
+
heap_used_bytes?: number;
|
|
41
|
+
/** só Python: `threading.active_count()` */
|
|
42
|
+
threads?: number;
|
|
43
|
+
}
|
|
44
|
+
interface MachineSnapshot {
|
|
45
|
+
/** ISO 8601 — momento da coleta (relógio do cliente) */
|
|
46
|
+
sampled_at: string;
|
|
47
|
+
/** `InitOptions.instanceId` — liga o snapshot de um evento à série da instância */
|
|
48
|
+
instance_id?: string;
|
|
49
|
+
hostname?: string;
|
|
50
|
+
/** `process.platform` / `sys.platform`: 'linux' | 'win32' | 'darwin' | ... */
|
|
51
|
+
os?: string;
|
|
52
|
+
arch?: string;
|
|
53
|
+
/** cores lógicos */
|
|
54
|
+
cpu_count?: number;
|
|
55
|
+
/** uso de CPU do sistema, 0..100 — média entre duas coletas; null até haver 2 amostras */
|
|
56
|
+
cpu_percent?: number | null;
|
|
57
|
+
/** load average de 1 min (POSIX; ausente no Windows) */
|
|
58
|
+
load_1?: number;
|
|
59
|
+
mem_total_bytes?: number;
|
|
60
|
+
mem_available_bytes?: number;
|
|
61
|
+
/** (total - disponível) / total × 100 */
|
|
62
|
+
mem_percent?: number;
|
|
63
|
+
/** volume medido — o diretório de trabalho do processo */
|
|
64
|
+
disk_path?: string;
|
|
65
|
+
disk_total_bytes?: number;
|
|
66
|
+
/** disponível para o usuário (bavail) */
|
|
67
|
+
disk_free_bytes?: number;
|
|
68
|
+
disk_percent?: number;
|
|
69
|
+
process: MachineProcess;
|
|
70
|
+
/** de onde vieram os números */
|
|
71
|
+
source?: 'stdlib' | 'psutil' | 'stdlib-loadavg';
|
|
72
|
+
}
|
|
73
|
+
|
|
1
74
|
/**
|
|
2
75
|
* Tipos do protocolo de tasks do Hobots (agente SDK ↔ servidor).
|
|
3
76
|
*
|
|
@@ -5,6 +78,7 @@
|
|
|
5
78
|
* o app valida os payloads com zod e trava o drift via `satisfies z.ZodType<...>`
|
|
6
79
|
* contra estes tipos (reexportados por `hobots/protocol`).
|
|
7
80
|
*/
|
|
81
|
+
|
|
8
82
|
/** Ciclo de vida completo de uma run no servidor. */
|
|
9
83
|
type RunStatus = 'pending' | 'claimed' | 'running' | 'succeeded' | 'failed' | 'canceled';
|
|
10
84
|
/** Subconjunto que o agente pode enviar no PATCH. */
|
|
@@ -30,6 +104,8 @@ interface InstanceInfo {
|
|
|
30
104
|
version?: string;
|
|
31
105
|
/** Hostname da máquina */
|
|
32
106
|
host?: string;
|
|
107
|
+
/** Ambiente da instância — mesmo valor do heartbeat; agentes poll-only só o informam aqui */
|
|
108
|
+
environment?: EnvironmentInput;
|
|
33
109
|
/** Tasks registradas no agente */
|
|
34
110
|
tasks?: string[];
|
|
35
111
|
/**
|
|
@@ -37,6 +113,8 @@ interface InstanceInfo {
|
|
|
37
113
|
* agentes poll-only, que sem isso herdariam a tolerância do heartbeat (30s × 3).
|
|
38
114
|
*/
|
|
39
115
|
poll_interval_ms?: number;
|
|
116
|
+
/** Recursos da máquina no momento do poll — alimenta a série da instância em agentes sem heartbeat */
|
|
117
|
+
machine?: MachineSnapshot;
|
|
40
118
|
}
|
|
41
119
|
/** POST /v1/tasks/poll */
|
|
42
120
|
interface PollRequest {
|
|
@@ -221,7 +299,7 @@ interface EventPayload {
|
|
|
221
299
|
contexts?: Record<string, Record<string, unknown>>;
|
|
222
300
|
extra?: Record<string, unknown>;
|
|
223
301
|
release?: string;
|
|
224
|
-
environment?:
|
|
302
|
+
environment?: EnvironmentInput;
|
|
225
303
|
}
|
|
226
304
|
/** Status de uma step (etapa). `warning` = terminou, mas merece atenção (não é falha). */
|
|
227
305
|
type StepStatus = 'ok' | 'warning' | 'error' | 'cancelled';
|
|
@@ -248,7 +326,7 @@ interface TransactionPayload {
|
|
|
248
326
|
steps: StepData[];
|
|
249
327
|
tags?: Record<string, string>;
|
|
250
328
|
release?: string;
|
|
251
|
-
environment?:
|
|
329
|
+
environment?: EnvironmentInput;
|
|
252
330
|
/** Correlaciona esta transaction a uma execução de task (ctx.tx dentro de um task handler) */
|
|
253
331
|
run_id?: string;
|
|
254
332
|
}
|
|
@@ -260,6 +338,10 @@ interface HeartbeatPayload {
|
|
|
260
338
|
timestamp: string;
|
|
261
339
|
metadata?: Record<string, unknown>;
|
|
262
340
|
release?: string;
|
|
341
|
+
/** Ambiente da instância — é ele que o app exibe e que as regras de alerta filtram */
|
|
342
|
+
environment?: EnvironmentInput;
|
|
343
|
+
/** Recursos da máquina no momento do beat (CPU, memória, disco, processo) */
|
|
344
|
+
machine?: MachineSnapshot;
|
|
263
345
|
}
|
|
264
346
|
type EnvelopeItem = {
|
|
265
347
|
type: 'event';
|
|
@@ -281,4 +363,4 @@ interface Envelope {
|
|
|
281
363
|
items: EnvelopeItem[];
|
|
282
364
|
}
|
|
283
365
|
|
|
284
|
-
export type { Breadcrumb, BreadcrumbLevel, Envelope, EnvelopeItem, EventPayload, EventType, EventUser, ExceptionData, HeartbeatPayload, InstanceInfo, PollRequest, PollResponse, RunAttachmentConfirmRequest, RunAttachmentConfirmResponse, RunAttachmentContentType, RunAttachmentCreateRequest, RunAttachmentCreateResponse, RunDescriptor, RunError, RunItemInput, RunItemStatus, RunItemsCreateRequest, RunItemsCreateResponse, RunLogEntry, RunLogLevel, RunProgress, RunStatus, RunUpdateRequest, RunUpdateResponse, RunUpdateStatus, StackFrame, StepData, StepStatus, TransactionPayload };
|
|
366
|
+
export type { Breadcrumb, BreadcrumbLevel, Envelope, EnvelopeItem, Environment, EnvironmentInput, EventPayload, EventType, EventUser, ExceptionData, HeartbeatPayload, InstanceInfo, MachineProcess, MachineSnapshot, PollRequest, PollResponse, RunAttachmentConfirmRequest, RunAttachmentConfirmResponse, RunAttachmentContentType, RunAttachmentCreateRequest, RunAttachmentCreateResponse, RunDescriptor, RunError, RunItemInput, RunItemStatus, RunItemsCreateRequest, RunItemsCreateResponse, RunLogEntry, RunLogLevel, RunProgress, RunStatus, RunUpdateRequest, RunUpdateResponse, RunUpdateStatus, StackFrame, StepData, StepStatus, TransactionPayload };
|
package/dist/protocol.d.ts
CHANGED
|
@@ -1,3 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Ambiente lógico onde o robô roda.
|
|
3
|
+
*
|
|
4
|
+
* Arquivo-folha do protocolo (não importa nada): referenciado pelo heartbeat, pelo
|
|
5
|
+
* poll de tasks (`InstanceInfo.environment`) e pelos eventos/transactions, e
|
|
6
|
+
* reexportado por `hobots/protocol`.
|
|
7
|
+
*
|
|
8
|
+
* A fonte única do vocabulário (rótulos em pt-BR, apelidos legados aceitos e a
|
|
9
|
+
* normalização) vive no servidor, em packages/utils/src/environments.ts — o SDK é
|
|
10
|
+
* publicado sozinho no npm e não depende do monorepo, então o union é redeclarado
|
|
11
|
+
* aqui. O servidor normaliza o que chega: valores antigos de texto livre ('prod',
|
|
12
|
+
* 'qa', 'homologacao') continuam sendo aceitos e classificados.
|
|
13
|
+
*/
|
|
14
|
+
type Environment = 'development' | 'testing' | 'staging' | 'production';
|
|
15
|
+
/**
|
|
16
|
+
* O que o wire realmente aceita: o ambiente canônico ou uma string legada que o
|
|
17
|
+
* servidor normaliza ('prod', 'qa', 'homologacao'...). O `string & {}` preserva o
|
|
18
|
+
* autocomplete dos quatro valores sem fechar a porta para o que já roda em campo
|
|
19
|
+
* — e mantém os `satisfies z.ZodType<...>` da api fechando contra `z.string()`.
|
|
20
|
+
*/
|
|
21
|
+
type EnvironmentInput = Environment | (string & {});
|
|
22
|
+
|
|
23
|
+
/**
|
|
24
|
+
* Snapshot dos recursos da máquina onde a instância roda.
|
|
25
|
+
*
|
|
26
|
+
* Arquivo-folha do protocolo (não importa nada): reexportado por `hobots/protocol`
|
|
27
|
+
* e referenciado pelo heartbeat, pelo poll de tasks (`InstanceInfo.machine`) e por
|
|
28
|
+
* `contexts.machine` nos eventos. Bytes em bytes; percentuais 0..100. Campo ausente =
|
|
29
|
+
* não mensurável nesta plataforma/runtime.
|
|
30
|
+
*/
|
|
31
|
+
interface MachineProcess {
|
|
32
|
+
pid: number;
|
|
33
|
+
/** segundos desde o `init()` do SDK (Python) / início do processo (Node) */
|
|
34
|
+
uptime_s: number;
|
|
35
|
+
/** memória residente do processo do bot */
|
|
36
|
+
rss_bytes?: number;
|
|
37
|
+
/** CPU do processo, 0..100 normalizado pelo número de cores (delta entre coletas); null até haver 2 amostras */
|
|
38
|
+
cpu_percent?: number | null;
|
|
39
|
+
/** só Node: `process.memoryUsage().heapUsed` */
|
|
40
|
+
heap_used_bytes?: number;
|
|
41
|
+
/** só Python: `threading.active_count()` */
|
|
42
|
+
threads?: number;
|
|
43
|
+
}
|
|
44
|
+
interface MachineSnapshot {
|
|
45
|
+
/** ISO 8601 — momento da coleta (relógio do cliente) */
|
|
46
|
+
sampled_at: string;
|
|
47
|
+
/** `InitOptions.instanceId` — liga o snapshot de um evento à série da instância */
|
|
48
|
+
instance_id?: string;
|
|
49
|
+
hostname?: string;
|
|
50
|
+
/** `process.platform` / `sys.platform`: 'linux' | 'win32' | 'darwin' | ... */
|
|
51
|
+
os?: string;
|
|
52
|
+
arch?: string;
|
|
53
|
+
/** cores lógicos */
|
|
54
|
+
cpu_count?: number;
|
|
55
|
+
/** uso de CPU do sistema, 0..100 — média entre duas coletas; null até haver 2 amostras */
|
|
56
|
+
cpu_percent?: number | null;
|
|
57
|
+
/** load average de 1 min (POSIX; ausente no Windows) */
|
|
58
|
+
load_1?: number;
|
|
59
|
+
mem_total_bytes?: number;
|
|
60
|
+
mem_available_bytes?: number;
|
|
61
|
+
/** (total - disponível) / total × 100 */
|
|
62
|
+
mem_percent?: number;
|
|
63
|
+
/** volume medido — o diretório de trabalho do processo */
|
|
64
|
+
disk_path?: string;
|
|
65
|
+
disk_total_bytes?: number;
|
|
66
|
+
/** disponível para o usuário (bavail) */
|
|
67
|
+
disk_free_bytes?: number;
|
|
68
|
+
disk_percent?: number;
|
|
69
|
+
process: MachineProcess;
|
|
70
|
+
/** de onde vieram os números */
|
|
71
|
+
source?: 'stdlib' | 'psutil' | 'stdlib-loadavg';
|
|
72
|
+
}
|
|
73
|
+
|
|
1
74
|
/**
|
|
2
75
|
* Tipos do protocolo de tasks do Hobots (agente SDK ↔ servidor).
|
|
3
76
|
*
|
|
@@ -5,6 +78,7 @@
|
|
|
5
78
|
* o app valida os payloads com zod e trava o drift via `satisfies z.ZodType<...>`
|
|
6
79
|
* contra estes tipos (reexportados por `hobots/protocol`).
|
|
7
80
|
*/
|
|
81
|
+
|
|
8
82
|
/** Ciclo de vida completo de uma run no servidor. */
|
|
9
83
|
type RunStatus = 'pending' | 'claimed' | 'running' | 'succeeded' | 'failed' | 'canceled';
|
|
10
84
|
/** Subconjunto que o agente pode enviar no PATCH. */
|
|
@@ -30,6 +104,8 @@ interface InstanceInfo {
|
|
|
30
104
|
version?: string;
|
|
31
105
|
/** Hostname da máquina */
|
|
32
106
|
host?: string;
|
|
107
|
+
/** Ambiente da instância — mesmo valor do heartbeat; agentes poll-only só o informam aqui */
|
|
108
|
+
environment?: EnvironmentInput;
|
|
33
109
|
/** Tasks registradas no agente */
|
|
34
110
|
tasks?: string[];
|
|
35
111
|
/**
|
|
@@ -37,6 +113,8 @@ interface InstanceInfo {
|
|
|
37
113
|
* agentes poll-only, que sem isso herdariam a tolerância do heartbeat (30s × 3).
|
|
38
114
|
*/
|
|
39
115
|
poll_interval_ms?: number;
|
|
116
|
+
/** Recursos da máquina no momento do poll — alimenta a série da instância em agentes sem heartbeat */
|
|
117
|
+
machine?: MachineSnapshot;
|
|
40
118
|
}
|
|
41
119
|
/** POST /v1/tasks/poll */
|
|
42
120
|
interface PollRequest {
|
|
@@ -221,7 +299,7 @@ interface EventPayload {
|
|
|
221
299
|
contexts?: Record<string, Record<string, unknown>>;
|
|
222
300
|
extra?: Record<string, unknown>;
|
|
223
301
|
release?: string;
|
|
224
|
-
environment?:
|
|
302
|
+
environment?: EnvironmentInput;
|
|
225
303
|
}
|
|
226
304
|
/** Status de uma step (etapa). `warning` = terminou, mas merece atenção (não é falha). */
|
|
227
305
|
type StepStatus = 'ok' | 'warning' | 'error' | 'cancelled';
|
|
@@ -248,7 +326,7 @@ interface TransactionPayload {
|
|
|
248
326
|
steps: StepData[];
|
|
249
327
|
tags?: Record<string, string>;
|
|
250
328
|
release?: string;
|
|
251
|
-
environment?:
|
|
329
|
+
environment?: EnvironmentInput;
|
|
252
330
|
/** Correlaciona esta transaction a uma execução de task (ctx.tx dentro de um task handler) */
|
|
253
331
|
run_id?: string;
|
|
254
332
|
}
|
|
@@ -260,6 +338,10 @@ interface HeartbeatPayload {
|
|
|
260
338
|
timestamp: string;
|
|
261
339
|
metadata?: Record<string, unknown>;
|
|
262
340
|
release?: string;
|
|
341
|
+
/** Ambiente da instância — é ele que o app exibe e que as regras de alerta filtram */
|
|
342
|
+
environment?: EnvironmentInput;
|
|
343
|
+
/** Recursos da máquina no momento do beat (CPU, memória, disco, processo) */
|
|
344
|
+
machine?: MachineSnapshot;
|
|
263
345
|
}
|
|
264
346
|
type EnvelopeItem = {
|
|
265
347
|
type: 'event';
|
|
@@ -281,4 +363,4 @@ interface Envelope {
|
|
|
281
363
|
items: EnvelopeItem[];
|
|
282
364
|
}
|
|
283
365
|
|
|
284
|
-
export type { Breadcrumb, BreadcrumbLevel, Envelope, EnvelopeItem, EventPayload, EventType, EventUser, ExceptionData, HeartbeatPayload, InstanceInfo, PollRequest, PollResponse, RunAttachmentConfirmRequest, RunAttachmentConfirmResponse, RunAttachmentContentType, RunAttachmentCreateRequest, RunAttachmentCreateResponse, RunDescriptor, RunError, RunItemInput, RunItemStatus, RunItemsCreateRequest, RunItemsCreateResponse, RunLogEntry, RunLogLevel, RunProgress, RunStatus, RunUpdateRequest, RunUpdateResponse, RunUpdateStatus, StackFrame, StepData, StepStatus, TransactionPayload };
|
|
366
|
+
export type { Breadcrumb, BreadcrumbLevel, Envelope, EnvelopeItem, Environment, EnvironmentInput, EventPayload, EventType, EventUser, ExceptionData, HeartbeatPayload, InstanceInfo, MachineProcess, MachineSnapshot, PollRequest, PollResponse, RunAttachmentConfirmRequest, RunAttachmentConfirmResponse, RunAttachmentContentType, RunAttachmentCreateRequest, RunAttachmentCreateResponse, RunDescriptor, RunError, RunItemInput, RunItemStatus, RunItemsCreateRequest, RunItemsCreateResponse, RunLogEntry, RunLogLevel, RunProgress, RunStatus, RunUpdateRequest, RunUpdateResponse, RunUpdateStatus, StackFrame, StepData, StepStatus, TransactionPayload };
|
package/docs/api-reference.md
CHANGED
|
@@ -95,7 +95,7 @@ No poll, o agente se identifica com `InstanceInfo` (`hobots/protocol`): o campo
|
|
|
95
95
|
| Opção | Tipo | Default | Descrição |
|
|
96
96
|
| --- | --- | --- | --- |
|
|
97
97
|
| `clientSecret` | `string` | — | **obrigatório**; o Client Secret do agente (`hb_<64 hex>`), copiado em **Configurações → Agentes** |
|
|
98
|
-
| `environment` | `
|
|
98
|
+
| `environment` | `'development' \| 'testing' \| 'staging' \| 'production'` | `'production'` | ambiente lógico — vai nos eventos **e** na identidade da instância; é por ele que as regras de alerta decidem se notificam |
|
|
99
99
|
| `release` | `string` | — | versão do programa, ex. `robo-nfe@1.4.2` |
|
|
100
100
|
| `instanceId` | `string` | **obrigatório** | identidade única da instância; heartbeat e poll de tasks convergem nela |
|
|
101
101
|
| `tags` | `Record<string,string>` | — | tags aplicadas a todos os eventos |
|
|
@@ -103,6 +103,7 @@ No poll, o agente se identifica com `InstanceInfo` (`hobots/protocol`): o campo
|
|
|
103
103
|
| `tracesSampleRate` | `number` | `1` | amostragem de transactions (0..1) |
|
|
104
104
|
| `maxBreadcrumbs` | `number` | `100` | tamanho do buffer de breadcrumbs |
|
|
105
105
|
| `captureUnhandled` | `boolean` | `true` | handlers globais de erro |
|
|
106
|
+
| `machineMetrics` | `boolean` | `true` | coleta CPU/memória/disco/processo: vai no heartbeat e no poll (série da instância) e em `contexts.machine` de cada evento; só em Node |
|
|
106
107
|
| `heartbeat` | `boolean \| HeartbeatOptions` | `false` | heartbeat periódico |
|
|
107
108
|
| `tasks` | `boolean \| TasksOptions` | `false` | habilita a execução sob demanda (`true` usa defaults) |
|
|
108
109
|
| `beforeSend` | `(event) => event \| null` | — | edita/descarta evento (retorne `null` para descartar) |
|
|
@@ -120,6 +121,8 @@ O teto da fila do transport (200 itens; ao encher, o **mais antigo** é descarta
|
|
|
120
121
|
| `name` | `string` | o `instanceId` | nome amigável no dashboard |
|
|
121
122
|
| `metadata` | `Record<string,unknown>` | — | metadados anexados ao batimento |
|
|
122
123
|
|
|
124
|
+
Com `machineMetrics` (default) cada batimento também leva `machine` — um [MachineSnapshot](./protocol.md#machinesnapshot) da máquina.
|
|
125
|
+
|
|
123
126
|
### CaptureHint
|
|
124
127
|
|
|
125
128
|
| Campo | Tipo | Descrição |
|
package/docs/concepts.md
CHANGED
|
@@ -339,7 +339,7 @@ O que o torna especial é que ele é a identidade dos **dois** canais ao mesmo t
|
|
|
339
339
|
|
|
340
340
|
## Release e environment
|
|
341
341
|
|
|
342
|
-
**`release`** é a versão do seu programa (`robo-nfe@1.4.2`) e **`environment`** é o ambiente lógico
|
|
342
|
+
**`release`** é a versão do seu programa (`robo-nfe@1.4.2`) e **`environment`** é o ambiente lógico, um de quatro valores: `development`, `testing`, `staging` (homologação) e `production`. Os dois são anexados a **todo** item enviado: eventos e transactions — e o `environment` vai também na identidade da **instância**, pelo heartbeat e pelo poll.
|
|
343
343
|
|
|
344
344
|
Servem a duas perguntas concretas:
|
|
345
345
|
|
|
@@ -348,6 +348,10 @@ Servem a duas perguntas concretas:
|
|
|
348
348
|
|
|
349
349
|
`environment` default é `production`. Se você roda homologação sem definir isso, os dois ambientes se misturam na mesma issue — vale configurar no primeiro dia.
|
|
350
350
|
|
|
351
|
+
E não é só organização: é o `environment` que decide **quem é notificado**. Cada regra de alerta lista os ambientes em que dispara, e por padrão só produção — um erro de homologação não acorda a lista de plantão, e uma máquina de testes que desliga no fim do expediente não vira alerta de madrugada. Para ser avisado em outro ambiente, marque-o na regra em **Alertas**.
|
|
352
|
+
|
|
353
|
+
Valores antigos de texto livre (`prod`, `qa`, `homologacao`) continuam sendo aceitos — o servidor os classifica num dos quatro; o que ele não reconhece vira produção, para nunca silenciar um alerta por engano. O ambiente de uma instância também pode ser corrigido no app, na página dela: a partir daí ele ignora o que o robô declara, até você desfazer.
|
|
354
|
+
|
|
351
355
|
## Run
|
|
352
356
|
|
|
353
357
|
Uma **run** (execução) é um pedido concreto de trabalho criado no app: alguém preencheu o formulário da task, ou uma automação disparou, e agora existe uma solicitação esperando um agente pegar.
|
package/docs/protocol.md
CHANGED
|
@@ -44,6 +44,28 @@ Um `transaction` pode carregar `run_id`: é assim que a [transaction de uma run]
|
|
|
44
44
|
|
|
45
45
|
**Flush & retries:** o transport flusha por `flushIntervalMs` ou ao atingir `maxBatchSize`. Ladder de retry de 3 tentativas; respostas 4xx (exceto 429) são descartadas sem retry; a fila tem teto fixo e descarta os itens **mais antigos** ao encher. Todos os valores em [Tempos e intervalos](./api-reference.md#tempos-e-intervalos).
|
|
46
46
|
|
|
47
|
+
|
|
48
|
+
### MachineSnapshot
|
|
49
|
+
|
|
50
|
+
Recursos da máquina onde a instância roda. Vai em `HeartbeatPayload.machine`, em `instance.machine` do `POST /v1/tasks/poll` e em `contexts.machine` dos eventos. Bytes em bytes, percentuais 0..100; campo ausente = não mensurável nesta plataforma. Teto: **4 KiB** serializado (heartbeat/poll → 422; `contexts.machine` idem). Chaves desconhecidas são descartadas pelo servidor.
|
|
51
|
+
|
|
52
|
+
| Campo | Tipo | Descrição |
|
|
53
|
+
| --- | --- | --- |
|
|
54
|
+
| `sampled_at` | ISO 8601 | momento da coleta (relógio do cliente) — chave de dedupe da série |
|
|
55
|
+
| `instance_id` | string | o `instanceId` do `init()` — liga o snapshot de um evento à série da instância |
|
|
56
|
+
| `hostname`, `os`, `arch` | string | identificação da máquina (`process.platform` / `sys.platform`) |
|
|
57
|
+
| `cpu_count` | int | cores lógicos |
|
|
58
|
+
| `cpu_percent` | number \| null | uso de CPU do sistema — média entre duas coletas; `null` até haver 2 amostras |
|
|
59
|
+
| `load_1` | number | load average de 1 min (POSIX; ausente no Windows) |
|
|
60
|
+
| `mem_total_bytes`, `mem_available_bytes`, `mem_percent` | int, int, number | memória do sistema |
|
|
61
|
+
| `disk_path`, `disk_total_bytes`, `disk_free_bytes`, `disk_percent` | string, int, int, number | volume do diretório de trabalho do bot |
|
|
62
|
+
| `process.pid`, `process.uptime_s` | int, number | **obrigatórios** |
|
|
63
|
+
| `process.rss_bytes`, `process.cpu_percent` | int, number \| null | memória residente e CPU do processo (normalizada pelos cores) |
|
|
64
|
+
| `process.heap_used_bytes` / `process.threads` | int | só Node / só Python |
|
|
65
|
+
| `source` | `stdlib` \| `psutil` \| `stdlib-loadavg` | de onde vieram os números (`stdlib-loadavg` = CPU estimada pelo load, macOS sem psutil) |
|
|
66
|
+
|
|
67
|
+
O servidor guarda o último snapshot em `instances.machine` e um ponto por heartbeat/poll (máx. 1 a cada 30s por instância) em `instance_metrics`, expurgado em 14 dias.
|
|
68
|
+
|
|
47
69
|
## Tasks — polling e reporte
|
|
48
70
|
|
|
49
71
|
Dois endpoints sob `<baseUrl>/v1/tasks`, ambos com `Authorization: Bearer <clientSecret>` (a credencial única do agente):
|
|
@@ -59,6 +81,7 @@ Corpo `PollRequest`:
|
|
|
59
81
|
"name": "VM 01",
|
|
60
82
|
"version": "2.0.0",
|
|
61
83
|
"host": "vm-01",
|
|
84
|
+
"environment": "production", // ambiente da instância: development | testing | staging | production
|
|
62
85
|
"tasks": ["processar-nfe"]
|
|
63
86
|
},
|
|
64
87
|
"max": 1, // quantas reivindicar (1..5)
|
package/docs/telemetry.md
CHANGED
|
@@ -133,6 +133,17 @@ O primeiro batimento sai **na hora** em que o `init()` roda — não depois do p
|
|
|
133
133
|
|
|
134
134
|
Essa identidade é a mesma que o poll de tasks envia (`agent.instance_id`) — os dois canais derivam do `instanceId` do `init()`, então o robô aparece como **um agente só** no módulo Agentes automaticamente. Por isso, com `tasks: true` o heartbeat é **opcional** (o poll já marca a presença do agente); ele é essencial para agentes só de telemetria.
|
|
135
135
|
|
|
136
|
+
## Recursos da máquina (CPU, memória, disco)
|
|
137
|
+
|
|
138
|
+
Ligado por padrão em Node (`machineMetrics: true`), o SDK coleta CPU do sistema, memória, disco do volume do bot e RSS/CPU do próprio processo — **sem dependência nova** e sem timer próprio: a leitura pega carona em cada heartbeat e em cada poll de tasks (série da instância em **Instâncias → recursos da máquina**) e vai como `contexts.machine` em cada evento (card **"máquina no momento do erro"** no detalhe da issue). Assim dá para responder se o ambiente tem recurso suficiente e se um erro coincidiu com CPU/memória no limite.
|
|
139
|
+
|
|
140
|
+
```js
|
|
141
|
+
Hobots.init({ clientSecret, instanceId: 'vm-01', heartbeat: true }); // coleta ligada
|
|
142
|
+
Hobots.init({ clientSecret, instanceId: 'vm-01', machineMetrics: false }); // desliga
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
O snapshot tem ~600 bytes (teto do servidor: 4 KiB). Formato em [Protocolo → MachineSnapshot](./protocol.md#machinesnapshot).
|
|
146
|
+
|
|
136
147
|
## Flush e close
|
|
137
148
|
|
|
138
149
|
Nada é enviado na hora: cada evento, transaction e heartbeat entra numa **fila em memória** e sai em lote. É por isso que essas duas funções existem — quando o processo morre, a fila morre com ele. Conceito: [Fila, flush e close](./concepts.md#fila-flush-e-close).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hobots",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.4.0",
|
|
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,
|
|
@@ -31,7 +31,8 @@
|
|
|
31
31
|
"build": "tsup",
|
|
32
32
|
"dev": "tsup --watch",
|
|
33
33
|
"lint": "eslint . --max-warnings 0",
|
|
34
|
-
"test": "
|
|
34
|
+
"test": "vitest run",
|
|
35
|
+
"test:watch": "vitest",
|
|
35
36
|
"typecheck": "tsc --noEmit"
|
|
36
37
|
},
|
|
37
38
|
"devDependencies": {
|
|
@@ -39,6 +40,7 @@
|
|
|
39
40
|
"@workspace/eslint-config": "workspace:*",
|
|
40
41
|
"@workspace/typescript-config": "workspace:*",
|
|
41
42
|
"tsup": "^8.4.0",
|
|
42
|
-
"typescript": "5.7.3"
|
|
43
|
+
"typescript": "5.7.3",
|
|
44
|
+
"vitest": "^4.1.10"
|
|
43
45
|
}
|
|
44
46
|
}
|