@zihin/agent-client 0.6.0 → 0.6.1
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 +37 -0
- package/dist/index.d.mts +59 -2
- package/dist/index.d.ts +59 -2
- package/dist/index.js +87 -1
- package/dist/index.mjs +87 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -111,6 +111,43 @@ gera **outra** sessão, e a ordem dos campos entra no hash. Chave repetida nos d
|
|
|
111
111
|
`bindings`. Campo do `sessionFrom` que a redação alterou (no `context`) é recusado com
|
|
112
112
|
`VALIDATION_ERROR` (sai como `config`): mande-o em `bindings`.
|
|
113
113
|
|
|
114
|
+
### Nome do contato e sugestões de resposta (0.6.1)
|
|
115
|
+
|
|
116
|
+
> Backend: zihin-agent-builder `1aa752e6` (+ migration `20261001000002`). Contra um backend
|
|
117
|
+
> anterior os dois recursos só não acontecem: o turno roda normalmente.
|
|
118
|
+
|
|
119
|
+
```ts
|
|
120
|
+
const r = await zihin.invokeAgent({
|
|
121
|
+
agentId,
|
|
122
|
+
message: 'Quero canetas azuis',
|
|
123
|
+
consumer: { key: 'dev-cotai-1410', name: 'Fernando Produtor' }, // nome aparece nos contatos do console
|
|
124
|
+
capabilities: { blocks: ['quick_replies'] }, // minha tela mostra sugestões
|
|
125
|
+
});
|
|
126
|
+
r.suggestions; // ['Caneta A', 'Caneta B'] — ou undefined quando o agente não sugeriu
|
|
127
|
+
```
|
|
128
|
+
|
|
129
|
+
- **`consumer: { key, name? }`** é o `consumerKey` com o nome junto. `consumer.key` e `consumerKey`
|
|
130
|
+
são o mesmo campo (mande um; se vierem os dois, têm de ser iguais) e seguem a mesma regra: só
|
|
131
|
+
valem sob API key admin/owner, e o núcleo recusa o turno se o servidor os ignorar. O nome vai como
|
|
132
|
+
`consumer_display_name` (até 255 caracteres) e vale **do presente em diante**: atualiza o
|
|
133
|
+
contato e a conversa em andamento; conversas encerradas guardam o nome da época (o histórico não
|
|
134
|
+
é reescrito). Dado pessoal: mande só o que a operação precisa ver.
|
|
135
|
+
- **Uma `consumer.key` por pessoa.** A chave é a identidade: memória, bloqueio e engajamento são
|
|
136
|
+
dela. Se várias pessoas usam o mesmo canal (ex.: um WhatsApp comercial que troca de vendedor),
|
|
137
|
+
dê a cada uma a sua chave — trocar só o `name` não separa as pessoas.
|
|
138
|
+
- **`capabilities: { blocks: ['quick_replies'] }`** diz que a sua tela renderiza sugestões de
|
|
139
|
+
resposta. Sem declarar, o agente nem recebe a ferramenta — nada é gerado e nada é cobrado. É um
|
|
140
|
+
**pedido**, não uma exigência: qualquer API key pode mandar, e um servidor que não o conheça só o
|
|
141
|
+
reporta em `ignoredFields` (o turno não falha). O dono do agente pode desligar as sugestões
|
|
142
|
+
(`quick_replies_enabled`), e o agente decide quando vale sugerir — nem todo turno traz.
|
|
143
|
+
- **`suggestions`** (em `AgentResult` e no chunk `response`) são os rótulos do bloco `quick_replies`
|
|
144
|
+
de `blocks`, já filtrados: até 4, curtos. Tocar uma sugestão = mandar o texto dela como a próxima
|
|
145
|
+
`message`. Num turno só com sugestões, `content` vem **vazio**.
|
|
146
|
+
- **Descontinuados**: `options.jitMode`, `options.temperature` e `options.maxTokens` não têm efeito no
|
|
147
|
+
`/stream` (temperatura e teto de saída são configuração do agente). Continuam sendo enviados e o
|
|
148
|
+
servidor os lista em `ignoredFields`; o núcleo emite um `ZihinDeprecationWarning` **uma vez por
|
|
149
|
+
processo** (`ZIHIN_DEP001`/`ZIHIN_DEP002`). Saem do SDK na 1.0.
|
|
150
|
+
|
|
114
151
|
## Uso — caminho assíncrono (triggers)
|
|
115
152
|
|
|
116
153
|
```ts
|
package/dist/index.d.mts
CHANGED
|
@@ -118,7 +118,17 @@ interface Attachment {
|
|
|
118
118
|
type: AttachmentType;
|
|
119
119
|
}
|
|
120
120
|
interface InvokeOptions {
|
|
121
|
+
/**
|
|
122
|
+
* @deprecated Sem efeito: o `/stream` usa a temperatura da configuração do agente
|
|
123
|
+
* (`llm_config.temperature`, no console ou via `update_agent`). O servidor ignora o campo e o
|
|
124
|
+
* reporta em `ignoredFields`. Será retirado do SDK na 1.0.
|
|
125
|
+
*/
|
|
121
126
|
temperature?: number;
|
|
127
|
+
/**
|
|
128
|
+
* @deprecated Sem efeito: o teto de saída é a configuração do agente (`llm_config.max_tokens`,
|
|
129
|
+
* no console ou via `update_agent`). O servidor ignora o campo e o reporta em `ignoredFields`.
|
|
130
|
+
* Será retirado do SDK na 1.0.
|
|
131
|
+
*/
|
|
122
132
|
maxTokens?: number;
|
|
123
133
|
/**
|
|
124
134
|
* Teto do TURNO desta chamada (ms); sobrepõe o do cliente. Vai ao BE como `options.timeout_ms`
|
|
@@ -130,9 +140,41 @@ interface InvokeOptions {
|
|
|
130
140
|
* local soma `DEADLINE_GRACE_MS` a este valor para ainda receber o desfecho do servidor.
|
|
131
141
|
*/
|
|
132
142
|
timeoutMs?: number;
|
|
133
|
-
/**
|
|
143
|
+
/**
|
|
144
|
+
* @deprecated Recurso descontinuado no servidor (ago/2026): sem efeito, reportado em
|
|
145
|
+
* `ignoredFields`. Remova-o. Será retirado do SDK na 1.0.
|
|
146
|
+
*/
|
|
134
147
|
jitMode?: boolean;
|
|
135
148
|
}
|
|
149
|
+
/** Blocos estruturados que a sua interface sabe renderizar (`capabilities.blocks`). */
|
|
150
|
+
type ClientBlockType = 'quick_replies';
|
|
151
|
+
/**
|
|
152
|
+
* O que a SUA tela sabe mostrar. O agente só oferece o que você declarar — sem declarar, nada é
|
|
153
|
+
* gerado e nada é cobrado. Não exige privilégio de API key.
|
|
154
|
+
*/
|
|
155
|
+
interface ClientCapabilities {
|
|
156
|
+
/**
|
|
157
|
+
* `quick_replies`: até 4 sugestões curtas de resposta ao fim do turno (o usuário toca e o texto
|
|
158
|
+
* vira a próxima mensagem). Chegam em `AgentResult.suggestions` (e no bloco `quick_replies` de
|
|
159
|
+
* `blocks`). O dono do agente pode desligá-las (`quick_replies_enabled`); o agente decide quando
|
|
160
|
+
* vale sugerir — nem todo turno traz sugestões.
|
|
161
|
+
*/
|
|
162
|
+
blocks?: ClientBlockType[];
|
|
163
|
+
}
|
|
164
|
+
/** A pessoa do outro lado da conversa. Só vale sob API key **admin/owner**. */
|
|
165
|
+
interface ConsumerIdentity {
|
|
166
|
+
/**
|
|
167
|
+
* Identificador estável da pessoa no SEU sistema (memória por pessoa, denylist, gate de
|
|
168
|
+
* engajamento). Para continuar conversas que um webhook já gravava, use o MESMO valor que o
|
|
169
|
+
* webhook usava. Enviado como `consumer_key`.
|
|
170
|
+
*/
|
|
171
|
+
key: string;
|
|
172
|
+
/**
|
|
173
|
+
* Nome para exibição no console da Zihin (lista de contatos). Enviado como
|
|
174
|
+
* `consumer_display_name`. Dado pessoal: mande só o que a operação precisa ver.
|
|
175
|
+
*/
|
|
176
|
+
name?: string;
|
|
177
|
+
}
|
|
136
178
|
interface InvokeAgentParams {
|
|
137
179
|
/** UUID do agente (path :agent_id). */
|
|
138
180
|
agentId: string;
|
|
@@ -148,6 +190,13 @@ interface InvokeAgentParams {
|
|
|
148
190
|
* valor que o webhook usava. Enviado como `consumer_key`.
|
|
149
191
|
*/
|
|
150
192
|
consumerKey?: string;
|
|
193
|
+
/**
|
|
194
|
+
* A pessoa do outro lado: `{ key, name? }`. `consumer.key` é o mesmo que `consumerKey` (use um
|
|
195
|
+
* dos dois; se vierem os dois, têm de ser iguais). Só vale sob API key admin/owner.
|
|
196
|
+
*/
|
|
197
|
+
consumer?: ConsumerIdentity;
|
|
198
|
+
/** O que a sua interface sabe renderizar — ex.: `{ blocks: ['quick_replies'] }`. */
|
|
199
|
+
capabilities?: ClientCapabilities;
|
|
151
200
|
/**
|
|
152
201
|
* Contexto estruturado que o **modelo lê** — bloco de plataforma junto da mensagem do usuário
|
|
153
202
|
* (não no system prompt). **Fica gravado** com a mensagem (`declared_context`) e se repete em
|
|
@@ -228,6 +277,12 @@ interface AgentResult {
|
|
|
228
277
|
type: string;
|
|
229
278
|
[k: string]: unknown;
|
|
230
279
|
}>;
|
|
280
|
+
/**
|
|
281
|
+
* Sugestões de resposta do turno (bloco `quick_replies`), já extraídas de `blocks`. Só vêm se
|
|
282
|
+
* você declarou `capabilities: { blocks: ['quick_replies'] }`. O texto de cada uma é o que o
|
|
283
|
+
* usuário "diz" ao tocá-la. Num turno só com sugestões, `content` vem vazio.
|
|
284
|
+
*/
|
|
285
|
+
suggestions?: string[];
|
|
231
286
|
iterations?: number;
|
|
232
287
|
executionTimeMs?: number;
|
|
233
288
|
/** `execution_id` do turno (evento `metrics`) — handle de correlação no console/telemetria. */
|
|
@@ -377,6 +432,8 @@ type AgentStreamChunk =
|
|
|
377
432
|
type: string;
|
|
378
433
|
[k: string]: unknown;
|
|
379
434
|
}>;
|
|
435
|
+
/** Sugestões de resposta (bloco `quick_replies`), extraídas de `blocks`. */
|
|
436
|
+
suggestions?: string[];
|
|
380
437
|
/** Resposta ENLATADA de um gate (handoff humano, denylist, sessão suspensa) — não do agente. */
|
|
381
438
|
gated?: boolean;
|
|
382
439
|
data: unknown;
|
|
@@ -965,4 +1022,4 @@ declare function signRequest(payload: string, secretKey: string, timestamp?: num
|
|
|
965
1022
|
*/
|
|
966
1023
|
declare const MAX_TASK_PAYLOAD_BYTES: number;
|
|
967
1024
|
|
|
968
|
-
export { type AgentOutcome, type AgentResult, type AgentStreamChunk, type AgentSummary, type Attachment, type AttachmentType, type CancelTaskParams, type CancelTaskResult, type ContextValue, type CreateTriggerParams, DEADLINE_GRACE_MS, DEFAULT_LIMITS, type DelegateTaskParams, type DeleteTriggerParams, type DispatchAgentParams, type DispatchResult, type ExecutionStatus, type FindOrCreateResult, type GetExecutionParams, type GetTaskParams, type GetTriggerParams, type IgnoredField, type InvokeAgentParams, type InvokeOptions, type ListTasksParams, type ListTriggersParams, MAX_TASK_PAYLOAD_BYTES, OPERATION_TIMEOUT_MS, type QueryExtraction, type ResponseTransformMode, type RetryInfo, type SignedRequestHeaders, type Source, type TaskDossier, type TaskExecution, type TaskInfo, type TaskListPage, type TimeoutClock, type TimeoutOperation, type TriggerInfo, type TriggerMode, type TriggerRef, type UpdateTriggerParams, type Usage, ZihinAgentClient, ZihinAgentError, type ZihinClientConfig, type ZihinErrorKind, classifyStreamErrorKind, createClient, errorFromDoneChunk, errorFromStreamChunk, isCommercialBlock, sanitizeApiError, signRequest, validateApiKeyFormat, validateBaseUrl, validatePromptSize };
|
|
1025
|
+
export { type AgentOutcome, type AgentResult, type AgentStreamChunk, type AgentSummary, type Attachment, type AttachmentType, type CancelTaskParams, type CancelTaskResult, type ClientBlockType, type ClientCapabilities, type ConsumerIdentity, type ContextValue, type CreateTriggerParams, DEADLINE_GRACE_MS, DEFAULT_LIMITS, type DelegateTaskParams, type DeleteTriggerParams, type DispatchAgentParams, type DispatchResult, type ExecutionStatus, type FindOrCreateResult, type GetExecutionParams, type GetTaskParams, type GetTriggerParams, type IgnoredField, type InvokeAgentParams, type InvokeOptions, type ListTasksParams, type ListTriggersParams, MAX_TASK_PAYLOAD_BYTES, OPERATION_TIMEOUT_MS, type QueryExtraction, type ResponseTransformMode, type RetryInfo, type SignedRequestHeaders, type Source, type TaskDossier, type TaskExecution, type TaskInfo, type TaskListPage, type TimeoutClock, type TimeoutOperation, type TriggerInfo, type TriggerMode, type TriggerRef, type UpdateTriggerParams, type Usage, ZihinAgentClient, ZihinAgentError, type ZihinClientConfig, type ZihinErrorKind, classifyStreamErrorKind, createClient, errorFromDoneChunk, errorFromStreamChunk, isCommercialBlock, sanitizeApiError, signRequest, validateApiKeyFormat, validateBaseUrl, validatePromptSize };
|
package/dist/index.d.ts
CHANGED
|
@@ -118,7 +118,17 @@ interface Attachment {
|
|
|
118
118
|
type: AttachmentType;
|
|
119
119
|
}
|
|
120
120
|
interface InvokeOptions {
|
|
121
|
+
/**
|
|
122
|
+
* @deprecated Sem efeito: o `/stream` usa a temperatura da configuração do agente
|
|
123
|
+
* (`llm_config.temperature`, no console ou via `update_agent`). O servidor ignora o campo e o
|
|
124
|
+
* reporta em `ignoredFields`. Será retirado do SDK na 1.0.
|
|
125
|
+
*/
|
|
121
126
|
temperature?: number;
|
|
127
|
+
/**
|
|
128
|
+
* @deprecated Sem efeito: o teto de saída é a configuração do agente (`llm_config.max_tokens`,
|
|
129
|
+
* no console ou via `update_agent`). O servidor ignora o campo e o reporta em `ignoredFields`.
|
|
130
|
+
* Será retirado do SDK na 1.0.
|
|
131
|
+
*/
|
|
122
132
|
maxTokens?: number;
|
|
123
133
|
/**
|
|
124
134
|
* Teto do TURNO desta chamada (ms); sobrepõe o do cliente. Vai ao BE como `options.timeout_ms`
|
|
@@ -130,9 +140,41 @@ interface InvokeOptions {
|
|
|
130
140
|
* local soma `DEADLINE_GRACE_MS` a este valor para ainda receber o desfecho do servidor.
|
|
131
141
|
*/
|
|
132
142
|
timeoutMs?: number;
|
|
133
|
-
/**
|
|
143
|
+
/**
|
|
144
|
+
* @deprecated Recurso descontinuado no servidor (ago/2026): sem efeito, reportado em
|
|
145
|
+
* `ignoredFields`. Remova-o. Será retirado do SDK na 1.0.
|
|
146
|
+
*/
|
|
134
147
|
jitMode?: boolean;
|
|
135
148
|
}
|
|
149
|
+
/** Blocos estruturados que a sua interface sabe renderizar (`capabilities.blocks`). */
|
|
150
|
+
type ClientBlockType = 'quick_replies';
|
|
151
|
+
/**
|
|
152
|
+
* O que a SUA tela sabe mostrar. O agente só oferece o que você declarar — sem declarar, nada é
|
|
153
|
+
* gerado e nada é cobrado. Não exige privilégio de API key.
|
|
154
|
+
*/
|
|
155
|
+
interface ClientCapabilities {
|
|
156
|
+
/**
|
|
157
|
+
* `quick_replies`: até 4 sugestões curtas de resposta ao fim do turno (o usuário toca e o texto
|
|
158
|
+
* vira a próxima mensagem). Chegam em `AgentResult.suggestions` (e no bloco `quick_replies` de
|
|
159
|
+
* `blocks`). O dono do agente pode desligá-las (`quick_replies_enabled`); o agente decide quando
|
|
160
|
+
* vale sugerir — nem todo turno traz sugestões.
|
|
161
|
+
*/
|
|
162
|
+
blocks?: ClientBlockType[];
|
|
163
|
+
}
|
|
164
|
+
/** A pessoa do outro lado da conversa. Só vale sob API key **admin/owner**. */
|
|
165
|
+
interface ConsumerIdentity {
|
|
166
|
+
/**
|
|
167
|
+
* Identificador estável da pessoa no SEU sistema (memória por pessoa, denylist, gate de
|
|
168
|
+
* engajamento). Para continuar conversas que um webhook já gravava, use o MESMO valor que o
|
|
169
|
+
* webhook usava. Enviado como `consumer_key`.
|
|
170
|
+
*/
|
|
171
|
+
key: string;
|
|
172
|
+
/**
|
|
173
|
+
* Nome para exibição no console da Zihin (lista de contatos). Enviado como
|
|
174
|
+
* `consumer_display_name`. Dado pessoal: mande só o que a operação precisa ver.
|
|
175
|
+
*/
|
|
176
|
+
name?: string;
|
|
177
|
+
}
|
|
136
178
|
interface InvokeAgentParams {
|
|
137
179
|
/** UUID do agente (path :agent_id). */
|
|
138
180
|
agentId: string;
|
|
@@ -148,6 +190,13 @@ interface InvokeAgentParams {
|
|
|
148
190
|
* valor que o webhook usava. Enviado como `consumer_key`.
|
|
149
191
|
*/
|
|
150
192
|
consumerKey?: string;
|
|
193
|
+
/**
|
|
194
|
+
* A pessoa do outro lado: `{ key, name? }`. `consumer.key` é o mesmo que `consumerKey` (use um
|
|
195
|
+
* dos dois; se vierem os dois, têm de ser iguais). Só vale sob API key admin/owner.
|
|
196
|
+
*/
|
|
197
|
+
consumer?: ConsumerIdentity;
|
|
198
|
+
/** O que a sua interface sabe renderizar — ex.: `{ blocks: ['quick_replies'] }`. */
|
|
199
|
+
capabilities?: ClientCapabilities;
|
|
151
200
|
/**
|
|
152
201
|
* Contexto estruturado que o **modelo lê** — bloco de plataforma junto da mensagem do usuário
|
|
153
202
|
* (não no system prompt). **Fica gravado** com a mensagem (`declared_context`) e se repete em
|
|
@@ -228,6 +277,12 @@ interface AgentResult {
|
|
|
228
277
|
type: string;
|
|
229
278
|
[k: string]: unknown;
|
|
230
279
|
}>;
|
|
280
|
+
/**
|
|
281
|
+
* Sugestões de resposta do turno (bloco `quick_replies`), já extraídas de `blocks`. Só vêm se
|
|
282
|
+
* você declarou `capabilities: { blocks: ['quick_replies'] }`. O texto de cada uma é o que o
|
|
283
|
+
* usuário "diz" ao tocá-la. Num turno só com sugestões, `content` vem vazio.
|
|
284
|
+
*/
|
|
285
|
+
suggestions?: string[];
|
|
231
286
|
iterations?: number;
|
|
232
287
|
executionTimeMs?: number;
|
|
233
288
|
/** `execution_id` do turno (evento `metrics`) — handle de correlação no console/telemetria. */
|
|
@@ -377,6 +432,8 @@ type AgentStreamChunk =
|
|
|
377
432
|
type: string;
|
|
378
433
|
[k: string]: unknown;
|
|
379
434
|
}>;
|
|
435
|
+
/** Sugestões de resposta (bloco `quick_replies`), extraídas de `blocks`. */
|
|
436
|
+
suggestions?: string[];
|
|
380
437
|
/** Resposta ENLATADA de um gate (handoff humano, denylist, sessão suspensa) — não do agente. */
|
|
381
438
|
gated?: boolean;
|
|
382
439
|
data: unknown;
|
|
@@ -965,4 +1022,4 @@ declare function signRequest(payload: string, secretKey: string, timestamp?: num
|
|
|
965
1022
|
*/
|
|
966
1023
|
declare const MAX_TASK_PAYLOAD_BYTES: number;
|
|
967
1024
|
|
|
968
|
-
export { type AgentOutcome, type AgentResult, type AgentStreamChunk, type AgentSummary, type Attachment, type AttachmentType, type CancelTaskParams, type CancelTaskResult, type ContextValue, type CreateTriggerParams, DEADLINE_GRACE_MS, DEFAULT_LIMITS, type DelegateTaskParams, type DeleteTriggerParams, type DispatchAgentParams, type DispatchResult, type ExecutionStatus, type FindOrCreateResult, type GetExecutionParams, type GetTaskParams, type GetTriggerParams, type IgnoredField, type InvokeAgentParams, type InvokeOptions, type ListTasksParams, type ListTriggersParams, MAX_TASK_PAYLOAD_BYTES, OPERATION_TIMEOUT_MS, type QueryExtraction, type ResponseTransformMode, type RetryInfo, type SignedRequestHeaders, type Source, type TaskDossier, type TaskExecution, type TaskInfo, type TaskListPage, type TimeoutClock, type TimeoutOperation, type TriggerInfo, type TriggerMode, type TriggerRef, type UpdateTriggerParams, type Usage, ZihinAgentClient, ZihinAgentError, type ZihinClientConfig, type ZihinErrorKind, classifyStreamErrorKind, createClient, errorFromDoneChunk, errorFromStreamChunk, isCommercialBlock, sanitizeApiError, signRequest, validateApiKeyFormat, validateBaseUrl, validatePromptSize };
|
|
1025
|
+
export { type AgentOutcome, type AgentResult, type AgentStreamChunk, type AgentSummary, type Attachment, type AttachmentType, type CancelTaskParams, type CancelTaskResult, type ClientBlockType, type ClientCapabilities, type ConsumerIdentity, type ContextValue, type CreateTriggerParams, DEADLINE_GRACE_MS, DEFAULT_LIMITS, type DelegateTaskParams, type DeleteTriggerParams, type DispatchAgentParams, type DispatchResult, type ExecutionStatus, type FindOrCreateResult, type GetExecutionParams, type GetTaskParams, type GetTriggerParams, type IgnoredField, type InvokeAgentParams, type InvokeOptions, type ListTasksParams, type ListTriggersParams, MAX_TASK_PAYLOAD_BYTES, OPERATION_TIMEOUT_MS, type QueryExtraction, type ResponseTransformMode, type RetryInfo, type SignedRequestHeaders, type Source, type TaskDossier, type TaskExecution, type TaskInfo, type TaskListPage, type TimeoutClock, type TimeoutOperation, type TriggerInfo, type TriggerMode, type TriggerRef, type UpdateTriggerParams, type Usage, ZihinAgentClient, ZihinAgentError, type ZihinClientConfig, type ZihinErrorKind, classifyStreamErrorKind, createClient, errorFromDoneChunk, errorFromStreamChunk, isCommercialBlock, sanitizeApiError, signRequest, validateApiKeyFormat, validateBaseUrl, validatePromptSize };
|
package/dist/index.js
CHANGED
|
@@ -89,6 +89,20 @@ var RUNNING_STATUSES = /* @__PURE__ */ new Set([
|
|
|
89
89
|
function isTerminalStatus(status) {
|
|
90
90
|
return !RUNNING_STATUSES.has(status.toLowerCase().replace(/-/g, "_"));
|
|
91
91
|
}
|
|
92
|
+
var _warnedDeprecations = /* @__PURE__ */ new Set();
|
|
93
|
+
function warnDeprecatedOnce(code, message) {
|
|
94
|
+
if (_warnedDeprecations.has(code)) return;
|
|
95
|
+
_warnedDeprecations.add(code);
|
|
96
|
+
try {
|
|
97
|
+
const proc = globalThis.process;
|
|
98
|
+
if (typeof proc?.emitWarning === "function") {
|
|
99
|
+
proc.emitWarning(message, { type: "ZihinDeprecationWarning", code });
|
|
100
|
+
return;
|
|
101
|
+
}
|
|
102
|
+
console.warn(`[${code}] ${message}`);
|
|
103
|
+
} catch {
|
|
104
|
+
}
|
|
105
|
+
}
|
|
92
106
|
|
|
93
107
|
// src/security.ts
|
|
94
108
|
var PRIVATE_IP_PATTERNS = [
|
|
@@ -923,6 +937,16 @@ function parseIgnoredFields(v) {
|
|
|
923
937
|
}
|
|
924
938
|
return out;
|
|
925
939
|
}
|
|
940
|
+
var MAX_SUGGESTIONS = 10;
|
|
941
|
+
var MAX_SUGGESTION_CHARS = 200;
|
|
942
|
+
function suggestionsFromBlocks(blocks) {
|
|
943
|
+
if (!Array.isArray(blocks)) return void 0;
|
|
944
|
+
const qr = [...blocks].reverse().find((b) => rec(b).type === "quick_replies");
|
|
945
|
+
const labels = rec(rec(qr).data).labels;
|
|
946
|
+
if (!Array.isArray(labels)) return void 0;
|
|
947
|
+
const out = labels.filter((l) => typeof l === "string" && l.trim().length > 0 && l.length <= MAX_SUGGESTION_CHARS).slice(0, MAX_SUGGESTIONS);
|
|
948
|
+
return out.length ? out : void 0;
|
|
949
|
+
}
|
|
926
950
|
function mapEvent(e) {
|
|
927
951
|
const d = rec(e.data);
|
|
928
952
|
switch (e.event) {
|
|
@@ -989,6 +1013,7 @@ function mapEvent(e) {
|
|
|
989
1013
|
gated: d.gated === true ? true : void 0,
|
|
990
1014
|
sources: Array.isArray(d.sources) ? d.sources : void 0,
|
|
991
1015
|
blocks: Array.isArray(d.blocks) ? d.blocks : void 0,
|
|
1016
|
+
suggestions: suggestionsFromBlocks(d.blocks),
|
|
992
1017
|
data: e.data
|
|
993
1018
|
};
|
|
994
1019
|
case "metrics": {
|
|
@@ -1012,6 +1037,8 @@ function buildRequestBody(params, normalizedTimeoutMs) {
|
|
|
1012
1037
|
if (params.message !== void 0) body.message = params.message;
|
|
1013
1038
|
if (params.sessionId) body.session_id = params.sessionId;
|
|
1014
1039
|
if (params.consumerKey) body.consumer_key = params.consumerKey;
|
|
1040
|
+
if (params.consumer?.name !== void 0) body.consumer_display_name = params.consumer.name;
|
|
1041
|
+
if (params.capabilities?.blocks?.length) body.capabilities = { blocks: [...params.capabilities.blocks] };
|
|
1015
1042
|
if (params.context) body.context = { ...params.context };
|
|
1016
1043
|
if (params.bindings) body.bindings = { ...params.bindings };
|
|
1017
1044
|
if (params.sessionFrom?.length) body.session_from = [...params.sessionFrom];
|
|
@@ -1054,6 +1081,7 @@ function validateParams(params) {
|
|
|
1054
1081
|
}
|
|
1055
1082
|
}
|
|
1056
1083
|
validateStructuredInput(params);
|
|
1084
|
+
warnDeprecatedOptions(params);
|
|
1057
1085
|
if (params.options?.timeoutMs !== void 0) {
|
|
1058
1086
|
normalizeTimeoutMs(params.options.timeoutMs, "options.timeoutMs");
|
|
1059
1087
|
}
|
|
@@ -1064,6 +1092,22 @@ function validateParams(params) {
|
|
|
1064
1092
|
}
|
|
1065
1093
|
}
|
|
1066
1094
|
}
|
|
1095
|
+
function warnDeprecatedOptions(params) {
|
|
1096
|
+
const o = params.options;
|
|
1097
|
+
if (!o) return;
|
|
1098
|
+
if (o.jitMode !== void 0) {
|
|
1099
|
+
warnDeprecatedOnce(
|
|
1100
|
+
"ZIHIN_DEP001",
|
|
1101
|
+
"`options.jitMode` is deprecated and has no effect (the server discontinued it). Remove it; it will be dropped from the SDK in 1.0."
|
|
1102
|
+
);
|
|
1103
|
+
}
|
|
1104
|
+
if (o.temperature !== void 0 || o.maxTokens !== void 0) {
|
|
1105
|
+
warnDeprecatedOnce(
|
|
1106
|
+
"ZIHIN_DEP002",
|
|
1107
|
+
"`options.temperature`/`options.maxTokens` have no effect: the agent's own configuration (`llm_config`) decides them \u2014 change it in the Zihin console or with `update_agent`. They will be dropped from the SDK in 1.0."
|
|
1108
|
+
);
|
|
1109
|
+
}
|
|
1110
|
+
}
|
|
1067
1111
|
var MAX_FIELDS = 50;
|
|
1068
1112
|
var MAX_VALUE_CHARS = 2e3;
|
|
1069
1113
|
var MAX_TOTAL_CHARS = { context: 2e3, bindings: 16e3 };
|
|
@@ -1071,13 +1115,36 @@ var MAX_SESSION_FROM_FIELDS = 5;
|
|
|
1071
1115
|
var FIELD_NAME_RE = /^[A-Za-z_][A-Za-z0-9_-]{0,63}$/;
|
|
1072
1116
|
var PROTOTYPE_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
1073
1117
|
var MAX_CONSUMER_KEY_CHARS = 200;
|
|
1118
|
+
var MAX_CONSUMER_NAME_CHARS = 255;
|
|
1119
|
+
var MAX_CLIENT_BLOCKS = 10;
|
|
1074
1120
|
function snapshotStructuredInput(params) {
|
|
1075
1121
|
const snap = (v) => isPlainObject(v) ? Object.fromEntries(Object.entries(v).filter(([, x]) => x !== void 0)) : v;
|
|
1076
1122
|
return {
|
|
1077
1123
|
...params,
|
|
1124
|
+
...normalizeConsumer(params),
|
|
1078
1125
|
context: snap(params.context),
|
|
1079
1126
|
bindings: snap(params.bindings),
|
|
1080
|
-
sessionFrom: Array.isArray(params.sessionFrom) ? [...params.sessionFrom] : params.sessionFrom
|
|
1127
|
+
sessionFrom: Array.isArray(params.sessionFrom) ? [...params.sessionFrom] : params.sessionFrom,
|
|
1128
|
+
capabilities: isPlainObject(params.capabilities) ? {
|
|
1129
|
+
...params.capabilities,
|
|
1130
|
+
blocks: Array.isArray(params.capabilities.blocks) ? [...params.capabilities.blocks] : params.capabilities.blocks
|
|
1131
|
+
} : params.capabilities
|
|
1132
|
+
};
|
|
1133
|
+
}
|
|
1134
|
+
function normalizeConsumer(params) {
|
|
1135
|
+
const c = params.consumer;
|
|
1136
|
+
if (c === void 0) return {};
|
|
1137
|
+
if (!isPlainObject(c)) {
|
|
1138
|
+
throw new ZihinAgentError("config", "`consumer` must be an object: `{ key, name? }`.");
|
|
1139
|
+
}
|
|
1140
|
+
const key = c.key;
|
|
1141
|
+
if (params.consumerKey !== void 0 && key !== void 0 && params.consumerKey !== key) {
|
|
1142
|
+
throw new ZihinAgentError("config", "`consumerKey` and `consumer.key` differ \u2014 send only one of them.");
|
|
1143
|
+
}
|
|
1144
|
+
const resolved = key ?? params.consumerKey;
|
|
1145
|
+
return {
|
|
1146
|
+
consumerKey: resolved,
|
|
1147
|
+
consumer: { key: resolved, ...c.name !== void 0 ? { name: c.name } : {} }
|
|
1081
1148
|
};
|
|
1082
1149
|
}
|
|
1083
1150
|
function isPlainObject(v) {
|
|
@@ -1095,6 +1162,24 @@ function validateStructuredInput(params) {
|
|
|
1095
1162
|
if (typeof params.consumerKey === "string" && params.consumerKey.length > MAX_CONSUMER_KEY_CHARS) {
|
|
1096
1163
|
throw new ZihinAgentError("config", `\`consumerKey\` is longer than ${MAX_CONSUMER_KEY_CHARS} characters.`);
|
|
1097
1164
|
}
|
|
1165
|
+
if (params.consumer !== void 0) {
|
|
1166
|
+
if (params.consumerKey === void 0) {
|
|
1167
|
+
throw new ZihinAgentError("config", "`consumer.key` is required (the name has nothing to attach to without it).");
|
|
1168
|
+
}
|
|
1169
|
+
const n = params.consumer.name;
|
|
1170
|
+
if (n !== void 0 && (typeof n !== "string" || !n.trim() || n.length > MAX_CONSUMER_NAME_CHARS)) {
|
|
1171
|
+
throw new ZihinAgentError("config", `\`consumer.name\` must be a non-empty string of up to ${MAX_CONSUMER_NAME_CHARS} characters.`);
|
|
1172
|
+
}
|
|
1173
|
+
}
|
|
1174
|
+
if (params.capabilities !== void 0) {
|
|
1175
|
+
const blocks = isPlainObject(params.capabilities) ? params.capabilities.blocks : null;
|
|
1176
|
+
if (blocks === null || blocks !== void 0 && (!Array.isArray(blocks) || blocks.length > MAX_CLIENT_BLOCKS || blocks.some((b) => typeof b !== "string"))) {
|
|
1177
|
+
throw new ZihinAgentError(
|
|
1178
|
+
"config",
|
|
1179
|
+
`\`capabilities\` must be \`{ blocks: [...] }\` with up to ${MAX_CLIENT_BLOCKS} block names (e.g. \`['quick_replies']\`).`
|
|
1180
|
+
);
|
|
1181
|
+
}
|
|
1182
|
+
}
|
|
1098
1183
|
for (const name of ["context", "bindings"]) {
|
|
1099
1184
|
const v = params[name];
|
|
1100
1185
|
if (v === void 0) continue;
|
|
@@ -1382,6 +1467,7 @@ async function invokeAgent(cfg, params) {
|
|
|
1382
1467
|
usage: metricsChunk?.usage,
|
|
1383
1468
|
sources: responseChunk.sources,
|
|
1384
1469
|
blocks: responseChunk.blocks,
|
|
1470
|
+
suggestions: responseChunk.suggestions,
|
|
1385
1471
|
gated: responseChunk.gated,
|
|
1386
1472
|
iterations: metricsChunk?.iterations,
|
|
1387
1473
|
executionTimeMs: metricsChunk?.executionTimeMs,
|
package/dist/index.mjs
CHANGED
|
@@ -55,6 +55,20 @@ var RUNNING_STATUSES = /* @__PURE__ */ new Set([
|
|
|
55
55
|
function isTerminalStatus(status) {
|
|
56
56
|
return !RUNNING_STATUSES.has(status.toLowerCase().replace(/-/g, "_"));
|
|
57
57
|
}
|
|
58
|
+
var _warnedDeprecations = /* @__PURE__ */ new Set();
|
|
59
|
+
function warnDeprecatedOnce(code, message) {
|
|
60
|
+
if (_warnedDeprecations.has(code)) return;
|
|
61
|
+
_warnedDeprecations.add(code);
|
|
62
|
+
try {
|
|
63
|
+
const proc = globalThis.process;
|
|
64
|
+
if (typeof proc?.emitWarning === "function") {
|
|
65
|
+
proc.emitWarning(message, { type: "ZihinDeprecationWarning", code });
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
console.warn(`[${code}] ${message}`);
|
|
69
|
+
} catch {
|
|
70
|
+
}
|
|
71
|
+
}
|
|
58
72
|
|
|
59
73
|
// src/security.ts
|
|
60
74
|
var PRIVATE_IP_PATTERNS = [
|
|
@@ -889,6 +903,16 @@ function parseIgnoredFields(v) {
|
|
|
889
903
|
}
|
|
890
904
|
return out;
|
|
891
905
|
}
|
|
906
|
+
var MAX_SUGGESTIONS = 10;
|
|
907
|
+
var MAX_SUGGESTION_CHARS = 200;
|
|
908
|
+
function suggestionsFromBlocks(blocks) {
|
|
909
|
+
if (!Array.isArray(blocks)) return void 0;
|
|
910
|
+
const qr = [...blocks].reverse().find((b) => rec(b).type === "quick_replies");
|
|
911
|
+
const labels = rec(rec(qr).data).labels;
|
|
912
|
+
if (!Array.isArray(labels)) return void 0;
|
|
913
|
+
const out = labels.filter((l) => typeof l === "string" && l.trim().length > 0 && l.length <= MAX_SUGGESTION_CHARS).slice(0, MAX_SUGGESTIONS);
|
|
914
|
+
return out.length ? out : void 0;
|
|
915
|
+
}
|
|
892
916
|
function mapEvent(e) {
|
|
893
917
|
const d = rec(e.data);
|
|
894
918
|
switch (e.event) {
|
|
@@ -955,6 +979,7 @@ function mapEvent(e) {
|
|
|
955
979
|
gated: d.gated === true ? true : void 0,
|
|
956
980
|
sources: Array.isArray(d.sources) ? d.sources : void 0,
|
|
957
981
|
blocks: Array.isArray(d.blocks) ? d.blocks : void 0,
|
|
982
|
+
suggestions: suggestionsFromBlocks(d.blocks),
|
|
958
983
|
data: e.data
|
|
959
984
|
};
|
|
960
985
|
case "metrics": {
|
|
@@ -978,6 +1003,8 @@ function buildRequestBody(params, normalizedTimeoutMs) {
|
|
|
978
1003
|
if (params.message !== void 0) body.message = params.message;
|
|
979
1004
|
if (params.sessionId) body.session_id = params.sessionId;
|
|
980
1005
|
if (params.consumerKey) body.consumer_key = params.consumerKey;
|
|
1006
|
+
if (params.consumer?.name !== void 0) body.consumer_display_name = params.consumer.name;
|
|
1007
|
+
if (params.capabilities?.blocks?.length) body.capabilities = { blocks: [...params.capabilities.blocks] };
|
|
981
1008
|
if (params.context) body.context = { ...params.context };
|
|
982
1009
|
if (params.bindings) body.bindings = { ...params.bindings };
|
|
983
1010
|
if (params.sessionFrom?.length) body.session_from = [...params.sessionFrom];
|
|
@@ -1020,6 +1047,7 @@ function validateParams(params) {
|
|
|
1020
1047
|
}
|
|
1021
1048
|
}
|
|
1022
1049
|
validateStructuredInput(params);
|
|
1050
|
+
warnDeprecatedOptions(params);
|
|
1023
1051
|
if (params.options?.timeoutMs !== void 0) {
|
|
1024
1052
|
normalizeTimeoutMs(params.options.timeoutMs, "options.timeoutMs");
|
|
1025
1053
|
}
|
|
@@ -1030,6 +1058,22 @@ function validateParams(params) {
|
|
|
1030
1058
|
}
|
|
1031
1059
|
}
|
|
1032
1060
|
}
|
|
1061
|
+
function warnDeprecatedOptions(params) {
|
|
1062
|
+
const o = params.options;
|
|
1063
|
+
if (!o) return;
|
|
1064
|
+
if (o.jitMode !== void 0) {
|
|
1065
|
+
warnDeprecatedOnce(
|
|
1066
|
+
"ZIHIN_DEP001",
|
|
1067
|
+
"`options.jitMode` is deprecated and has no effect (the server discontinued it). Remove it; it will be dropped from the SDK in 1.0."
|
|
1068
|
+
);
|
|
1069
|
+
}
|
|
1070
|
+
if (o.temperature !== void 0 || o.maxTokens !== void 0) {
|
|
1071
|
+
warnDeprecatedOnce(
|
|
1072
|
+
"ZIHIN_DEP002",
|
|
1073
|
+
"`options.temperature`/`options.maxTokens` have no effect: the agent's own configuration (`llm_config`) decides them \u2014 change it in the Zihin console or with `update_agent`. They will be dropped from the SDK in 1.0."
|
|
1074
|
+
);
|
|
1075
|
+
}
|
|
1076
|
+
}
|
|
1033
1077
|
var MAX_FIELDS = 50;
|
|
1034
1078
|
var MAX_VALUE_CHARS = 2e3;
|
|
1035
1079
|
var MAX_TOTAL_CHARS = { context: 2e3, bindings: 16e3 };
|
|
@@ -1037,13 +1081,36 @@ var MAX_SESSION_FROM_FIELDS = 5;
|
|
|
1037
1081
|
var FIELD_NAME_RE = /^[A-Za-z_][A-Za-z0-9_-]{0,63}$/;
|
|
1038
1082
|
var PROTOTYPE_KEYS = /* @__PURE__ */ new Set(["__proto__", "constructor", "prototype"]);
|
|
1039
1083
|
var MAX_CONSUMER_KEY_CHARS = 200;
|
|
1084
|
+
var MAX_CONSUMER_NAME_CHARS = 255;
|
|
1085
|
+
var MAX_CLIENT_BLOCKS = 10;
|
|
1040
1086
|
function snapshotStructuredInput(params) {
|
|
1041
1087
|
const snap = (v) => isPlainObject(v) ? Object.fromEntries(Object.entries(v).filter(([, x]) => x !== void 0)) : v;
|
|
1042
1088
|
return {
|
|
1043
1089
|
...params,
|
|
1090
|
+
...normalizeConsumer(params),
|
|
1044
1091
|
context: snap(params.context),
|
|
1045
1092
|
bindings: snap(params.bindings),
|
|
1046
|
-
sessionFrom: Array.isArray(params.sessionFrom) ? [...params.sessionFrom] : params.sessionFrom
|
|
1093
|
+
sessionFrom: Array.isArray(params.sessionFrom) ? [...params.sessionFrom] : params.sessionFrom,
|
|
1094
|
+
capabilities: isPlainObject(params.capabilities) ? {
|
|
1095
|
+
...params.capabilities,
|
|
1096
|
+
blocks: Array.isArray(params.capabilities.blocks) ? [...params.capabilities.blocks] : params.capabilities.blocks
|
|
1097
|
+
} : params.capabilities
|
|
1098
|
+
};
|
|
1099
|
+
}
|
|
1100
|
+
function normalizeConsumer(params) {
|
|
1101
|
+
const c = params.consumer;
|
|
1102
|
+
if (c === void 0) return {};
|
|
1103
|
+
if (!isPlainObject(c)) {
|
|
1104
|
+
throw new ZihinAgentError("config", "`consumer` must be an object: `{ key, name? }`.");
|
|
1105
|
+
}
|
|
1106
|
+
const key = c.key;
|
|
1107
|
+
if (params.consumerKey !== void 0 && key !== void 0 && params.consumerKey !== key) {
|
|
1108
|
+
throw new ZihinAgentError("config", "`consumerKey` and `consumer.key` differ \u2014 send only one of them.");
|
|
1109
|
+
}
|
|
1110
|
+
const resolved = key ?? params.consumerKey;
|
|
1111
|
+
return {
|
|
1112
|
+
consumerKey: resolved,
|
|
1113
|
+
consumer: { key: resolved, ...c.name !== void 0 ? { name: c.name } : {} }
|
|
1047
1114
|
};
|
|
1048
1115
|
}
|
|
1049
1116
|
function isPlainObject(v) {
|
|
@@ -1061,6 +1128,24 @@ function validateStructuredInput(params) {
|
|
|
1061
1128
|
if (typeof params.consumerKey === "string" && params.consumerKey.length > MAX_CONSUMER_KEY_CHARS) {
|
|
1062
1129
|
throw new ZihinAgentError("config", `\`consumerKey\` is longer than ${MAX_CONSUMER_KEY_CHARS} characters.`);
|
|
1063
1130
|
}
|
|
1131
|
+
if (params.consumer !== void 0) {
|
|
1132
|
+
if (params.consumerKey === void 0) {
|
|
1133
|
+
throw new ZihinAgentError("config", "`consumer.key` is required (the name has nothing to attach to without it).");
|
|
1134
|
+
}
|
|
1135
|
+
const n = params.consumer.name;
|
|
1136
|
+
if (n !== void 0 && (typeof n !== "string" || !n.trim() || n.length > MAX_CONSUMER_NAME_CHARS)) {
|
|
1137
|
+
throw new ZihinAgentError("config", `\`consumer.name\` must be a non-empty string of up to ${MAX_CONSUMER_NAME_CHARS} characters.`);
|
|
1138
|
+
}
|
|
1139
|
+
}
|
|
1140
|
+
if (params.capabilities !== void 0) {
|
|
1141
|
+
const blocks = isPlainObject(params.capabilities) ? params.capabilities.blocks : null;
|
|
1142
|
+
if (blocks === null || blocks !== void 0 && (!Array.isArray(blocks) || blocks.length > MAX_CLIENT_BLOCKS || blocks.some((b) => typeof b !== "string"))) {
|
|
1143
|
+
throw new ZihinAgentError(
|
|
1144
|
+
"config",
|
|
1145
|
+
`\`capabilities\` must be \`{ blocks: [...] }\` with up to ${MAX_CLIENT_BLOCKS} block names (e.g. \`['quick_replies']\`).`
|
|
1146
|
+
);
|
|
1147
|
+
}
|
|
1148
|
+
}
|
|
1064
1149
|
for (const name of ["context", "bindings"]) {
|
|
1065
1150
|
const v = params[name];
|
|
1066
1151
|
if (v === void 0) continue;
|
|
@@ -1348,6 +1433,7 @@ async function invokeAgent(cfg, params) {
|
|
|
1348
1433
|
usage: metricsChunk?.usage,
|
|
1349
1434
|
sources: responseChunk.sources,
|
|
1350
1435
|
blocks: responseChunk.blocks,
|
|
1436
|
+
suggestions: responseChunk.suggestions,
|
|
1351
1437
|
gated: responseChunk.gated,
|
|
1352
1438
|
iterations: metricsChunk?.iterations,
|
|
1353
1439
|
executionTimeMs: metricsChunk?.executionTimeMs,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zihin/agent-client",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.1",
|
|
4
4
|
"description": "Núcleo de invocação de agentes Zihin.ai — padrão único para n8n, Paperclip e integrações futuras. Stream direto (SSE bufferizado) + triggers assíncronos com callback.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"zihin",
|