n8n-nodes-cribops 0.1.20 → 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.
@@ -4,78 +4,212 @@ export interface CribopsHttpConfig {
4
4
  apiToken: string;
5
5
  timeout?: number;
6
6
  }
7
- export interface CribopsAgent {
7
+ export interface CribopsWebhookDelivery {
8
8
  id: string;
9
- name: string;
10
- description?: string;
11
- status: 'active' | 'inactive';
12
- tenantId: string;
13
- organizationId: string;
14
- metadata?: IDataObject;
9
+ webhook_id: string;
10
+ destination_url: string;
11
+ status: 'pending' | 'delivered' | 'failed' | 'retrying';
12
+ attempts: number;
13
+ max_attempts: number;
14
+ last_attempt_at?: string;
15
+ next_retry_at?: string;
16
+ response_status?: number;
17
+ response_body?: string;
18
+ error_message?: string;
19
+ created_at: string;
20
+ delivered_at?: string;
15
21
  }
16
- export interface CribopsWebhookMessage {
17
- id: string;
18
- type: 'user_message' | 'agent_response';
19
- content: string;
20
- conversationId: string;
21
- userId?: string;
22
- agentId: string;
23
- timestamp: string;
24
- metadata?: IDataObject;
25
- fileUrl?: string;
26
- fileName?: string;
27
- fileType?: string;
22
+ export interface CribopsWebhookMetrics {
23
+ total_webhooks: number;
24
+ successful_deliveries: number;
25
+ failed_deliveries: number;
26
+ pending_deliveries: number;
27
+ average_delivery_time_ms: number;
28
+ success_rate: number;
29
+ destinations: {
30
+ url: string;
31
+ count: number;
32
+ success_rate: number;
33
+ average_response_time_ms: number;
34
+ }[];
28
35
  }
29
- export interface CribopsQueueMessage {
30
- id: number;
31
- correlation_id: string;
32
- queue_name: string;
33
- data: {
34
- data: string;
35
- params: IDataObject;
36
- headers: IDataObject;
36
+ export interface CribopsWebhookStore extends IDataObject {
37
+ webhook_id: string;
38
+ destination_url: string;
39
+ payload: IDataObject;
40
+ headers?: IDataObject;
41
+ priority: 'low' | 'normal' | 'high';
42
+ max_retries: number;
43
+ retry_delay: number;
44
+ rate_limit: number;
45
+ timeout: number;
46
+ authentication?: {
47
+ type: 'none' | 'bearer' | 'basic' | 'apikey';
48
+ value: string;
37
49
  };
38
- inserted_at: string;
39
- }
40
- export interface CribopsWebhookEntity {
41
- id: string;
42
- name: string;
43
- description?: string;
44
- type: 'N8N' | 'GHL_API' | 'GENERIC';
45
- status: 'active' | 'inactive';
46
- linked_workflow_id?: string;
47
- linked_workflow_name?: string;
48
- organization_id: string;
49
- created_at: string;
50
- updated_at: string;
51
50
  }
52
51
  export declare class CribopsHttp {
53
52
  private config;
54
53
  constructor(config: CribopsHttpConfig);
55
54
  private makeRequest;
56
- getAgents(): Promise<CribopsAgent[]>;
57
- getAgent(agentId: string): Promise<CribopsAgent>;
58
- sendMessage(agentId: string, message: Partial<CribopsWebhookMessage>): Promise<CribopsWebhookMessage>;
59
- downloadFile(fileUrl: string): Promise<Buffer>;
60
- validateWebhook(payload: any, signature: string): Promise<boolean>;
61
- testConnection(): Promise<boolean>;
62
- sendTypingIndicator(agentId: string, conversationId: string, typing: boolean): Promise<any>;
63
- pollQueue(tenantId: string, limit?: number, queueName?: string): Promise<CribopsQueueMessage[]>;
64
- acknowledgeMessages(tenantId: string, messageIds: number[]): Promise<{
55
+ storeWebhook(data: CribopsWebhookStore): Promise<{
56
+ webhook_id: string;
65
57
  status: string;
66
- deleted_count: number;
67
58
  }>;
68
- failMessages(tenantId: string, messageIds: number[], errorMessage: string): Promise<{
59
+ getWebhookStatus(webhookId: string): Promise<CribopsWebhookDelivery>;
60
+ retryWebhook(webhookId: string): Promise<{
69
61
  status: string;
70
- updated_count: number;
62
+ retry_scheduled: boolean;
63
+ }>;
64
+ listDeliveries(filters?: {
65
+ status?: string;
66
+ destination_url?: string;
67
+ limit?: number;
68
+ offset?: number;
69
+ }): Promise<{
70
+ deliveries: CribopsWebhookDelivery[];
71
+ total: number;
71
72
  }>;
72
- getWebhooks(organizationId?: string): Promise<CribopsWebhookEntity[]>;
73
- linkWebhook(webhookId: string, linkData: {
73
+ getMetrics(timeRange: string): Promise<CribopsWebhookMetrics>;
74
+ registerWebhookEndpoint(config: {
75
+ path: string;
74
76
  workflow_id: string;
77
+ workflow_name: string;
75
78
  webhook_url: string;
76
79
  test_webhook_url: string;
80
+ store_webhook: boolean;
81
+ acknowledge_immediately: boolean;
82
+ enable_deduplication?: boolean;
83
+ deduplication_window?: number;
84
+ enable_rate_limit?: boolean;
85
+ rate_limit?: number;
86
+ allowed_ips?: string[];
87
+ metadata?: IDataObject;
88
+ }): Promise<{
89
+ endpoint_id: string;
90
+ status: string;
91
+ }>;
92
+ unregisterWebhookEndpoint(path: string): Promise<{
93
+ status: string;
94
+ }>;
95
+ receiveWebhook(data: {
96
+ path: string;
97
+ headers?: IDataObject;
98
+ query?: IDataObject;
99
+ body: IDataObject;
100
+ metadata?: IDataObject;
101
+ source_ip?: string;
102
+ }): Promise<{
103
+ webhook_id: string;
104
+ status: string;
105
+ }>;
106
+ replayWebhook(webhookId: string, options?: {
107
+ destination_url?: string;
108
+ headers?: IDataObject;
109
+ }): Promise<{
110
+ status: string;
111
+ delivery_id: string;
112
+ }>;
113
+ testConnection(): Promise<boolean>;
114
+ reportError(data: {
115
+ webhook_id: string;
116
+ error: {
117
+ message: string;
118
+ type: string;
119
+ stack_trace?: string;
120
+ node_name?: string;
121
+ retry_recommended: boolean;
122
+ timestamp: string;
123
+ workflow_id?: string;
124
+ workflow_name?: string;
125
+ };
126
+ }): Promise<{
127
+ status: string;
128
+ error_id: string;
129
+ }>;
130
+ reportPerformance(data: {
131
+ webhook_id: string;
132
+ metrics: {
133
+ processing_time_ms: number;
134
+ memory_usage_mb?: number;
135
+ items_processed: number;
136
+ api_calls?: number;
137
+ success: boolean;
138
+ timestamp: string;
139
+ workflow_id?: string;
140
+ workflow_name?: string;
141
+ };
142
+ }): Promise<{
143
+ status: string;
144
+ metric_id: string;
145
+ }>;
146
+ sendCallback(data: {
147
+ webhook_id: string;
148
+ type: 'success' | 'failure' | 'partial';
149
+ data: IDataObject;
150
+ summary?: string;
151
+ timestamp: string;
152
+ workflow_id?: string;
153
+ workflow_name?: string;
154
+ }): Promise<{
155
+ status: string;
156
+ callback_id: string;
157
+ }>;
158
+ sendProgress(data: {
159
+ webhook_id: string;
160
+ progress: {
161
+ percentage: number;
162
+ message?: string;
163
+ items_completed?: number;
164
+ total_items?: number;
165
+ timestamp: string;
166
+ };
167
+ }): Promise<{
168
+ status: string;
169
+ progress_id: string;
170
+ }>;
171
+ analyzeWorkflow(data: {
172
+ workflow_id: string;
173
+ workflow_name: string;
174
+ metrics?: {
175
+ avg_execution_time_ms: number;
176
+ daily_executions: number;
177
+ failure_rate: number;
178
+ node_count: number;
179
+ };
180
+ workflow_definition?: {
181
+ nodes: any[];
182
+ connections: any;
183
+ };
184
+ }): Promise<{
185
+ status: string;
186
+ recommendations: Array<{
187
+ type: string;
188
+ priority: 'high' | 'medium' | 'low';
189
+ description: string;
190
+ estimated_improvement?: string;
191
+ }>;
192
+ optimization_potential: {
193
+ scalability_score: number;
194
+ parallelization_opportunities: number;
195
+ estimated_cost_reduction?: string;
196
+ };
197
+ }>;
198
+ registerN8NEndpoint(config: {
199
+ webhook_path: string;
200
+ n8n_webhook_url: string;
201
+ test_webhook_url?: string;
202
+ workflow_id?: string;
77
203
  workflow_name: string;
78
- }): Promise<any>;
79
- unlinkWebhook(webhookId: string): Promise<any>;
204
+ report_performance?: boolean;
205
+ report_errors?: boolean;
206
+ signature_secret?: string | null;
207
+ }): Promise<{
208
+ status: string;
209
+ endpoint_id: string;
210
+ }>;
211
+ unregisterN8NEndpoint(webhookPath: string): Promise<{
212
+ status: string;
213
+ }>;
80
214
  request<T = any>(method: IHttpRequestMethods, endpoint: string, data?: IDataObject, options?: Partial<IHttpRequestOptions>): Promise<T>;
81
215
  }
@@ -11,10 +11,10 @@ class CribopsHttp {
11
11
  }
12
12
  async makeRequest(method, endpoint, data, options) {
13
13
  let url = `${this.config.baseUrl}${endpoint}`;
14
- // Handle query parameters
15
- if (method === 'GET' && data?.params) {
14
+ // Handle query parameters for GET requests
15
+ if (method === 'GET' && data && Object.keys(data).length > 0) {
16
16
  const params = new URLSearchParams();
17
- Object.entries(data.params).forEach(([key, value]) => {
17
+ Object.entries(data).forEach(([key, value]) => {
18
18
  if (value !== undefined && value !== null) {
19
19
  params.append(key, String(value));
20
20
  }
@@ -23,7 +23,8 @@ class CribopsHttp {
23
23
  if (queryString) {
24
24
  url += `?${queryString}`;
25
25
  }
26
- delete data.params;
26
+ // Clear data for GET requests as params are in URL
27
+ data = undefined;
27
28
  }
28
29
  const requestHeaders = {
29
30
  'Authorization': `Bearer ${this.config.apiToken}`,
@@ -42,8 +43,17 @@ class CribopsHttp {
42
43
  body: (method !== 'GET' && data) ? JSON.stringify(data) : undefined,
43
44
  });
44
45
  if (!response.ok) {
45
- const errorText = await response.text();
46
- throw new Error(`HTTP ${response.status}: ${errorText}`);
46
+ let errorText = await response.text();
47
+ let errorDetail = '';
48
+ // Try to parse error response as JSON
49
+ try {
50
+ const errorJson = JSON.parse(errorText);
51
+ errorDetail = errorJson.message || errorJson.error || errorText;
52
+ }
53
+ catch {
54
+ errorDetail = errorText;
55
+ }
56
+ throw new Error(`HTTP ${response.status}: ${errorDetail}`);
47
57
  }
48
58
  const result = await response.json();
49
59
  return result;
@@ -52,137 +62,152 @@ class CribopsHttp {
52
62
  throw new Error(`Request failed: ${error}`);
53
63
  }
54
64
  }
55
- async getAgents() {
65
+ // Webhook Store & Forward Operations
66
+ async storeWebhook(data) {
56
67
  try {
57
- const response = await this.makeRequest('GET', '/api/v1/agents');
58
- return response.agents || [];
68
+ return await this.makeRequest('POST', '/api/v1/webhooks/store', data);
59
69
  }
60
70
  catch (error) {
61
- throw new Error(`Failed to fetch agents: ${error}`);
71
+ throw new Error(`Failed to store webhook: ${error}`);
62
72
  }
63
73
  }
64
- async getAgent(agentId) {
74
+ async getWebhookStatus(webhookId) {
65
75
  try {
66
- const response = await this.makeRequest('GET', `/api/v1/agents/${agentId}`);
67
- return response.agent;
76
+ return await this.makeRequest('GET', `/api/v1/webhooks/${webhookId}/status`);
68
77
  }
69
78
  catch (error) {
70
- throw new Error(`Failed to fetch agent ${agentId}: ${error}`);
79
+ throw new Error(`Failed to get webhook status: ${error}`);
71
80
  }
72
81
  }
73
- async sendMessage(agentId, message) {
82
+ async retryWebhook(webhookId) {
74
83
  try {
75
- const response = await this.makeRequest('POST', `/webhooks/agents/${agentId}/message`, message);
76
- return response.message;
84
+ return await this.makeRequest('POST', `/api/v1/webhooks/${webhookId}/retry`);
77
85
  }
78
86
  catch (error) {
79
- throw new Error(`Failed to send message to agent ${agentId}: ${error}`);
87
+ throw new Error(`Failed to retry webhook: ${error}`);
80
88
  }
81
89
  }
82
- async downloadFile(fileUrl) {
90
+ async listDeliveries(filters) {
83
91
  try {
84
- const response = await fetch(fileUrl, {
85
- headers: {
86
- 'Authorization': `Bearer ${this.config.apiToken}`,
87
- },
88
- });
89
- if (!response.ok) {
90
- const errorText = await response.text();
91
- throw new Error(`HTTP ${response.status}: ${errorText}`);
92
- }
93
- const arrayBuffer = await response.arrayBuffer();
94
- return Buffer.from(arrayBuffer);
92
+ return await this.makeRequest('GET', '/api/v1/webhooks/deliveries', filters);
93
+ }
94
+ catch (error) {
95
+ throw new Error(`Failed to list webhook deliveries: ${error}`);
96
+ }
97
+ }
98
+ async getMetrics(timeRange) {
99
+ try {
100
+ return await this.makeRequest('GET', `/api/v1/webhooks/metrics`, { range: timeRange });
95
101
  }
96
102
  catch (error) {
97
- throw new Error(`Failed to download file: ${error}`);
103
+ throw new Error(`Failed to get webhook metrics: ${error}`);
98
104
  }
99
105
  }
100
- async validateWebhook(payload, signature) {
101
- // Implement webhook signature validation if needed
102
- // This would typically use HMAC verification
103
- return true;
106
+ // Webhook Endpoint Registration (for trigger nodes)
107
+ async registerWebhookEndpoint(config) {
108
+ try {
109
+ return await this.makeRequest('POST', '/api/v1/webhook-endpoints/register', config);
110
+ }
111
+ catch (error) {
112
+ throw new Error(`Failed to register webhook endpoint: ${error}`);
113
+ }
104
114
  }
115
+ async unregisterWebhookEndpoint(path) {
116
+ try {
117
+ return await this.makeRequest('DELETE', `/api/v1/webhook-endpoints/${path}`);
118
+ }
119
+ catch (error) {
120
+ throw new Error(`Failed to unregister webhook endpoint: ${error}`);
121
+ }
122
+ }
123
+ // Webhook Reception (for storing incoming webhooks)
124
+ async receiveWebhook(data) {
125
+ try {
126
+ return await this.makeRequest('POST', '/api/v1/webhooks/receive', data);
127
+ }
128
+ catch (error) {
129
+ throw new Error(`Failed to receive webhook: ${error}`);
130
+ }
131
+ }
132
+ // Webhook Replay
133
+ async replayWebhook(webhookId, options) {
134
+ try {
135
+ return await this.makeRequest('POST', `/api/v1/webhooks/${webhookId}/replay`, options);
136
+ }
137
+ catch (error) {
138
+ throw new Error(`Failed to replay webhook: ${error}`);
139
+ }
140
+ }
141
+ // Test connection
105
142
  async testConnection() {
106
143
  try {
107
- await this.getAgents();
144
+ await this.makeRequest('GET', '/api/v1/health');
108
145
  return true;
109
146
  }
110
147
  catch (error) {
111
148
  return false;
112
149
  }
113
150
  }
114
- async sendTypingIndicator(agentId, conversationId, typing) {
151
+ // Error Reporting
152
+ async reportError(data) {
115
153
  try {
116
- const response = await this.makeRequest('POST', `/api/agents/${agentId}/callback`, {
117
- data: {
118
- typing: typing,
119
- },
120
- conversation_id: conversationId,
121
- callback_type: 'typing',
122
- });
123
- return response;
154
+ return await this.makeRequest('POST', '/api/v1/webhooks/report-error', data);
124
155
  }
125
156
  catch (error) {
126
- throw new Error(`Failed to send typing indicator for agent ${agentId}: ${error}`);
157
+ throw new Error(`Failed to report error: ${error}`);
127
158
  }
128
159
  }
129
- async pollQueue(tenantId, limit = 10, queueName) {
160
+ // Performance Metrics Reporting
161
+ async reportPerformance(data) {
130
162
  try {
131
- const params = { limit };
132
- if (queueName) {
133
- params.queue_name = queueName;
134
- }
135
- const url = `/api/queue/${tenantId}/poll?${new URLSearchParams(params).toString()}`;
136
- const response = await this.makeRequest('GET', url);
137
- return response;
163
+ return await this.makeRequest('POST', '/api/v1/webhooks/report-performance', data);
138
164
  }
139
165
  catch (error) {
140
- throw new Error(`Failed to poll queue for tenant ${tenantId}: ${error}`);
166
+ throw new Error(`Failed to report performance metrics: ${error}`);
141
167
  }
142
168
  }
143
- async acknowledgeMessages(tenantId, messageIds) {
169
+ // Send Callback for Long-Running Workflows
170
+ async sendCallback(data) {
144
171
  try {
145
- const response = await this.makeRequest('POST', `/api/queue/${tenantId}/acknowledge`, { message_ids: messageIds });
146
- return response;
172
+ return await this.makeRequest('POST', '/api/v1/webhooks/callback', data);
147
173
  }
148
174
  catch (error) {
149
- throw new Error(`Failed to acknowledge messages for tenant ${tenantId}: ${error}`);
175
+ throw new Error(`Failed to send callback: ${error}`);
150
176
  }
151
177
  }
152
- async failMessages(tenantId, messageIds, errorMessage) {
178
+ // Send Progress Update
179
+ async sendProgress(data) {
153
180
  try {
154
- const response = await this.makeRequest('POST', `/api/queue/${tenantId}/fail`, { message_ids: messageIds, error_message: errorMessage });
155
- return response;
181
+ return await this.makeRequest('POST', '/api/v1/webhooks/progress', data);
156
182
  }
157
183
  catch (error) {
158
- throw new Error(`Failed to mark messages as failed for tenant ${tenantId}: ${error}`);
184
+ throw new Error(`Failed to send progress update: ${error}`);
159
185
  }
160
186
  }
161
- // Webhook-specific methods
162
- async getWebhooks(organizationId) {
187
+ // Workflow Analysis
188
+ async analyzeWorkflow(data) {
163
189
  try {
164
- const params = organizationId ? { params: { organization_id: organizationId } } : undefined;
165
- const response = await this.makeRequest('GET', '/api/v1/webhooks', params);
166
- return response.data || [];
190
+ return await this.makeRequest('POST', '/api/v1/workflows/analyze', data);
167
191
  }
168
192
  catch (error) {
169
- throw new Error(`Failed to fetch webhooks: ${error}`);
193
+ throw new Error(`Failed to analyze workflow: ${error}`);
170
194
  }
171
195
  }
172
- async linkWebhook(webhookId, linkData) {
196
+ // N8N Endpoint Registration (Updated for new architecture)
197
+ async registerN8NEndpoint(config) {
173
198
  try {
174
- return await this.makeRequest('POST', `/api/v1/webhooks/${webhookId}/link`, linkData);
199
+ return await this.makeRequest('POST', '/api/v1/n8n-endpoints/register', config);
175
200
  }
176
201
  catch (error) {
177
- throw new Error(`Failed to link webhook: ${error}`);
202
+ throw new Error(`Failed to register N8N endpoint: ${error}`);
178
203
  }
179
204
  }
180
- async unlinkWebhook(webhookId) {
205
+ async unregisterN8NEndpoint(webhookPath) {
181
206
  try {
182
- return await this.makeRequest('DELETE', `/api/v1/webhooks/${webhookId}/link`);
207
+ return await this.makeRequest('DELETE', `/api/v1/n8n-endpoints/${webhookPath}`);
183
208
  }
184
209
  catch (error) {
185
- throw new Error(`Failed to unlink webhook: ${error}`);
210
+ throw new Error(`Failed to unregister N8N endpoint: ${error}`);
186
211
  }
187
212
  }
188
213
  // Generic request method for custom API calls
@@ -0,0 +1,138 @@
1
+ export interface HiveClientConfig {
2
+ host: string;
3
+ port: number;
4
+ password?: string;
5
+ tls?: boolean;
6
+ }
7
+ export interface HiveParallelHttpRequest {
8
+ url: string;
9
+ method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';
10
+ headers?: Record<string, string>;
11
+ body?: any;
12
+ }
13
+ export interface HiveParallelHttpResult {
14
+ url: string;
15
+ status: number | null;
16
+ body?: any;
17
+ error?: string;
18
+ time_ms: number;
19
+ }
20
+ export interface HiveCronConfig {
21
+ name: string;
22
+ expression: string;
23
+ webhook_url: string;
24
+ payload?: Record<string, any>;
25
+ timezone?: string;
26
+ }
27
+ export interface HiveCronInfo {
28
+ name: string;
29
+ expression: string;
30
+ webhook_url: string;
31
+ payload: Record<string, any>;
32
+ timezone: string;
33
+ enabled: boolean;
34
+ created_at: string;
35
+ next_run?: string;
36
+ }
37
+ export interface HiveFanoutResult {
38
+ endpoint: string;
39
+ status?: number;
40
+ success: boolean;
41
+ error?: string;
42
+ }
43
+ export interface HiveCircuitStatus {
44
+ service: string;
45
+ status: 'closed' | 'open' | 'half_open';
46
+ failure_count: number;
47
+ last_failure: string | null;
48
+ can_proceed: boolean;
49
+ }
50
+ export declare class HiveClient {
51
+ private redis;
52
+ private connected;
53
+ constructor(config: HiveClientConfig);
54
+ connect(): Promise<void>;
55
+ disconnect(): Promise<void>;
56
+ private execute;
57
+ ping(): Promise<{
58
+ pong: boolean;
59
+ timestamp: string;
60
+ }>;
61
+ info(): Promise<{
62
+ version: string;
63
+ accelerator: boolean;
64
+ oban_pro: boolean;
65
+ operations: string[];
66
+ dedup_stats: {
67
+ active_dedup_keys: number;
68
+ ttl_ms: number;
69
+ };
70
+ }>;
71
+ /**
72
+ * Execute multiple HTTP requests in parallel via Hive's Elixir Task.async_stream
73
+ */
74
+ parallelHttp(requests: HiveParallelHttpRequest[], options?: {
75
+ concurrency?: number;
76
+ timeout_ms?: number;
77
+ }): Promise<{
78
+ results: HiveParallelHttpResult[];
79
+ stats: {
80
+ total: number;
81
+ successful: number;
82
+ failed: number;
83
+ total_time_ms: number;
84
+ };
85
+ }>;
86
+ /**
87
+ * Schedule a dynamic cron job via Oban Pro
88
+ */
89
+ scheduleCron(config: HiveCronConfig): Promise<{
90
+ scheduled: boolean;
91
+ name: string;
92
+ expression: string;
93
+ timezone: string;
94
+ next_run: string | null;
95
+ }>;
96
+ /**
97
+ * Delete a dynamic cron job
98
+ */
99
+ deleteCron(name: string): Promise<{
100
+ deleted: boolean;
101
+ name: string;
102
+ }>;
103
+ /**
104
+ * List all dynamic cron jobs
105
+ */
106
+ listCrons(): Promise<{
107
+ crons: HiveCronInfo[];
108
+ count: number;
109
+ }>;
110
+ /**
111
+ * Fan-out a payload to multiple webhook endpoints in parallel
112
+ */
113
+ fanout(endpoints: string[], payload: Record<string, any>, options?: {
114
+ timeout_ms?: number;
115
+ }): Promise<{
116
+ results: HiveFanoutResult[];
117
+ stats: {
118
+ total: number;
119
+ successful: number;
120
+ failed: number;
121
+ total_time_ms: number;
122
+ };
123
+ }>;
124
+ /**
125
+ * Check if data is a duplicate (deduplication)
126
+ */
127
+ dedupCheck(data: Record<string, any>, options?: {
128
+ ttl_seconds?: number;
129
+ }): Promise<{
130
+ is_duplicate: boolean;
131
+ hash: string;
132
+ first_seen: string;
133
+ }>;
134
+ /**
135
+ * Check circuit breaker status and optionally record success/failure
136
+ */
137
+ circuitCheck(service: string, recordResult?: 'success' | 'failure'): Promise<HiveCircuitStatus>;
138
+ }