@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.
Files changed (82) hide show
  1. package/LICENSE +21 -0
  2. package/dist/node/index.cjs +1 -0
  3. package/dist/node/index.d.ts +1724 -0
  4. package/dist/node/index.d.ts.map +1 -0
  5. package/dist/node/index.js +2 -0
  6. package/dist/node/index.js.map +1 -0
  7. package/package.json +48 -0
  8. package/src/conversation-history/__tests__/conversation-history-plugin.test.ts +221 -0
  9. package/src/conversation-history/__tests__/history-storages.test.ts +115 -0
  10. package/src/conversation-history/conversation-history-helpers.ts +120 -0
  11. package/src/conversation-history/conversation-history-plugin.ts +294 -0
  12. package/src/conversation-history/index.ts +11 -0
  13. package/src/conversation-history/storages/database-storage.ts +96 -0
  14. package/src/conversation-history/storages/file-storage.ts +95 -0
  15. package/src/conversation-history/storages/index.ts +3 -0
  16. package/src/conversation-history/storages/memory-storage.ts +44 -0
  17. package/src/conversation-history/types.ts +64 -0
  18. package/src/error-handling/__tests__/error-handling-plugin.test.ts +201 -0
  19. package/src/error-handling/context-adapter.ts +48 -0
  20. package/src/error-handling/error-handling-helpers.ts +53 -0
  21. package/src/error-handling/error-handling-plugin.ts +293 -0
  22. package/src/error-handling/index.ts +9 -0
  23. package/src/error-handling/types.ts +82 -0
  24. package/src/execution-analytics/__tests__/execution-analytics-plugin.test.ts +224 -0
  25. package/src/execution-analytics/analytics-aggregation.ts +88 -0
  26. package/src/execution-analytics/execution-analytics-helpers.ts +83 -0
  27. package/src/execution-analytics/execution-analytics-plugin.ts +315 -0
  28. package/src/execution-analytics/index.ts +9 -0
  29. package/src/execution-analytics/types.ts +97 -0
  30. package/src/index.ts +8 -0
  31. package/src/limits/__tests__/limits-plugin.test.ts +712 -0
  32. package/src/limits/index.ts +9 -0
  33. package/src/limits/limits-helpers.ts +185 -0
  34. package/src/limits/limits-plugin.ts +196 -0
  35. package/src/limits/types.ts +73 -0
  36. package/src/limits/validation.ts +81 -0
  37. package/src/logging/__tests__/formatters.test.ts +48 -0
  38. package/src/logging/__tests__/logging-plugin.test.ts +464 -0
  39. package/src/logging/__tests__/logging-storages.test.ts +95 -0
  40. package/src/logging/formatters.ts +28 -0
  41. package/src/logging/index.ts +15 -0
  42. package/src/logging/logging-helpers.ts +223 -0
  43. package/src/logging/logging-plugin.ts +288 -0
  44. package/src/logging/storages/console-storage.ts +44 -0
  45. package/src/logging/storages/file-storage.ts +44 -0
  46. package/src/logging/storages/index.ts +4 -0
  47. package/src/logging/storages/remote-storage.ts +78 -0
  48. package/src/logging/storages/silent-storage.ts +18 -0
  49. package/src/logging/types.ts +106 -0
  50. package/src/performance/__tests__/memory-storage.test.ts +86 -0
  51. package/src/performance/__tests__/performance-plugin.test.ts +208 -0
  52. package/src/performance/__tests__/system-metrics-collector.test.ts +33 -0
  53. package/src/performance/collectors/system-metrics-collector.ts +69 -0
  54. package/src/performance/index.ts +12 -0
  55. package/src/performance/performance-helpers.ts +86 -0
  56. package/src/performance/performance-plugin.ts +274 -0
  57. package/src/performance/storages/index.ts +1 -0
  58. package/src/performance/storages/memory-storage.ts +88 -0
  59. package/src/performance/types.ts +160 -0
  60. package/src/usage/__tests__/aggregate-usage-stats.test.ts +136 -0
  61. package/src/usage/__tests__/memory-storage.test.ts +83 -0
  62. package/src/usage/__tests__/silent-storage.test.ts +44 -0
  63. package/src/usage/__tests__/usage-plugin-helpers.test.ts +155 -0
  64. package/src/usage/__tests__/usage-plugin.test.ts +358 -0
  65. package/src/usage/aggregate-usage-stats.ts +142 -0
  66. package/src/usage/index.ts +14 -0
  67. package/src/usage/storages/file-storage.ts +115 -0
  68. package/src/usage/storages/index.ts +4 -0
  69. package/src/usage/storages/memory-storage.ts +61 -0
  70. package/src/usage/storages/remote-storage.ts +143 -0
  71. package/src/usage/storages/silent-storage.ts +38 -0
  72. package/src/usage/types.ts +132 -0
  73. package/src/usage/usage-plugin-helpers.ts +116 -0
  74. package/src/usage/usage-plugin.ts +296 -0
  75. package/src/webhook/__tests__/webhook-plugin.test.ts +560 -0
  76. package/src/webhook/http-client.ts +141 -0
  77. package/src/webhook/index.ts +9 -0
  78. package/src/webhook/transformer.ts +209 -0
  79. package/src/webhook/types.ts +201 -0
  80. package/src/webhook/webhook-helpers.ts +60 -0
  81. package/src/webhook/webhook-plugin.ts +298 -0
  82. 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
+ }