hobots 2.0.1 → 2.2.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 +19 -0
- package/dist/index.cjs +83 -3
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +22 -2
- package/dist/index.d.ts +22 -2
- package/dist/index.js +83 -3
- package/dist/index.js.map +1 -1
- package/dist/protocol.cjs.map +1 -1
- package/dist/protocol.d.cts +13 -1
- package/dist/protocol.d.ts +13 -1
- package/docs/api-reference.md +10 -0
- package/docs/protocol.md +3 -1
- package/docs/tasks.md +38 -0
- package/package.json +1 -1
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 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?: string;\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?: string;\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}\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":[]}
|
|
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?: string;\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?: string;\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}\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
|
@@ -68,6 +68,16 @@ interface RunError {
|
|
|
68
68
|
message: string;
|
|
69
69
|
stack?: string;
|
|
70
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* Progresso declarado pelo bot via `ctx.progress` — snapshot absoluto (o servidor
|
|
73
|
+
* sobrescreve, não soma). Opcional: sem ele a plataforma não mostra barra nem ETA.
|
|
74
|
+
*/
|
|
75
|
+
interface RunProgress {
|
|
76
|
+
/** itens já processados (0..total) */
|
|
77
|
+
current: number;
|
|
78
|
+
/** total de itens previsto (>= 1) */
|
|
79
|
+
total: number;
|
|
80
|
+
}
|
|
71
81
|
/** PATCH /v1/tasks/runs/{id} — 'running' pode repetir com logs incrementais */
|
|
72
82
|
interface RunUpdateRequest {
|
|
73
83
|
status: RunUpdateStatus;
|
|
@@ -75,6 +85,8 @@ interface RunUpdateRequest {
|
|
|
75
85
|
error?: RunError;
|
|
76
86
|
/** Delta desde o último envio — o servidor concatena */
|
|
77
87
|
logs?: RunLogEntry[];
|
|
88
|
+
/** Snapshot mais recente de `ctx.progress` — pega carona no PATCH que sair (≤ 1/s) */
|
|
89
|
+
progress?: RunProgress;
|
|
78
90
|
}
|
|
79
91
|
interface RunUpdateResponse {
|
|
80
92
|
ok: true;
|
|
@@ -269,4 +281,4 @@ interface Envelope {
|
|
|
269
281
|
items: EnvelopeItem[];
|
|
270
282
|
}
|
|
271
283
|
|
|
272
|
-
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, RunStatus, RunUpdateRequest, RunUpdateResponse, RunUpdateStatus, StackFrame, StepData, StepStatus, TransactionPayload };
|
|
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 };
|
package/dist/protocol.d.ts
CHANGED
|
@@ -68,6 +68,16 @@ interface RunError {
|
|
|
68
68
|
message: string;
|
|
69
69
|
stack?: string;
|
|
70
70
|
}
|
|
71
|
+
/**
|
|
72
|
+
* Progresso declarado pelo bot via `ctx.progress` — snapshot absoluto (o servidor
|
|
73
|
+
* sobrescreve, não soma). Opcional: sem ele a plataforma não mostra barra nem ETA.
|
|
74
|
+
*/
|
|
75
|
+
interface RunProgress {
|
|
76
|
+
/** itens já processados (0..total) */
|
|
77
|
+
current: number;
|
|
78
|
+
/** total de itens previsto (>= 1) */
|
|
79
|
+
total: number;
|
|
80
|
+
}
|
|
71
81
|
/** PATCH /v1/tasks/runs/{id} — 'running' pode repetir com logs incrementais */
|
|
72
82
|
interface RunUpdateRequest {
|
|
73
83
|
status: RunUpdateStatus;
|
|
@@ -75,6 +85,8 @@ interface RunUpdateRequest {
|
|
|
75
85
|
error?: RunError;
|
|
76
86
|
/** Delta desde o último envio — o servidor concatena */
|
|
77
87
|
logs?: RunLogEntry[];
|
|
88
|
+
/** Snapshot mais recente de `ctx.progress` — pega carona no PATCH que sair (≤ 1/s) */
|
|
89
|
+
progress?: RunProgress;
|
|
78
90
|
}
|
|
79
91
|
interface RunUpdateResponse {
|
|
80
92
|
ok: true;
|
|
@@ -269,4 +281,4 @@ interface Envelope {
|
|
|
269
281
|
items: EnvelopeItem[];
|
|
270
282
|
}
|
|
271
283
|
|
|
272
|
-
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, RunStatus, RunUpdateRequest, RunUpdateResponse, RunUpdateStatus, StackFrame, StepData, StepStatus, TransactionPayload };
|
|
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 };
|
package/docs/api-reference.md
CHANGED
|
@@ -169,6 +169,7 @@ interface RunContext {
|
|
|
169
169
|
task: string;
|
|
170
170
|
log: RunLogger; // ctx.log.debug/info/warn/error/success(message)
|
|
171
171
|
items: RunItems; // ctx.items.add/succeeded/failed/occurrence — a entrega do bot
|
|
172
|
+
progress: RunProgressReporter; // ctx.progress.total/advance/set — barra + tempo restante (opcional)
|
|
172
173
|
tx: Transaction; // transaction desta run — correlacionada e finalizada pelo SDK
|
|
173
174
|
signal: AbortSignal;
|
|
174
175
|
throwIfCanceled(): void; // lança RunCanceled se o signal já disparou
|
|
@@ -181,11 +182,20 @@ interface RunItems {
|
|
|
181
182
|
failed(message: string, payload?: Record<string, unknown>, options?: { id?: string }): void;
|
|
182
183
|
occurrence(message: string, payload?: Record<string, unknown>, options?: { id?: string }): void;
|
|
183
184
|
}
|
|
185
|
+
|
|
186
|
+
interface RunProgressReporter {
|
|
187
|
+
total(total: number): void; // declara/ajusta o total de itens (inteiro >= 1; idempotente)
|
|
188
|
+
advance(count?: number): void; // incrementa os processados (padrão 1; clampa em total)
|
|
189
|
+
set(current: number, total?: number): void; // valor absoluto
|
|
190
|
+
readonly current: number;
|
|
191
|
+
readonly snapshot: RunProgress | null; // { current, total } ou null sem total declarado
|
|
192
|
+
}
|
|
184
193
|
```
|
|
185
194
|
|
|
186
195
|
- **`runId` / `task`** — identificam a execução; úteis para correlacionar com os seus próprios logs.
|
|
187
196
|
- **`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).
|
|
188
197
|
- **`items.<status>(…)`** — registra um item processado/gerado pela execução (síncrono, bufferizado, lotes de até 500). `id` opcional = idempotência dentro da run. Guia: [Itens de execução](./tasks.md#itens-de-execução-ctxitems).
|
|
198
|
+
- **`progress.total(n)` / `progress.advance()` / `progress.set(c, t?)`** — progresso declarado da run (itens processados / total), opcional e independente de `items`; o app mostra barra, percentual e tempo restante. Síncrono; o snapshot pega carona nos PATCHes de log e sai no máximo 1×/s por conta própria. Guia: [Progresso da execução](./tasks.md#progresso-da-execução-ctxprogress).
|
|
189
199
|
- **`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.
|
|
190
200
|
- **`signal`** — `AbortSignal` que dispara em cancelamento no app, timeout ou shutdown.
|
|
191
201
|
- **`throwIfCanceled()`** — o ponto de parada de uma linha: lança `RunCanceled` se o `signal` já disparou.
|
package/docs/protocol.md
CHANGED
|
@@ -84,11 +84,13 @@ Corpo `RunUpdateRequest`:
|
|
|
84
84
|
{ "ts": "…", "level": "info", "message": "portal após o login",
|
|
85
85
|
"attachments": ["<32 hex>"] } // opcional; ids de anexo (máx. 4)
|
|
86
86
|
],
|
|
87
|
-
"error": { "type": "Error", "message": "…", "stack": "…" } // só com 'failed'
|
|
87
|
+
"error": { "type": "Error", "message": "…", "stack": "…" }, // só com 'failed'
|
|
88
|
+
"progress": { "current": 10, "total": 100 } // opcional (SDK ≥ 2.1): snapshot de ctx.progress
|
|
88
89
|
}
|
|
89
90
|
```
|
|
90
91
|
|
|
91
92
|
- `status: 'running'` pode repetir para enviar **logs incrementais** (throttle por `logFlushIntervalMs`, flush ao acumular 20, chunk de 100, teto de 1000 logs/run, mensagem cap 10k).
|
|
93
|
+
- `progress` é **opcional** e aditivo (SDK ≥ 2.1): snapshot absoluto de `ctx.progress` (`current` 0..total, `total` ≥ 1) — o servidor **sobrescreve** `progress_current`/`progress_total` e grava `progress_started_at` no primeiro PATCH que o traga (relógio do servidor; âncora da ETA no app). `current > total` é clampado; progresso enviado a uma run já terminal é descartado. O SDK anexa o snapshot mais recente a **qualquer** PATCH que saia (logs, heartbeat, terminal) e só dispara um PATCH próprio, no máximo 1/s, quando nada mais está a caminho. Uma API anterior ao recurso descarta o campo (objeto não-strict).
|
|
92
94
|
- `attachments` é **opcional** e aditivo: SDKs anteriores à 1.9 simplesmente não enviam o campo, e uma API anterior ao recurso descarta o campo na validação (objeto não-strict) sem rejeitar o PATCH. Os ids são gerados pelo agente **antes** do upload, o que permite enviar a linha de log sem esperar o binário subir.
|
|
93
95
|
- Ordem garantida `running → logs → terminal` (PATCHes serializados numa cadeia de promise).
|
|
94
96
|
- Retry `[1s, 4s, 16s]`; 4xx exceto 429 é terminal (**409** = run cancelada / transição inválida → marca a run como morta e dispara `ctx.signal`).
|
package/docs/tasks.md
CHANGED
|
@@ -130,6 +130,44 @@ Diferente de logs e status, **uma run cancelada continua aceitando itens**: item
|
|
|
130
130
|
|
|
131
131
|
> **Dados sensíveis:** como os logs, `message` e `payload` **são enviados ao servidor** e ficam visíveis na solicitação. Não inclua senhas, tokens ou dados pessoais desnecessários.
|
|
132
132
|
|
|
133
|
+
## Progresso da execução (`ctx.progress`)
|
|
134
|
+
|
|
135
|
+
Itens contam **o que** foi entregue; progresso conta **quanto falta**. Quando a run percorre uma lista de tamanho conhecido, declare o total e avance a cada item — a solicitação no app mostra barra, percentual (`10/100 · 10%`) e **tempo restante estimado** (calculado pela taxa média desde o primeiro reporte).
|
|
136
|
+
|
|
137
|
+
```js
|
|
138
|
+
Hobots.register('baixar-notas', async (params, ctx) => {
|
|
139
|
+
const notas = await listarNotas(params);
|
|
140
|
+
ctx.progress.total(notas.length); // antes do loop
|
|
141
|
+
for (const nota of notas) {
|
|
142
|
+
await baixar(nota);
|
|
143
|
+
ctx.progress.advance(); // a cada item
|
|
144
|
+
}
|
|
145
|
+
});
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
### API
|
|
149
|
+
|
|
150
|
+
```ts
|
|
151
|
+
interface RunProgressReporter {
|
|
152
|
+
total(total: number): void; // declara/ajusta o total (inteiro >= 1; idempotente)
|
|
153
|
+
advance(count?: number): void; // incrementa os processados (padrão 1; clampa em total)
|
|
154
|
+
set(current: number, total?: number): void; // valor absoluto (ex.: retomada de um lote)
|
|
155
|
+
readonly current: number; // processados até agora
|
|
156
|
+
readonly snapshot: { current: number; total: number } | null; // null sem total declarado
|
|
157
|
+
}
|
|
158
|
+
```
|
|
159
|
+
|
|
160
|
+
- **Opcional** — sem `total()` nada é enviado e a UI não mostra barra nem estimativa. `advance()` antes do `total()` só guarda o contador.
|
|
161
|
+
- **Independente de `ctx.items`** — use um, outro ou ambos; nenhum avança o outro (um item pode gerar vários registros, ou nenhum).
|
|
162
|
+
- **Total inválido** (`0`, negativo, não-inteiro) é ignorado com um aviso único no terminal.
|
|
163
|
+
- **Semântica de snapshot** — o servidor sobrescreve `current`/`total` com o último valor recebido; não há soma. Ajustar o `total` no meio da run (a lista cresceu) é permitido.
|
|
164
|
+
|
|
165
|
+
### Como funciona (e por que não gera tráfego)
|
|
166
|
+
|
|
167
|
+
As chamadas são **síncronas e baratas**: o snapshot mais recente pega carona em **qualquer** PATCH que saia — logs incrementais, heartbeat de cancelamento, reporte terminal. Só quando nada mais está a caminho o SDK dispara um PATCH `running` próprio, no máximo **1 por segundo**. `advance()` num loop de 10.000 itens em 5 segundos gera ~5 PATCHes, não 10.000. O PATCH terminal (`succeeded`/`failed`) **sempre** leva o valor final — uma run que falhou aparece como `87/100`.
|
|
168
|
+
|
|
169
|
+
O servidor grava `progress_started_at` no primeiro PATCH com progresso (relógio do servidor) — é a âncora da estimativa de término, calculada no app: `restante = decorrido × (total − current) ÷ current`.
|
|
170
|
+
|
|
133
171
|
## Anexos (screenshots)
|
|
134
172
|
|
|
135
173
|
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.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hobots",
|
|
3
|
-
"version": "2.0
|
|
3
|
+
"version": "2.2.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,
|