@robota-sdk/agent-plugin 3.0.0-beta.64
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/LICENSE +21 -0
- package/dist/node/index.cjs +1 -0
- package/dist/node/index.d.ts +1724 -0
- package/dist/node/index.d.ts.map +1 -0
- package/dist/node/index.js +2 -0
- package/dist/node/index.js.map +1 -0
- package/package.json +48 -0
- package/src/conversation-history/__tests__/conversation-history-plugin.test.ts +221 -0
- package/src/conversation-history/__tests__/history-storages.test.ts +115 -0
- package/src/conversation-history/conversation-history-helpers.ts +120 -0
- package/src/conversation-history/conversation-history-plugin.ts +294 -0
- package/src/conversation-history/index.ts +11 -0
- package/src/conversation-history/storages/database-storage.ts +96 -0
- package/src/conversation-history/storages/file-storage.ts +95 -0
- package/src/conversation-history/storages/index.ts +3 -0
- package/src/conversation-history/storages/memory-storage.ts +44 -0
- package/src/conversation-history/types.ts +64 -0
- package/src/error-handling/__tests__/error-handling-plugin.test.ts +201 -0
- package/src/error-handling/context-adapter.ts +48 -0
- package/src/error-handling/error-handling-helpers.ts +53 -0
- package/src/error-handling/error-handling-plugin.ts +293 -0
- package/src/error-handling/index.ts +9 -0
- package/src/error-handling/types.ts +82 -0
- package/src/execution-analytics/__tests__/execution-analytics-plugin.test.ts +224 -0
- package/src/execution-analytics/analytics-aggregation.ts +88 -0
- package/src/execution-analytics/execution-analytics-helpers.ts +83 -0
- package/src/execution-analytics/execution-analytics-plugin.ts +315 -0
- package/src/execution-analytics/index.ts +9 -0
- package/src/execution-analytics/types.ts +97 -0
- package/src/index.ts +8 -0
- package/src/limits/__tests__/limits-plugin.test.ts +712 -0
- package/src/limits/index.ts +9 -0
- package/src/limits/limits-helpers.ts +185 -0
- package/src/limits/limits-plugin.ts +196 -0
- package/src/limits/types.ts +73 -0
- package/src/limits/validation.ts +81 -0
- package/src/logging/__tests__/formatters.test.ts +48 -0
- package/src/logging/__tests__/logging-plugin.test.ts +464 -0
- package/src/logging/__tests__/logging-storages.test.ts +95 -0
- package/src/logging/formatters.ts +28 -0
- package/src/logging/index.ts +15 -0
- package/src/logging/logging-helpers.ts +223 -0
- package/src/logging/logging-plugin.ts +288 -0
- package/src/logging/storages/console-storage.ts +44 -0
- package/src/logging/storages/file-storage.ts +44 -0
- package/src/logging/storages/index.ts +4 -0
- package/src/logging/storages/remote-storage.ts +78 -0
- package/src/logging/storages/silent-storage.ts +18 -0
- package/src/logging/types.ts +106 -0
- package/src/performance/__tests__/memory-storage.test.ts +86 -0
- package/src/performance/__tests__/performance-plugin.test.ts +208 -0
- package/src/performance/__tests__/system-metrics-collector.test.ts +33 -0
- package/src/performance/collectors/system-metrics-collector.ts +69 -0
- package/src/performance/index.ts +12 -0
- package/src/performance/performance-helpers.ts +86 -0
- package/src/performance/performance-plugin.ts +274 -0
- package/src/performance/storages/index.ts +1 -0
- package/src/performance/storages/memory-storage.ts +88 -0
- package/src/performance/types.ts +160 -0
- package/src/usage/__tests__/aggregate-usage-stats.test.ts +136 -0
- package/src/usage/__tests__/memory-storage.test.ts +83 -0
- package/src/usage/__tests__/silent-storage.test.ts +44 -0
- package/src/usage/__tests__/usage-plugin-helpers.test.ts +155 -0
- package/src/usage/__tests__/usage-plugin.test.ts +358 -0
- package/src/usage/aggregate-usage-stats.ts +142 -0
- package/src/usage/index.ts +14 -0
- package/src/usage/storages/file-storage.ts +115 -0
- package/src/usage/storages/index.ts +4 -0
- package/src/usage/storages/memory-storage.ts +61 -0
- package/src/usage/storages/remote-storage.ts +143 -0
- package/src/usage/storages/silent-storage.ts +38 -0
- package/src/usage/types.ts +132 -0
- package/src/usage/usage-plugin-helpers.ts +116 -0
- package/src/usage/usage-plugin.ts +296 -0
- package/src/webhook/__tests__/webhook-plugin.test.ts +560 -0
- package/src/webhook/http-client.ts +141 -0
- package/src/webhook/index.ts +9 -0
- package/src/webhook/transformer.ts +209 -0
- package/src/webhook/types.ts +201 -0
- package/src/webhook/webhook-helpers.ts +60 -0
- package/src/webhook/webhook-plugin.ts +298 -0
- package/src/webhook/webhook-queue.ts +148 -0
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Webhook data transformation utilities
|
|
3
|
+
* Converts base plugin types to webhook-specific types safely
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type {
|
|
7
|
+
IPluginExecutionContext,
|
|
8
|
+
IPluginExecutionResult,
|
|
9
|
+
TLoggerData,
|
|
10
|
+
TUniversalValue,
|
|
11
|
+
} from '@robota-sdk/agent-core';
|
|
12
|
+
import type {
|
|
13
|
+
IWebhookExecutionContext,
|
|
14
|
+
IWebhookExecutionResult,
|
|
15
|
+
IWebhookEventData,
|
|
16
|
+
IWebhookExecutionData,
|
|
17
|
+
IWebhookConversationData,
|
|
18
|
+
IWebhookToolData,
|
|
19
|
+
IWebhookErrorData,
|
|
20
|
+
IWebhookToolCallData,
|
|
21
|
+
TWebhookEventName,
|
|
22
|
+
} from './types';
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Webhook data transformer utility class
|
|
26
|
+
*/
|
|
27
|
+
export class WebhookTransformer {
|
|
28
|
+
/**
|
|
29
|
+
* Convert IPluginExecutionContext to WebhookExecutionContext
|
|
30
|
+
*/
|
|
31
|
+
static contextToWebhook(context: IPluginExecutionContext): IWebhookExecutionContext {
|
|
32
|
+
return {
|
|
33
|
+
executionId: context.executionId,
|
|
34
|
+
sessionId: context.sessionId,
|
|
35
|
+
userId: context.userId,
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
/**
|
|
40
|
+
* Convert IPluginExecutionResult to WebhookExecutionResult
|
|
41
|
+
*/
|
|
42
|
+
static resultToWebhook(result: IPluginExecutionResult): IWebhookExecutionResult {
|
|
43
|
+
return {
|
|
44
|
+
response: result.response,
|
|
45
|
+
content: result.content,
|
|
46
|
+
duration: result.duration,
|
|
47
|
+
tokensUsed: result.tokensUsed,
|
|
48
|
+
toolsExecuted: result.toolsExecuted,
|
|
49
|
+
success: result.success,
|
|
50
|
+
usage: result.usage,
|
|
51
|
+
toolCalls: result.toolCalls,
|
|
52
|
+
error: result.error,
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/**
|
|
57
|
+
* Create execution event data
|
|
58
|
+
*/
|
|
59
|
+
static createExecutionData(
|
|
60
|
+
context: IWebhookExecutionContext,
|
|
61
|
+
result: IWebhookExecutionResult,
|
|
62
|
+
): IWebhookEventData {
|
|
63
|
+
const executionData: IWebhookExecutionData = {
|
|
64
|
+
response: result.response || undefined,
|
|
65
|
+
duration: result.duration || undefined,
|
|
66
|
+
tokensUsed: result.tokensUsed || undefined,
|
|
67
|
+
toolsExecuted: result.toolsExecuted || undefined,
|
|
68
|
+
success: result.success !== undefined ? result.success : undefined,
|
|
69
|
+
};
|
|
70
|
+
|
|
71
|
+
return {
|
|
72
|
+
executionId: context.executionId,
|
|
73
|
+
sessionId: context.sessionId,
|
|
74
|
+
userId: context.userId,
|
|
75
|
+
result: executionData,
|
|
76
|
+
};
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
/**
|
|
80
|
+
* Create conversation event data
|
|
81
|
+
*/
|
|
82
|
+
static createConversationData(
|
|
83
|
+
context: IWebhookExecutionContext,
|
|
84
|
+
result: IWebhookExecutionResult,
|
|
85
|
+
): IWebhookEventData {
|
|
86
|
+
const toolCalls: IWebhookToolCallData[] =
|
|
87
|
+
result.toolCalls?.map((call) => ({
|
|
88
|
+
id: call.id || '',
|
|
89
|
+
name: call.name || '',
|
|
90
|
+
arguments: JSON.stringify(call.arguments || {}),
|
|
91
|
+
result: String(call.result || ''),
|
|
92
|
+
})) || [];
|
|
93
|
+
|
|
94
|
+
const conversationData: IWebhookConversationData = {
|
|
95
|
+
response: result.content || result.response || undefined,
|
|
96
|
+
tokensUsed: result.usage?.totalTokens || result.tokensUsed || undefined,
|
|
97
|
+
toolCalls: toolCalls.length > 0 ? toolCalls : undefined,
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
return {
|
|
101
|
+
executionId: context.executionId,
|
|
102
|
+
sessionId: context.sessionId,
|
|
103
|
+
userId: context.userId,
|
|
104
|
+
conversation: conversationData,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
/**
|
|
109
|
+
* Create tool execution event data
|
|
110
|
+
*
|
|
111
|
+
* REASON: Tool result structure varies by tool type and provider, needs flexible handling for webhook processing
|
|
112
|
+
* ALTERNATIVES_CONSIDERED:
|
|
113
|
+
* 1. Strict tool result interfaces (breaks tool compatibility)
|
|
114
|
+
* 2. Union types (insufficient for dynamic tool results)
|
|
115
|
+
* 3. Generic constraints (too complex for webhook processing)
|
|
116
|
+
* 4. Interface definitions (too rigid for varied tool results)
|
|
117
|
+
* 5. Type assertions (decreases type safety)
|
|
118
|
+
* TODO: Consider standardized tool result interface across tools
|
|
119
|
+
*/
|
|
120
|
+
static createToolData(
|
|
121
|
+
context: IWebhookExecutionContext,
|
|
122
|
+
toolResult: TLoggerData,
|
|
123
|
+
): IWebhookEventData {
|
|
124
|
+
// Safely extract tool data from result
|
|
125
|
+
const toolName = this.safeGetProperty(toolResult, 'toolName') || 'unknown';
|
|
126
|
+
const toolId =
|
|
127
|
+
this.safeGetProperty(toolResult, 'toolId') ||
|
|
128
|
+
this.safeGetProperty(toolResult, 'executionId') ||
|
|
129
|
+
'unknown';
|
|
130
|
+
const hasError = this.safeGetProperty(toolResult, 'error');
|
|
131
|
+
const duration = this.safeGetProperty(toolResult, 'duration');
|
|
132
|
+
const result = this.safeGetProperty(toolResult, 'result');
|
|
133
|
+
|
|
134
|
+
const toolData: IWebhookToolData = {
|
|
135
|
+
name: String(toolName),
|
|
136
|
+
id: String(toolId),
|
|
137
|
+
success: !hasError,
|
|
138
|
+
duration: typeof duration === 'number' ? duration : undefined,
|
|
139
|
+
result: hasError ? undefined : String(result || ''),
|
|
140
|
+
error: hasError
|
|
141
|
+
? hasError instanceof Error
|
|
142
|
+
? hasError.message
|
|
143
|
+
: String(hasError)
|
|
144
|
+
: undefined,
|
|
145
|
+
};
|
|
146
|
+
|
|
147
|
+
return {
|
|
148
|
+
executionId: context.executionId,
|
|
149
|
+
sessionId: context.sessionId,
|
|
150
|
+
userId: context.userId,
|
|
151
|
+
tool: toolData,
|
|
152
|
+
};
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
/**
|
|
156
|
+
* Create error event data
|
|
157
|
+
*/
|
|
158
|
+
static createErrorData(context: IWebhookExecutionContext, error: Error): IWebhookEventData {
|
|
159
|
+
const errorData: IWebhookErrorData = {
|
|
160
|
+
message: error instanceof Error ? error.message : String(error),
|
|
161
|
+
stack: error instanceof Error ? error.stack : undefined,
|
|
162
|
+
type: error instanceof Error ? error.constructor.name : 'Unknown',
|
|
163
|
+
context: context
|
|
164
|
+
? {
|
|
165
|
+
executionId: context.executionId || '',
|
|
166
|
+
sessionId: context.sessionId || '',
|
|
167
|
+
userId: context.userId || '',
|
|
168
|
+
}
|
|
169
|
+
: undefined,
|
|
170
|
+
};
|
|
171
|
+
|
|
172
|
+
return {
|
|
173
|
+
executionId: context.executionId,
|
|
174
|
+
sessionId: context.sessionId,
|
|
175
|
+
userId: context.userId,
|
|
176
|
+
error: errorData,
|
|
177
|
+
};
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
/**
|
|
181
|
+
* Safely get property from object (handles index signature issues)
|
|
182
|
+
*
|
|
183
|
+
* REASON: Safe property access for webhook data transformation needs flexible input/output types
|
|
184
|
+
* ALTERNATIVES_CONSIDERED:
|
|
185
|
+
* 1. Strict object types (breaks dynamic property access)
|
|
186
|
+
* 2. Union types (insufficient for property extraction)
|
|
187
|
+
* 3. Generic constraints (too complex for simple property access)
|
|
188
|
+
* 4. Interface definitions (too rigid for dynamic objects)
|
|
189
|
+
* 5. Type assertions (decreases type safety)
|
|
190
|
+
* TODO: Consider typed property access if patterns emerge
|
|
191
|
+
*/
|
|
192
|
+
private static safeGetProperty(obj: TLoggerData, key: string): TUniversalValue | Date | Error {
|
|
193
|
+
if (!obj || typeof obj !== 'object' || obj === null || Array.isArray(obj)) {
|
|
194
|
+
return undefined;
|
|
195
|
+
}
|
|
196
|
+
return obj[key];
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Default payload transformer for webhook events
|
|
201
|
+
*/
|
|
202
|
+
static defaultPayloadTransformer(
|
|
203
|
+
_event: TWebhookEventName,
|
|
204
|
+
data: IWebhookEventData,
|
|
205
|
+
): IWebhookEventData {
|
|
206
|
+
// Simply return the data as-is for the default transformer
|
|
207
|
+
return data;
|
|
208
|
+
}
|
|
209
|
+
}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
import type { TExecutionEventName } from '@robota-sdk/agent-core';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Webhook plugin type definitions
|
|
5
|
+
* Clean separation of concerns with domain-specific types
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
export type TWebhookEventName =
|
|
9
|
+
| TExecutionEventName
|
|
10
|
+
| 'conversation.complete'
|
|
11
|
+
| 'tool.executed'
|
|
12
|
+
| 'error.occurred'
|
|
13
|
+
| 'custom';
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Base webhook context data
|
|
17
|
+
*/
|
|
18
|
+
export interface IWebhookContextData {
|
|
19
|
+
executionId?: string | undefined;
|
|
20
|
+
sessionId?: string | undefined;
|
|
21
|
+
userId?: string | undefined;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Execution result data for webhooks
|
|
26
|
+
*/
|
|
27
|
+
export interface IWebhookExecutionData {
|
|
28
|
+
response?: string | undefined;
|
|
29
|
+
duration?: number | undefined;
|
|
30
|
+
tokensUsed?: number | undefined;
|
|
31
|
+
toolsExecuted?: number | undefined;
|
|
32
|
+
success?: boolean | undefined;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* Conversation result data for webhooks
|
|
37
|
+
*/
|
|
38
|
+
export interface IWebhookConversationData {
|
|
39
|
+
response?: string | undefined;
|
|
40
|
+
tokensUsed?: number | undefined;
|
|
41
|
+
toolCalls?: IWebhookToolCallData[] | undefined;
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
/**
|
|
45
|
+
* Tool call data for webhooks
|
|
46
|
+
*/
|
|
47
|
+
export interface IWebhookToolCallData {
|
|
48
|
+
id: string;
|
|
49
|
+
name: string;
|
|
50
|
+
arguments: string;
|
|
51
|
+
result: string;
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
/**
|
|
55
|
+
* Tool execution data for webhooks
|
|
56
|
+
*/
|
|
57
|
+
export interface IWebhookToolData {
|
|
58
|
+
name: string;
|
|
59
|
+
id: string;
|
|
60
|
+
success: boolean;
|
|
61
|
+
duration?: number | undefined;
|
|
62
|
+
result?: string | undefined;
|
|
63
|
+
error?: string | undefined;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Error data for webhooks
|
|
68
|
+
*/
|
|
69
|
+
export interface IWebhookErrorData {
|
|
70
|
+
message: string;
|
|
71
|
+
stack?: string | undefined;
|
|
72
|
+
context?: Record<string, string | number | boolean> | undefined;
|
|
73
|
+
type?: string | undefined;
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
/**
|
|
77
|
+
* Complete webhook event data structure
|
|
78
|
+
*/
|
|
79
|
+
export interface IWebhookEventData extends IWebhookContextData {
|
|
80
|
+
result?: IWebhookExecutionData | undefined;
|
|
81
|
+
conversation?: IWebhookConversationData | undefined;
|
|
82
|
+
tool?: IWebhookToolData | undefined;
|
|
83
|
+
error?: IWebhookErrorData | undefined;
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
/**
|
|
87
|
+
* Webhook metadata for additional context
|
|
88
|
+
*/
|
|
89
|
+
export type TWebhookMetadata = Record<string, string | number | boolean | Date | string[]>;
|
|
90
|
+
|
|
91
|
+
/**
|
|
92
|
+
* Webhook execution context (simplified from base types)
|
|
93
|
+
*/
|
|
94
|
+
export interface IWebhookExecutionContext {
|
|
95
|
+
executionId?: string | undefined;
|
|
96
|
+
sessionId?: string | undefined;
|
|
97
|
+
userId?: string | undefined;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/**
|
|
101
|
+
* Webhook execution result (simplified from base types)
|
|
102
|
+
*/
|
|
103
|
+
export interface IWebhookExecutionResult {
|
|
104
|
+
response?: string | undefined;
|
|
105
|
+
content?: string | undefined;
|
|
106
|
+
duration?: number | undefined;
|
|
107
|
+
tokensUsed?: number | undefined;
|
|
108
|
+
toolsExecuted?: number | undefined;
|
|
109
|
+
success?: boolean | undefined;
|
|
110
|
+
usage?: { totalTokens?: number | undefined } | undefined;
|
|
111
|
+
// SSOT: reuse the canonical toolCalls shape from IPluginExecutionResult.
|
|
112
|
+
toolCalls?: import('@robota-sdk/agent-core').IPluginExecutionResult['toolCalls'];
|
|
113
|
+
results?:
|
|
114
|
+
| Array<{
|
|
115
|
+
toolName?: string | undefined;
|
|
116
|
+
toolId?: string | undefined;
|
|
117
|
+
executionId?: string | undefined;
|
|
118
|
+
error?: Error | undefined;
|
|
119
|
+
duration?: number | undefined;
|
|
120
|
+
result?: string | number | boolean | undefined;
|
|
121
|
+
}>
|
|
122
|
+
| undefined;
|
|
123
|
+
error?: Error | undefined;
|
|
124
|
+
}
|
|
125
|
+
|
|
126
|
+
/**
|
|
127
|
+
* Webhook payload structure
|
|
128
|
+
*/
|
|
129
|
+
export interface IWebhookPayload {
|
|
130
|
+
event: TWebhookEventName;
|
|
131
|
+
timestamp: string;
|
|
132
|
+
executionId?: string;
|
|
133
|
+
sessionId?: string;
|
|
134
|
+
userId?: string;
|
|
135
|
+
data: IWebhookEventData;
|
|
136
|
+
metadata?: TWebhookMetadata;
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/**
|
|
140
|
+
* Webhook endpoint configuration
|
|
141
|
+
*/
|
|
142
|
+
export interface IWebhookEndpoint {
|
|
143
|
+
url: string;
|
|
144
|
+
headers?: Record<string, string>;
|
|
145
|
+
events?: TWebhookEventName[];
|
|
146
|
+
retries?: number;
|
|
147
|
+
timeout?: number;
|
|
148
|
+
secret?: string;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
import type { IPluginOptions, IPluginStats } from '@robota-sdk/agent-core';
|
|
152
|
+
|
|
153
|
+
/**
|
|
154
|
+
* Webhook plugin configuration options
|
|
155
|
+
*/
|
|
156
|
+
export interface IWebhookPluginOptions extends IPluginOptions {
|
|
157
|
+
/** Webhook endpoints */
|
|
158
|
+
endpoints: IWebhookEndpoint[];
|
|
159
|
+
/** Events to send webhooks for */
|
|
160
|
+
events?: TWebhookEventName[];
|
|
161
|
+
/** Default timeout for webhook requests */
|
|
162
|
+
defaultTimeout?: number;
|
|
163
|
+
/** Default retry attempts */
|
|
164
|
+
defaultRetries?: number;
|
|
165
|
+
/** Whether to use async sending */
|
|
166
|
+
async?: boolean;
|
|
167
|
+
/** Maximum concurrent webhook requests */
|
|
168
|
+
maxConcurrency?: number;
|
|
169
|
+
/** Whether to batch webhook requests */
|
|
170
|
+
batching?: {
|
|
171
|
+
enabled: boolean;
|
|
172
|
+
maxSize: number;
|
|
173
|
+
flushInterval: number;
|
|
174
|
+
};
|
|
175
|
+
/** Custom payload transformer */
|
|
176
|
+
payloadTransformer?: (event: TWebhookEventName, data: IWebhookEventData) => IWebhookEventData;
|
|
177
|
+
}
|
|
178
|
+
|
|
179
|
+
/**
|
|
180
|
+
* Webhook plugin statistics
|
|
181
|
+
*/
|
|
182
|
+
export interface IWebhookPluginStats extends IPluginStats {
|
|
183
|
+
endpointCount: number;
|
|
184
|
+
queueLength: number;
|
|
185
|
+
batchQueueLength: number;
|
|
186
|
+
activeConcurrency: number;
|
|
187
|
+
supportedEvents: TWebhookEventName[];
|
|
188
|
+
totalSent: number;
|
|
189
|
+
totalErrors: number;
|
|
190
|
+
averageResponseTime: number;
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Internal webhook request structure
|
|
195
|
+
*/
|
|
196
|
+
export interface IWebhookRequest {
|
|
197
|
+
endpoint: IWebhookEndpoint;
|
|
198
|
+
payload: IWebhookPayload;
|
|
199
|
+
attempt: number;
|
|
200
|
+
timestamp: Date;
|
|
201
|
+
}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Webhook Plugin - Validation helpers and event constants.
|
|
3
|
+
*
|
|
4
|
+
* Extracted from webhook-plugin.ts to keep each file under 300 lines.
|
|
5
|
+
* @internal
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
import { PluginError, EXECUTION_EVENTS, EXECUTION_EVENT_PREFIX } from '@robota-sdk/agent-core';
|
|
9
|
+
import type { TWebhookEventName, IWebhookEndpoint } from './types';
|
|
10
|
+
|
|
11
|
+
/** Local execution event names used by WebhookPlugin. @internal */
|
|
12
|
+
export const WEBHOOK_EXEC_EVENTS = {
|
|
13
|
+
START: `${EXECUTION_EVENT_PREFIX}.${EXECUTION_EVENTS.START}` as TWebhookEventName,
|
|
14
|
+
COMPLETE: `${EXECUTION_EVENT_PREFIX}.${EXECUTION_EVENTS.COMPLETE}` as TWebhookEventName,
|
|
15
|
+
ERROR: `${EXECUTION_EVENT_PREFIX}.${EXECUTION_EVENTS.ERROR}` as TWebhookEventName,
|
|
16
|
+
} as const;
|
|
17
|
+
|
|
18
|
+
export const WEBHOOK_CONV_EVENTS = {
|
|
19
|
+
COMPLETE: 'conversation.complete' as TWebhookEventName,
|
|
20
|
+
} as const;
|
|
21
|
+
export const WEBHOOK_TOOL_EVENTS = { EXECUTED: 'tool.executed' as TWebhookEventName } as const;
|
|
22
|
+
export const WEBHOOK_ERROR_EVENTS = { OCCURRED: 'error.occurred' as TWebhookEventName } as const;
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* Validate all configured webhook endpoints. Throws PluginError for any
|
|
26
|
+
* invalid URL or unsupported event name. @internal
|
|
27
|
+
*/
|
|
28
|
+
export function validateWebhookEndpoints(
|
|
29
|
+
endpoints: IWebhookEndpoint[],
|
|
30
|
+
pluginName: string,
|
|
31
|
+
validEvents: TWebhookEventName[],
|
|
32
|
+
): void {
|
|
33
|
+
for (const endpoint of endpoints) {
|
|
34
|
+
if (!endpoint.url) {
|
|
35
|
+
throw new PluginError(`Webhook endpoint URL is required`, pluginName);
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
let parsed: URL;
|
|
39
|
+
try {
|
|
40
|
+
parsed = new URL(endpoint.url);
|
|
41
|
+
} catch {
|
|
42
|
+
throw new PluginError(`Invalid webhook URL: ${endpoint.url}`, pluginName);
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
if (parsed.protocol !== 'https:' && parsed.protocol !== 'http:') {
|
|
46
|
+
throw new PluginError(
|
|
47
|
+
`Webhook endpoint URL must use http or https: ${endpoint.url}`,
|
|
48
|
+
pluginName,
|
|
49
|
+
);
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (endpoint.events) {
|
|
53
|
+
for (const event of endpoint.events) {
|
|
54
|
+
if (!validEvents.includes(event)) {
|
|
55
|
+
throw new PluginError(`Invalid webhook event: ${event}`, pluginName);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
}
|