@zihin/agent-client 0.1.0 → 0.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.
@@ -1,82 +0,0 @@
1
- /**
2
- * Security utilities — portado de n8n-nodes-zihin/src/utils/security.ts (zero-dep).
3
- * SSRF prevention, payload limits, error sanitization, API-key format, HMAC signing.
4
- *
5
- * Núcleo compartilhado: os shells (n8n, Paperclip) reusam estas primitivas via @zihin/agent-client.
6
- *
7
- * @module security
8
- */
9
- export interface UrlValidationResult {
10
- valid: boolean;
11
- error?: string;
12
- sanitizedUrl?: string;
13
- }
14
- export interface UrlValidationOptions {
15
- allowCustomDomains?: boolean;
16
- allowHttp?: boolean;
17
- allowLocalhost?: boolean;
18
- }
19
- /**
20
- * Validates a base URL for SSRF prevention.
21
- *
22
- * NOTA (S4): a checagem é por NOME de host, não pelo IP resolvido. Com `allowCustomDomains: true`,
23
- * um host que resolve para IP privado (DNS rebinding) passa. Em ambiente sensível, mantenha o
24
- * whitelist (default) ou faça a resolução/checagem de IP na borda de rede.
25
- *
26
- * @param url - The URL to validate
27
- * @param options - Validation options
28
- * @returns Validation result with sanitized URL or error
29
- */
30
- export declare function validateBaseUrl(url: string, options?: UrlValidationOptions): UrlValidationResult;
31
- export interface PayloadLimits {
32
- maxPromptBytes: number;
33
- maxMessageCount: number;
34
- maxSingleMessageBytes: number;
35
- maxTotalPayloadBytes: number;
36
- }
37
- declare const DEFAULT_LIMITS: PayloadLimits;
38
- export interface PayloadValidationResult {
39
- valid: boolean;
40
- error?: string;
41
- truncated?: boolean;
42
- details?: {
43
- promptBytes?: number;
44
- messageCount?: number;
45
- largestMessageBytes?: number;
46
- totalBytes?: number;
47
- };
48
- }
49
- /**
50
- * Validates a single message/prompt size against configured limits.
51
- */
52
- export declare function validatePromptSize(prompt: string, limits?: Partial<PayloadLimits>): PayloadValidationResult;
53
- export interface SanitizedError {
54
- message: string;
55
- code?: string;
56
- retryable: boolean;
57
- retryAfter?: number;
58
- }
59
- /**
60
- * Sanitizes API errors to prevent information leakage (keys, request IDs, stack traces).
61
- */
62
- export declare function sanitizeApiError(error: unknown): SanitizedError;
63
- export interface ApiKeyValidationResult {
64
- valid: boolean;
65
- error?: string;
66
- environment?: 'live' | 'test' | 'dev';
67
- }
68
- /**
69
- * Validates API key format (zhn_live_* | zhn_test_* | zhn_dev_*).
70
- */
71
- export declare function validateApiKeyFormat(apiKey: string): ApiKeyValidationResult;
72
- export interface SignedRequestHeaders {
73
- 'X-Zihin-Signature': string;
74
- 'X-Zihin-Timestamp': string;
75
- 'X-Zihin-Nonce': string;
76
- }
77
- /**
78
- * Signs a request payload with HMAC-SHA256 (timestamp + nonce + payload).
79
- * Requer Node crypto — carregado sob demanda; lança em runtimes sem ele.
80
- */
81
- export declare function signRequest(payload: string, secretKey: string, timestamp?: number): SignedRequestHeaders;
82
- export { DEFAULT_LIMITS };
package/dist/security.js DELETED
@@ -1,251 +0,0 @@
1
- "use strict";
2
- /**
3
- * Security utilities — portado de n8n-nodes-zihin/src/utils/security.ts (zero-dep).
4
- * SSRF prevention, payload limits, error sanitization, API-key format, HMAC signing.
5
- *
6
- * Núcleo compartilhado: os shells (n8n, Paperclip) reusam estas primitivas via @zihin/agent-client.
7
- *
8
- * @module security
9
- */
10
- Object.defineProperty(exports, "__esModule", { value: true });
11
- exports.DEFAULT_LIMITS = void 0;
12
- exports.validateBaseUrl = validateBaseUrl;
13
- exports.validatePromptSize = validatePromptSize;
14
- exports.sanitizeApiError = sanitizeApiError;
15
- exports.validateApiKeyFormat = validateApiKeyFormat;
16
- exports.signRequest = signRequest;
17
- const internal_1 = require("./internal");
18
- // `node:crypto` é carregado SOB DEMANDA (só em signRequest) para não quebrar o load do módulo
19
- // em runtimes sem Node crypto (edge/browser), onde o resto do núcleo funciona via Web APIs.
20
- // ============================================
21
- // 1. URL Validation (SSRF Prevention)
22
- // ============================================
23
- const PRIVATE_IP_PATTERNS = [
24
- /^127\./, // 127.0.0.0/8 (localhost)
25
- /^10\./, // 10.0.0.0/8 (private)
26
- /^172\.(1[6-9]|2[0-9]|3[0-1])\./, // 172.16.0.0/12 (private)
27
- /^192\.168\./, // 192.168.0.0/16 (private)
28
- /^169\.254\./, // 169.254.0.0/16 (link-local)
29
- /^0\./, // 0.0.0.0/8
30
- /^::1$/, // IPv6 localhost
31
- /^fe80:/i, // IPv6 link-local
32
- /^fc00:/i, // IPv6 unique local
33
- /^fd00:/i, // IPv6 unique local
34
- ];
35
- const BLOCKED_HOSTNAMES = [
36
- 'localhost',
37
- 'localtest.me',
38
- 'metadata.google.internal', // GCP metadata
39
- '169.254.169.254', // AWS/Azure/GCP metadata
40
- 'metadata.azure.com',
41
- ];
42
- const ALLOWED_ZIHIN_DOMAINS = [
43
- 'llm.zihin.ai',
44
- 'api.zihin.ai',
45
- 'staging.llm.zihin.ai',
46
- 'dev.llm.zihin.ai',
47
- ];
48
- /**
49
- * Validates a base URL for SSRF prevention.
50
- *
51
- * NOTA (S4): a checagem é por NOME de host, não pelo IP resolvido. Com `allowCustomDomains: true`,
52
- * um host que resolve para IP privado (DNS rebinding) passa. Em ambiente sensível, mantenha o
53
- * whitelist (default) ou faça a resolução/checagem de IP na borda de rede.
54
- *
55
- * @param url - The URL to validate
56
- * @param options - Validation options
57
- * @returns Validation result with sanitized URL or error
58
- */
59
- function validateBaseUrl(url, options = {}) {
60
- // Empty/default URL is allowed
61
- if (!url || url.trim() === '') {
62
- return { valid: true, sanitizedUrl: 'https://llm.zihin.ai' };
63
- }
64
- try {
65
- const parsed = new URL(url);
66
- const hostname = parsed.hostname;
67
- // Check if this is localhost (for development)
68
- const isLocalhost = hostname === 'localhost' || hostname === '127.0.0.1' || hostname === '::1';
69
- // Allow localhost when explicitly enabled (development mode)
70
- if (isLocalhost && options.allowLocalhost) {
71
- const sanitizedUrl = parsed.origin + parsed.pathname.replace(/\/+$/, '');
72
- return { valid: true, sanitizedUrl };
73
- }
74
- // 1. Protocol validation (HTTPS only by default)
75
- if (!options.allowHttp && parsed.protocol !== 'https:') {
76
- return {
77
- valid: false,
78
- error: 'Only HTTPS URLs are allowed for security reasons',
79
- };
80
- }
81
- // 2. Block private IP ranges
82
- for (const pattern of PRIVATE_IP_PATTERNS) {
83
- if (pattern.test(hostname)) {
84
- return { valid: false, error: 'Private IP addresses are not allowed' };
85
- }
86
- }
87
- // 3. Block known dangerous hostnames
88
- for (const blocked of BLOCKED_HOSTNAMES) {
89
- if (blocked.startsWith('*')) {
90
- const suffix = blocked.slice(1);
91
- if (hostname.endsWith(suffix)) {
92
- return { valid: false, error: 'This hostname is not allowed' };
93
- }
94
- }
95
- else if (hostname === blocked || hostname.endsWith('.' + blocked)) {
96
- return { valid: false, error: 'This hostname is not allowed' };
97
- }
98
- }
99
- // 4. Whitelist mode (only Zihin domains) unless custom domains allowed
100
- if (!options.allowCustomDomains) {
101
- const isAllowed = ALLOWED_ZIHIN_DOMAINS.some((domain) => hostname === domain || hostname.endsWith('.' + domain));
102
- if (!isAllowed) {
103
- return {
104
- valid: false,
105
- error: `Only Zihin domains are allowed. Use 'allowCustomBaseUrl' for custom endpoints.`,
106
- };
107
- }
108
- }
109
- // Remove trailing slash for consistency
110
- const sanitizedUrl = parsed.origin + parsed.pathname.replace(/\/+$/, '');
111
- return { valid: true, sanitizedUrl };
112
- }
113
- catch {
114
- return { valid: false, error: 'Invalid URL format' };
115
- }
116
- }
117
- const DEFAULT_LIMITS = {
118
- maxPromptBytes: 100 * 1024, // 100KB
119
- maxMessageCount: 100,
120
- maxSingleMessageBytes: 50 * 1024, // 50KB
121
- maxTotalPayloadBytes: 500 * 1024, // 500KB
122
- };
123
- exports.DEFAULT_LIMITS = DEFAULT_LIMITS;
124
- /**
125
- * Validates a single message/prompt size against configured limits.
126
- */
127
- function validatePromptSize(prompt, limits = {}) {
128
- const effectiveLimits = { ...DEFAULT_LIMITS, ...limits };
129
- const bytes = (0, internal_1.utf8Len)(prompt);
130
- if (bytes > effectiveLimits.maxPromptBytes) {
131
- return {
132
- valid: false,
133
- error: `Prompt size (${Math.round(bytes / 1024)}KB) exceeds maximum allowed (${Math.round(effectiveLimits.maxPromptBytes / 1024)}KB)`,
134
- details: { promptBytes: bytes },
135
- };
136
- }
137
- return { valid: true, details: { promptBytes: bytes } };
138
- }
139
- // ============================================
140
- // 3. Error Sanitization
141
- // ============================================
142
- // Redação SÓ de segredos reais. request_id/trace_id/correlation_id NÃO são redatados:
143
- // não são secretos e são exatamente o que o suporte/observabilidade precisa para correlacionar.
144
- const SENSITIVE_PATTERNS = [
145
- /zhn_(?:live|test|dev)_[a-zA-Z0-9]+/g, // API keys
146
- /Bearer\s+[a-zA-Z0-9._-]+/gi, // Bearer tokens
147
- /at\s+[\w./<>]+\s*\(.*:\d+:\d+\)/g, // Stack trace lines
148
- /^\s+at\s+.+$/gm, // Stack traces
149
- /Error:\s*.*\n\s+at/g, // Error stack beginnings
150
- ];
151
- const ERROR_CODE_MAP = {
152
- RATE_LIMIT_EXCEEDED: 'Rate limit exceeded. Please wait before retrying.',
153
- UNAUTHORIZED: 'Authentication failed. Please check your API credentials.',
154
- FORBIDDEN: 'This API key lacks permission for this action. Use an admin/editor key (member keys cannot create triggers or read telemetry).',
155
- INVALID_MODEL: 'The specified model is not available.',
156
- INTERNAL_ERROR: 'An internal error occurred. Please try again later.',
157
- TIMEOUT: 'Request timed out. Try increasing the timeout.',
158
- INVALID_REQUEST: 'The request was malformed. Please check your input.',
159
- INSUFFICIENT_CREDITS: 'Insufficient credits. Please check your account balance.',
160
- CONTEXT_LENGTH_EXCEEDED: 'The input exceeds the model context length limit.',
161
- AGENT_NOT_FOUND: 'Agent not found or not active for this tenant.',
162
- };
163
- /**
164
- * Sanitizes API errors to prevent information leakage (keys, request IDs, stack traces).
165
- */
166
- function sanitizeApiError(error) {
167
- let message = 'An unexpected error occurred';
168
- let code;
169
- let retryable = false;
170
- let retryAfter;
171
- if (typeof error === 'object' && error !== null) {
172
- const err = error;
173
- // O BE usa o shape aninhado { error: { code, message } }; suporta também o plano
174
- // { error|code: string, message }. (Antes, err.error objeto virava "código" e a msg sumia.)
175
- const nested = err.error && typeof err.error === 'object' ? err.error : undefined;
176
- const codeRaw = nested?.code ?? (typeof err.error === 'string' ? err.error : err.code);
177
- code = typeof codeRaw === 'string' ? codeRaw : undefined;
178
- const rawMessage = (nested?.message ?? err.message);
179
- if (code && ERROR_CODE_MAP[code]) {
180
- message = ERROR_CODE_MAP[code];
181
- }
182
- else if (typeof rawMessage === 'string' && rawMessage) {
183
- message = rawMessage;
184
- }
185
- if (code === 'RATE_LIMIT_EXCEEDED' || code === 'TIMEOUT') {
186
- retryable = true;
187
- retryAfter = err.retryAfter || 60;
188
- }
189
- // S5: limita o tamanho ANTES das regex (bounda custo/ReDoS em mensagens grandes).
190
- if (message.length > 2000)
191
- message = message.slice(0, 2000);
192
- for (const pattern of SENSITIVE_PATTERNS) {
193
- message = message.replace(pattern, '[REDACTED]');
194
- }
195
- }
196
- else if (typeof error === 'string') {
197
- message = error;
198
- if (message.length > 2000)
199
- message = message.slice(0, 2000);
200
- for (const pattern of SENSITIVE_PATTERNS) {
201
- message = message.replace(pattern, '[REDACTED]');
202
- }
203
- }
204
- if (message.length > 500) {
205
- message = message.substring(0, 500) + '...';
206
- }
207
- return { message, code, retryable, retryAfter };
208
- }
209
- // ============================================
210
- // 4. API Key Validation
211
- // ============================================
212
- const API_KEY_PATTERN = /^zhn_(live|test|dev)_[a-zA-Z0-9]{20,}$/;
213
- /**
214
- * Validates API key format (zhn_live_* | zhn_test_* | zhn_dev_*).
215
- */
216
- function validateApiKeyFormat(apiKey) {
217
- if (!apiKey || apiKey.trim() === '') {
218
- return { valid: false, error: 'API key is required' };
219
- }
220
- const trimmed = apiKey.trim();
221
- if (!API_KEY_PATTERN.test(trimmed)) {
222
- return {
223
- valid: false,
224
- error: 'Invalid API key format. Expected: zhn_live_xxx, zhn_test_xxx or zhn_dev_xxx',
225
- };
226
- }
227
- const environment = trimmed.startsWith('zhn_live_')
228
- ? 'live'
229
- : trimmed.startsWith('zhn_test_')
230
- ? 'test'
231
- : 'dev';
232
- return { valid: true, environment };
233
- }
234
- /**
235
- * Signs a request payload with HMAC-SHA256 (timestamp + nonce + payload).
236
- * Requer Node crypto — carregado sob demanda; lança em runtimes sem ele.
237
- */
238
- function signRequest(payload, secretKey, timestamp) {
239
- // eslint-disable-next-line @typescript-eslint/no-var-requires
240
- const { createHmac, randomBytes } = require('node:crypto');
241
- const ts = timestamp || Date.now();
242
- const nonce = randomBytes(16).toString('hex');
243
- const message = `${ts}.${nonce}.${payload}`;
244
- const signature = createHmac('sha256', secretKey).update(message).digest('hex');
245
- return {
246
- 'X-Zihin-Signature': `sha256=${signature}`,
247
- 'X-Zihin-Timestamp': ts.toString(),
248
- 'X-Zihin-Nonce': nonce,
249
- };
250
- }
251
- //# sourceMappingURL=security.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"security.js","sourceRoot":"","sources":["../src/security.ts"],"names":[],"mappings":"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"}
package/dist/sse.d.ts DELETED
@@ -1,27 +0,0 @@
1
- /**
2
- * Parser de Server-Sent Events. Converte o corpo (ReadableStream) num async iterator de
3
- * eventos `{ event, data }`, com `data` já parseado de JSON quando possível.
4
- *
5
- * Robustez:
6
- * - limites de tamanho (maxEventBytes / maxTotalBytes) → aborta com `protocol` (anti-DoS de memória).
7
- * - parse incremental O(n) (sem replace global no buffer acumulado).
8
- * - `reader.cancel()` no finally → fecha a conexão mesmo em `break`/erro (sem socket vazado).
9
- *
10
- * @module sse
11
- */
12
- export interface SseEvent {
13
- event: string;
14
- data: unknown;
15
- rawData: string;
16
- }
17
- export interface ParseSseOptions {
18
- /** Signal do chamador, para checagem de abort entre leituras. */
19
- signal?: AbortSignal;
20
- /** Traduz uma rejeição de read()/abort para o erro correto (timeout/aborted/network). */
21
- onAbortError?: () => Error;
22
- /** Chamado no finally (libera deadline/recursos). */
23
- onEnd?: () => void;
24
- maxEventBytes?: number;
25
- maxTotalBytes?: number;
26
- }
27
- export declare function parseSse(response: Response, opts?: ParseSseOptions): AsyncGenerator<SseEvent>;
package/dist/sse.js DELETED
@@ -1,138 +0,0 @@
1
- "use strict";
2
- /**
3
- * Parser de Server-Sent Events. Converte o corpo (ReadableStream) num async iterator de
4
- * eventos `{ event, data }`, com `data` já parseado de JSON quando possível.
5
- *
6
- * Robustez:
7
- * - limites de tamanho (maxEventBytes / maxTotalBytes) → aborta com `protocol` (anti-DoS de memória).
8
- * - parse incremental O(n) (sem replace global no buffer acumulado).
9
- * - `reader.cancel()` no finally → fecha a conexão mesmo em `break`/erro (sem socket vazado).
10
- *
11
- * @module sse
12
- */
13
- Object.defineProperty(exports, "__esModule", { value: true });
14
- exports.parseSse = parseSse;
15
- const errors_1 = require("./errors");
16
- const internal_1 = require("./internal");
17
- const DEFAULT_MAX_EVENT_BYTES = 1 * 1024 * 1024;
18
- const DEFAULT_MAX_TOTAL_BYTES = 64 * 1024 * 1024;
19
- async function* parseSse(response, opts = {}) {
20
- if (!response.body) {
21
- throw new errors_1.ZihinAgentError('protocol', 'SSE response has no body.');
22
- }
23
- const maxEventBytes = opts.maxEventBytes ?? DEFAULT_MAX_EVENT_BYTES;
24
- const maxTotalBytes = opts.maxTotalBytes ?? DEFAULT_MAX_TOTAL_BYTES;
25
- const reader = response.body.getReader();
26
- const decoder = new TextDecoder('utf-8');
27
- let buffer = '';
28
- let eventName = '';
29
- let dataLines = [];
30
- let dataBytes = 0;
31
- let totalBytes = 0;
32
- const flush = () => {
33
- const had = dataLines.length > 0 || eventName !== '';
34
- const rawData = dataLines.join('\n');
35
- const evt = eventName || 'message';
36
- eventName = '';
37
- dataLines = [];
38
- dataBytes = 0;
39
- if (!had || rawData === '')
40
- return null;
41
- let data = rawData;
42
- try {
43
- data = JSON.parse(rawData);
44
- }
45
- catch {
46
- /* mantém string crua */
47
- }
48
- return { event: evt, data, rawData };
49
- };
50
- try {
51
- // eslint-disable-next-line no-constant-condition
52
- while (true) {
53
- if (opts.signal?.aborted) {
54
- throw opts.onAbortError ? opts.onAbortError() : new errors_1.ZihinAgentError('aborted', 'Stream aborted.');
55
- }
56
- let chunk;
57
- try {
58
- chunk = await reader.read();
59
- }
60
- catch (err) {
61
- throw opts.onAbortError ? opts.onAbortError() : (0, errors_1.errorFromThrow)(err);
62
- }
63
- if (chunk.done)
64
- break;
65
- totalBytes += chunk.value.byteLength;
66
- if (totalBytes > maxTotalBytes) {
67
- throw new errors_1.ZihinAgentError('protocol', `SSE stream exceeded ${maxTotalBytes} bytes.`);
68
- }
69
- buffer += decoder.decode(chunk.value, { stream: true });
70
- let nl;
71
- while ((nl = buffer.indexOf('\n')) !== -1) {
72
- let line = buffer.slice(0, nl);
73
- buffer = buffer.slice(nl + 1);
74
- if (line.endsWith('\r'))
75
- line = line.slice(0, -1); // \r\n sem replace global (P3)
76
- if (line === '') {
77
- const e = flush();
78
- if (e)
79
- yield e;
80
- continue;
81
- }
82
- if (line.startsWith(':'))
83
- continue; // comentário/keep-alive
84
- const colon = line.indexOf(':');
85
- const field = colon === -1 ? line : line.slice(0, colon);
86
- let val = colon === -1 ? '' : line.slice(colon + 1);
87
- if (val.startsWith(' '))
88
- val = val.slice(1);
89
- if (field === 'event') {
90
- eventName = val;
91
- }
92
- else if (field === 'data') {
93
- dataBytes += (0, internal_1.utf8Len)(val) + 1;
94
- if (dataBytes > maxEventBytes) {
95
- throw new errors_1.ZihinAgentError('protocol', `SSE event exceeded ${maxEventBytes} bytes.`);
96
- }
97
- dataLines.push(val);
98
- }
99
- // `id`/`retry` ignorados (sem reconexão automática aqui).
100
- }
101
- // Linha sem `\n` ainda em buffer não pode crescer sem teto (S2).
102
- if ((0, internal_1.utf8Len)(buffer) > maxEventBytes) {
103
- throw new errors_1.ZihinAgentError('protocol', `SSE line exceeded ${maxEventBytes} bytes.`);
104
- }
105
- }
106
- // Flush final do decoder (caractere multibyte partido no fim do stream) e processa
107
- // uma última linha `data:`/`event:` que tenha chegado sem o `\n` terminal.
108
- buffer += decoder.decode();
109
- if (buffer.length > 0) {
110
- let line = buffer.endsWith('\r') ? buffer.slice(0, -1) : buffer;
111
- if (line && !line.startsWith(':')) {
112
- const colon = line.indexOf(':');
113
- const field = colon === -1 ? line : line.slice(0, colon);
114
- let val = colon === -1 ? '' : line.slice(colon + 1);
115
- if (val.startsWith(' '))
116
- val = val.slice(1);
117
- if (field === 'data')
118
- dataLines.push(val);
119
- else if (field === 'event')
120
- eventName = val;
121
- }
122
- }
123
- const tail = flush();
124
- if (tail)
125
- yield tail;
126
- }
127
- finally {
128
- // Fecha a conexão também em break/throw (P2: sem socket vazado). cancel() libera o lock.
129
- try {
130
- await reader.cancel();
131
- }
132
- catch {
133
- /* ignore */
134
- }
135
- opts.onEnd?.();
136
- }
137
- }
138
- //# sourceMappingURL=sse.js.map
package/dist/sse.js.map DELETED
@@ -1 +0,0 @@
1
- {"version":3,"file":"sse.js","sourceRoot":"","sources":["../src/sse.ts"],"names":[],"mappings":"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"}
@@ -1,43 +0,0 @@
1
- /**
2
- * Caminho B — invocação assíncrona/desacoplada via sistema de triggers.
3
- * - createTrigger: provisiona (1x) um webhook ligado a um agente (POST /api/triggers).
4
- * - dispatchAgent: dispara o trigger (POST /api/triggers/webhook/:id) → 202 (async) | JSON (sync).
5
- * - getExecution: consulta o resultado (GET /api/triggers/:id/executions/:execId).
6
- *
7
- * Requer key role admin/editor (triggers:create / telemetry:read). Keys `member` → 403.
8
- *
9
- * @module triggers
10
- */
11
- import { type ResolvedConfig } from './http';
12
- import type { CreateTriggerParams, DeleteTriggerParams, DispatchAgentParams, DispatchResult, ExecutionStatus, FindOrCreateResult, GetExecutionParams, GetTriggerParams, ListTriggersParams, TriggerInfo, TriggerRef } from './types';
13
- /**
14
- * Provisiona um trigger de webhook ligado a um agente. Faça isto uma vez; depois dispare
15
- * quantas vezes quiser com `dispatchAgent`.
16
- */
17
- export declare function createTrigger(cfg: ResolvedConfig, params: CreateTriggerParams): Promise<TriggerRef>;
18
- /**
19
- * Dispara um trigger. Em modo async retorna `{ accepted, executionId }` (202);
20
- * em modo sync retorna também `{ agentResponse, usage }` (200).
21
- */
22
- export declare function dispatchAgent(cfg: ResolvedConfig, params: DispatchAgentParams): Promise<DispatchResult>;
23
- /** Lista os triggers do tenant (opcionalmente filtrando por agente/tipo/habilitados). */
24
- export declare function listTriggers(cfg: ResolvedConfig, params?: ListTriggersParams): Promise<TriggerInfo[]>;
25
- /** Obtém um trigger pelo id (inclui webhookUrl para webhooks). */
26
- export declare function getTrigger(cfg: ResolvedConfig, params: GetTriggerParams): Promise<TriggerInfo>;
27
- /** Remove um trigger. Requer key role admin/owner (editor NÃO pode deletar → 403). */
28
- export declare function deleteTrigger(cfg: ResolvedConfig, params: DeleteTriggerParams): Promise<{
29
- deleted: boolean;
30
- }>;
31
- /**
32
- * Reaproveita um trigger existente do mesmo agente+nome, ou cria um novo. Evita o footgun de
33
- * duplicação (o BE não tem unicidade de nome). Retorna `created: false` se reusou.
34
- *
35
- * Nota: se um trigger com o mesmo nome já existe mas com config diferente (ex.: outra callbackUrl),
36
- * ele é REAPROVEITADO como está — atualize explicitamente com o BE se precisar reconciliar.
37
- */
38
- export declare function findOrCreateTrigger(cfg: ResolvedConfig, params: CreateTriggerParams): Promise<FindOrCreateResult>;
39
- /**
40
- * Consulta o status/resultado de uma execução disparada por trigger.
41
- * Útil para polling no modo async (alternativa ao callback).
42
- */
43
- export declare function getExecution(cfg: ResolvedConfig, params: GetExecutionParams): Promise<ExecutionStatus>;