language-operator 0.1.61 → 0.1.62

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 (143) hide show
  1. checksums.yaml +4 -4
  2. data/.claude/commands/persona.md +9 -0
  3. data/.claude/commands/task.md +46 -1
  4. data/.rubocop.yml +13 -0
  5. data/.rubocop_custom/use_ux_helper.rb +44 -0
  6. data/CHANGELOG.md +8 -0
  7. data/Gemfile.lock +12 -1
  8. data/Makefile +26 -7
  9. data/Makefile.common +50 -0
  10. data/bin/aictl +8 -1
  11. data/components/agent/Gemfile +1 -1
  12. data/components/agent/bin/langop-agent +7 -0
  13. data/docs/README.md +58 -0
  14. data/docs/{dsl/best-practices.md → best-practices.md} +4 -4
  15. data/docs/cli-reference.md +274 -0
  16. data/docs/{dsl/constraints.md → constraints.md} +5 -5
  17. data/docs/how-agents-work.md +156 -0
  18. data/docs/installation.md +218 -0
  19. data/docs/quickstart.md +299 -0
  20. data/docs/understanding-generated-code.md +265 -0
  21. data/docs/using-tools.md +457 -0
  22. data/docs/webhooks.md +509 -0
  23. data/examples/ux_helpers_demo.rb +296 -0
  24. data/lib/language_operator/agent/base.rb +11 -1
  25. data/lib/language_operator/agent/executor.rb +23 -6
  26. data/lib/language_operator/agent/safety/safe_executor.rb +41 -39
  27. data/lib/language_operator/agent/task_executor.rb +346 -63
  28. data/lib/language_operator/agent/web_server.rb +110 -14
  29. data/lib/language_operator/agent/webhook_authenticator.rb +39 -5
  30. data/lib/language_operator/agent.rb +88 -2
  31. data/lib/language_operator/cli/base_command.rb +17 -11
  32. data/lib/language_operator/cli/command_loader.rb +72 -0
  33. data/lib/language_operator/cli/commands/agent/base.rb +837 -0
  34. data/lib/language_operator/cli/commands/agent/code_operations.rb +102 -0
  35. data/lib/language_operator/cli/commands/agent/helpers/cluster_llm_client.rb +116 -0
  36. data/lib/language_operator/cli/commands/agent/helpers/code_parser.rb +115 -0
  37. data/lib/language_operator/cli/commands/agent/helpers/synthesis_watcher.rb +96 -0
  38. data/lib/language_operator/cli/commands/agent/learning.rb +289 -0
  39. data/lib/language_operator/cli/commands/agent/lifecycle.rb +102 -0
  40. data/lib/language_operator/cli/commands/agent/logs.rb +125 -0
  41. data/lib/language_operator/cli/commands/agent/workspace.rb +327 -0
  42. data/lib/language_operator/cli/commands/cluster.rb +129 -84
  43. data/lib/language_operator/cli/commands/install.rb +1 -1
  44. data/lib/language_operator/cli/commands/model/base.rb +215 -0
  45. data/lib/language_operator/cli/commands/model/test.rb +165 -0
  46. data/lib/language_operator/cli/commands/persona.rb +16 -34
  47. data/lib/language_operator/cli/commands/quickstart.rb +3 -2
  48. data/lib/language_operator/cli/commands/status.rb +40 -67
  49. data/lib/language_operator/cli/commands/system/base.rb +44 -0
  50. data/lib/language_operator/cli/commands/system/exec.rb +147 -0
  51. data/lib/language_operator/cli/commands/system/helpers/llm_synthesis.rb +183 -0
  52. data/lib/language_operator/cli/commands/system/helpers/pod_manager.rb +212 -0
  53. data/lib/language_operator/cli/commands/system/helpers/template_loader.rb +57 -0
  54. data/lib/language_operator/cli/commands/system/helpers/template_validator.rb +174 -0
  55. data/lib/language_operator/cli/commands/system/schema.rb +92 -0
  56. data/lib/language_operator/cli/commands/system/synthesis_template.rb +151 -0
  57. data/lib/language_operator/cli/commands/system/synthesize.rb +224 -0
  58. data/lib/language_operator/cli/commands/system/validate_template.rb +130 -0
  59. data/lib/language_operator/cli/commands/tool/base.rb +271 -0
  60. data/lib/language_operator/cli/commands/tool/install.rb +255 -0
  61. data/lib/language_operator/cli/commands/tool/search.rb +69 -0
  62. data/lib/language_operator/cli/commands/tool/test.rb +115 -0
  63. data/lib/language_operator/cli/commands/use.rb +29 -6
  64. data/lib/language_operator/cli/errors/handler.rb +20 -17
  65. data/lib/language_operator/cli/errors/suggestions.rb +3 -5
  66. data/lib/language_operator/cli/errors/thor_errors.rb +55 -0
  67. data/lib/language_operator/cli/formatters/code_formatter.rb +4 -11
  68. data/lib/language_operator/cli/formatters/log_formatter.rb +8 -15
  69. data/lib/language_operator/cli/formatters/progress_formatter.rb +6 -8
  70. data/lib/language_operator/cli/formatters/status_formatter.rb +26 -7
  71. data/lib/language_operator/cli/formatters/table_formatter.rb +47 -36
  72. data/lib/language_operator/cli/formatters/value_formatter.rb +75 -0
  73. data/lib/language_operator/cli/helpers/cluster_context.rb +5 -3
  74. data/lib/language_operator/cli/helpers/kubeconfig_validator.rb +2 -1
  75. data/lib/language_operator/cli/helpers/label_utils.rb +97 -0
  76. data/lib/language_operator/{ux/concerns/provider_helpers.rb → cli/helpers/provider_helper.rb} +10 -29
  77. data/lib/language_operator/cli/helpers/schedule_builder.rb +21 -1
  78. data/lib/language_operator/cli/helpers/user_prompts.rb +19 -11
  79. data/lib/language_operator/cli/helpers/ux_helper.rb +538 -0
  80. data/lib/language_operator/{ux/concerns/input_validation.rb → cli/helpers/validation_helper.rb} +13 -66
  81. data/lib/language_operator/cli/main.rb +50 -40
  82. data/lib/language_operator/cli/templates/tools/generic.yaml +3 -0
  83. data/lib/language_operator/cli/wizards/agent_wizard.rb +12 -20
  84. data/lib/language_operator/cli/wizards/model_wizard.rb +271 -0
  85. data/lib/language_operator/cli/wizards/quickstart_wizard.rb +8 -34
  86. data/lib/language_operator/client/base.rb +28 -0
  87. data/lib/language_operator/client/config.rb +4 -1
  88. data/lib/language_operator/client/mcp_connector.rb +1 -1
  89. data/lib/language_operator/config/cluster_config.rb +3 -2
  90. data/lib/language_operator/config.rb +38 -11
  91. data/lib/language_operator/constants/kubernetes_labels.rb +80 -0
  92. data/lib/language_operator/constants.rb +13 -0
  93. data/lib/language_operator/dsl/http.rb +127 -10
  94. data/lib/language_operator/dsl.rb +153 -6
  95. data/lib/language_operator/errors.rb +50 -0
  96. data/lib/language_operator/kubernetes/client.rb +11 -6
  97. data/lib/language_operator/kubernetes/resource_builder.rb +58 -84
  98. data/lib/language_operator/templates/schema/agent_dsl_openapi.yaml +1 -1
  99. data/lib/language_operator/templates/schema/agent_dsl_schema.json +1 -1
  100. data/lib/language_operator/type_coercion.rb +118 -34
  101. data/lib/language_operator/utils/secure_path.rb +74 -0
  102. data/lib/language_operator/utils.rb +7 -0
  103. data/lib/language_operator/validators.rb +54 -2
  104. data/lib/language_operator/version.rb +1 -1
  105. data/synth/001/Makefile +10 -2
  106. data/synth/001/agent.rb +16 -15
  107. data/synth/001/output.log +27 -10
  108. data/synth/002/Makefile +10 -2
  109. data/synth/003/Makefile +1 -1
  110. data/synth/003/README.md +205 -133
  111. data/synth/003/agent.optimized.rb +66 -0
  112. data/synth/003/agent.synthesized.rb +41 -0
  113. metadata +111 -35
  114. data/docs/dsl/agent-reference.md +0 -604
  115. data/docs/dsl/mcp-integration.md +0 -1177
  116. data/docs/dsl/webhooks.md +0 -932
  117. data/docs/dsl/workflows.md +0 -744
  118. data/lib/language_operator/cli/commands/agent.rb +0 -1712
  119. data/lib/language_operator/cli/commands/model.rb +0 -366
  120. data/lib/language_operator/cli/commands/system.rb +0 -1259
  121. data/lib/language_operator/cli/commands/tool.rb +0 -654
  122. data/lib/language_operator/cli/formatters/optimization_formatter.rb +0 -226
  123. data/lib/language_operator/cli/helpers/pastel_helper.rb +0 -24
  124. data/lib/language_operator/learning/adapters/base_adapter.rb +0 -149
  125. data/lib/language_operator/learning/adapters/jaeger_adapter.rb +0 -221
  126. data/lib/language_operator/learning/adapters/signoz_adapter.rb +0 -435
  127. data/lib/language_operator/learning/adapters/tempo_adapter.rb +0 -239
  128. data/lib/language_operator/learning/optimizer.rb +0 -319
  129. data/lib/language_operator/learning/pattern_detector.rb +0 -260
  130. data/lib/language_operator/learning/task_synthesizer.rb +0 -288
  131. data/lib/language_operator/learning/trace_analyzer.rb +0 -285
  132. data/lib/language_operator/templates/task_synthesis.tmpl +0 -98
  133. data/lib/language_operator/ux/base.rb +0 -81
  134. data/lib/language_operator/ux/concerns/README.md +0 -155
  135. data/lib/language_operator/ux/concerns/headings.rb +0 -90
  136. data/lib/language_operator/ux/create_agent.rb +0 -255
  137. data/lib/language_operator/ux/create_model.rb +0 -267
  138. data/lib/language_operator/ux/quickstart.rb +0 -594
  139. data/synth/003/agent.rb +0 -41
  140. data/synth/003/output.log +0 -68
  141. /data/docs/{architecture/agent-runtime.md → agent-internals.md} +0 -0
  142. /data/docs/{dsl/chat-endpoints.md → chat-endpoints.md} +0 -0
  143. /data/docs/{dsl/SCHEMA_VERSION.md → schema-versioning.md} +0 -0
data/docs/webhooks.md ADDED
@@ -0,0 +1,509 @@
1
+ # Webhooks
2
+
3
+ Language Operator agents can respond to webhooks from GitHub, Stripe, Slack, and other services. This guide shows how webhook agents work and what they look like when synthesized.
4
+
5
+ ## How Webhook Agents Work
6
+
7
+ When you describe an agent that responds to external events, Language Operator creates a reactive agent with webhook endpoints.
8
+
9
+ ### Creating Webhook Agents
10
+
11
+ ```bash
12
+ aictl agent create github-pr-reviewer
13
+ # Wizard asks:
14
+ # - What service sends webhooks? (GitHub, Stripe, Slack, custom)
15
+ # - What events should trigger the agent? (pull_request, push, etc.)
16
+ # - What should the agent do when triggered?
17
+ ```
18
+
19
+ Language Operator automatically:
20
+ 1. Sets up secure webhook endpoints
21
+ 2. Configures authentication (HMAC, API keys, etc.)
22
+ 3. Handles payload parsing and validation
23
+ 4. Routes events to your agent logic
24
+
25
+ ## Webhook Agent Structure
26
+
27
+ ### Basic Structure
28
+
29
+ ```ruby
30
+ agent "github-pr-reviewer" do
31
+ description "Reviews pull requests and provides feedback"
32
+ mode :reactive
33
+
34
+ # Webhook configuration
35
+ webhook do
36
+ endpoint "github"
37
+ authentication :hmac_sha256
38
+ secret ENV['GITHUB_WEBHOOK_SECRET']
39
+ events ['pull_request.opened', 'pull_request.synchronize']
40
+ end
41
+
42
+ # Event processing tasks
43
+ task :analyze_pr,
44
+ instructions: "analyze the pull request changes and identify issues",
45
+ inputs: { pr_number: 'integer', diff: 'string', files: 'array' },
46
+ outputs: { issues: 'array', suggestion: 'string' }
47
+
48
+ # Main webhook handler
49
+ main do |webhook_payload|
50
+ # Extract PR information
51
+ pr_data = execute_task(:extract_pr_info, inputs: webhook_payload)
52
+
53
+ # Analyze the changes
54
+ analysis = execute_task(:analyze_pr, inputs: pr_data)
55
+
56
+ # Post review comment
57
+ execute_task(:post_review, inputs: analysis.merge(pr_data))
58
+ end
59
+
60
+ output do |outputs|
61
+ # Results are handled by tasks (posting comments, etc.)
62
+ { status: 'review_posted', timestamp: Time.now }
63
+ end
64
+ end
65
+ ```
66
+
67
+ ## Common Webhook Patterns
68
+
69
+ ### GitHub Integration
70
+
71
+ **Pull Request Reviews**:
72
+ ```ruby
73
+ agent "pr-reviewer" do
74
+ description "Automatically reviews pull requests for code quality"
75
+ mode :reactive
76
+
77
+ webhook do
78
+ endpoint "github"
79
+ authentication :hmac_sha256
80
+ events ['pull_request.opened', 'pull_request.synchronize']
81
+ end
82
+
83
+ task :fetch_pr_diff,
84
+ instructions: "get the diff and changed files for the pull request",
85
+ inputs: { pr_number: 'integer', repo: 'string' },
86
+ outputs: { diff: 'string', files: 'array' }
87
+
88
+ task :review_code,
89
+ instructions: "analyze code for bugs, style issues, and best practices",
90
+ inputs: { diff: 'string', files: 'array' },
91
+ outputs: { issues: 'array', overall_rating: 'string' }
92
+
93
+ task :post_review,
94
+ instructions: "post review comments on the pull request",
95
+ inputs: { pr_number: 'integer', issues: 'array', rating: 'string' },
96
+ outputs: { comment_posted: 'boolean' }
97
+
98
+ main do |webhook_payload|
99
+ pr_info = {
100
+ pr_number: webhook_payload['pull_request']['number'],
101
+ repo: webhook_payload['repository']['full_name']
102
+ }
103
+
104
+ diff_data = execute_task(:fetch_pr_diff, inputs: pr_info)
105
+ review = execute_task(:review_code, inputs: diff_data)
106
+ execute_task(:post_review, inputs: review.merge(pr_info))
107
+ end
108
+ end
109
+ ```
110
+
111
+ **Issue Management**:
112
+ ```ruby
113
+ agent "issue-triager" do
114
+ description "Automatically triages and labels GitHub issues"
115
+ mode :reactive
116
+
117
+ webhook do
118
+ endpoint "github"
119
+ events ['issues.opened']
120
+ end
121
+
122
+ task :classify_issue,
123
+ instructions: "classify issue type and priority based on title and description",
124
+ inputs: { title: 'string', body: 'string' },
125
+ outputs: { type: 'string', priority: 'string', labels: 'array' }
126
+
127
+ task :assign_issue,
128
+ instructions: "assign issue to appropriate team member based on classification",
129
+ inputs: { type: 'string', priority: 'string' },
130
+ outputs: { assignee: 'string' }
131
+
132
+ main do |webhook_payload|
133
+ issue_data = {
134
+ title: webhook_payload['issue']['title'],
135
+ body: webhook_payload['issue']['body']
136
+ }
137
+
138
+ classification = execute_task(:classify_issue, inputs: issue_data)
139
+ assignment = execute_task(:assign_issue, inputs: classification)
140
+
141
+ # Apply labels and assignment
142
+ execute_task(:update_issue, inputs: {
143
+ issue_number: webhook_payload['issue']['number'],
144
+ labels: classification[:labels],
145
+ assignee: assignment[:assignee]
146
+ })
147
+ end
148
+ end
149
+ ```
150
+
151
+ ### Stripe Integration
152
+
153
+ **Payment Processing**:
154
+ ```ruby
155
+ agent "payment-processor" do
156
+ description "Handles successful payments and sends notifications"
157
+ mode :reactive
158
+
159
+ webhook do
160
+ endpoint "stripe"
161
+ authentication :stripe_signature
162
+ events ['payment_intent.succeeded']
163
+ end
164
+
165
+ task :extract_payment_info,
166
+ instructions: "extract customer and payment details from Stripe payload",
167
+ inputs: { stripe_payload: 'hash' },
168
+ outputs: { customer_id: 'string', amount: 'number', currency: 'string' }
169
+
170
+ task :send_receipt,
171
+ instructions: "send payment receipt email to customer",
172
+ inputs: { customer_id: 'string', amount: 'number', currency: 'string' },
173
+ outputs: { email_sent: 'boolean' }
174
+
175
+ task :update_subscription,
176
+ instructions: "update customer subscription status in database",
177
+ inputs: { customer_id: 'string', amount: 'number' },
178
+ outputs: { subscription_updated: 'boolean' }
179
+
180
+ main do |webhook_payload|
181
+ payment_info = execute_task(:extract_payment_info,
182
+ inputs: { stripe_payload: webhook_payload })
183
+
184
+ # Send receipt and update subscription in parallel
185
+ execute_parallel([
186
+ { name: :send_receipt, inputs: payment_info },
187
+ { name: :update_subscription, inputs: payment_info }
188
+ ])
189
+ end
190
+ end
191
+ ```
192
+
193
+ ### Slack Integration
194
+
195
+ **Command Handler**:
196
+ ```ruby
197
+ agent "slack-bot" do
198
+ description "Handles slack slash commands and interactive messages"
199
+ mode :reactive
200
+
201
+ webhook do
202
+ endpoint "slack"
203
+ authentication :slack_verification
204
+ events ['slash_command', 'interactive_message']
205
+ end
206
+
207
+ task :parse_command,
208
+ instructions: "parse slack command and extract parameters",
209
+ inputs: { command: 'string', text: 'string' },
210
+ outputs: { action: 'string', params: 'hash' }
211
+
212
+ task :execute_action,
213
+ instructions: "execute the requested action with given parameters",
214
+ inputs: { action: 'string', params: 'hash' },
215
+ outputs: { result: 'string', success: 'boolean' }
216
+
217
+ main do |webhook_payload|
218
+ if webhook_payload['type'] == 'slash_command'
219
+ command_info = {
220
+ command: webhook_payload['command'],
221
+ text: webhook_payload['text']
222
+ }
223
+
224
+ parsed = execute_task(:parse_command, inputs: command_info)
225
+ result = execute_task(:execute_action, inputs: parsed)
226
+
227
+ # Respond to Slack
228
+ execute_task(:send_slack_response, inputs: {
229
+ response_url: webhook_payload['response_url'],
230
+ message: result[:result]
231
+ })
232
+ end
233
+ end
234
+ end
235
+ ```
236
+
237
+ ### Custom Webhooks
238
+
239
+ **API Integration**:
240
+ ```ruby
241
+ agent "api-monitor" do
242
+ description "Monitors API health via webhooks and alerts on issues"
243
+ mode :reactive
244
+
245
+ webhook do
246
+ endpoint "custom"
247
+ authentication :api_key
248
+ path "/health-check"
249
+ end
250
+
251
+ task :analyze_health_data,
252
+ instructions: "analyze API health metrics and identify problems",
253
+ inputs: { metrics: 'hash' },
254
+ outputs: { status: 'string', issues: 'array', alerts_needed: 'boolean' }
255
+
256
+ task :send_alerts,
257
+ instructions: "send alerts to operations team via multiple channels",
258
+ inputs: { issues: 'array', severity: 'string' },
259
+ outputs: { alerts_sent: 'array' }
260
+
261
+ main do |webhook_payload|
262
+ analysis = execute_task(:analyze_health_data,
263
+ inputs: { metrics: webhook_payload })
264
+
265
+ if analysis[:alerts_needed]
266
+ execute_task(:send_alerts, inputs: {
267
+ issues: analysis[:issues],
268
+ severity: analysis[:status]
269
+ })
270
+ end
271
+ end
272
+ end
273
+ ```
274
+
275
+ ## Webhook Configuration
276
+
277
+ ### Authentication Methods
278
+
279
+ Language Operator supports multiple authentication methods:
280
+
281
+ **HMAC Signature Verification** (GitHub, Stripe):
282
+ ```ruby
283
+ webhook do
284
+ endpoint "github"
285
+ authentication :hmac_sha256
286
+ secret ENV['GITHUB_WEBHOOK_SECRET']
287
+ end
288
+ ```
289
+
290
+ **API Key Authentication**:
291
+ ```ruby
292
+ webhook do
293
+ endpoint "custom"
294
+ authentication :api_key
295
+ api_key ENV['WEBHOOK_API_KEY']
296
+ header "X-API-Key" # Custom header name
297
+ end
298
+ ```
299
+
300
+ **Bearer Token Authentication**:
301
+ ```ruby
302
+ webhook do
303
+ endpoint "custom"
304
+ authentication :bearer_token
305
+ token ENV['WEBHOOK_TOKEN']
306
+ end
307
+ ```
308
+
309
+ **Custom Authentication**:
310
+ ```ruby
311
+ webhook do
312
+ endpoint "custom"
313
+ authentication :custom
314
+ validate do |headers, body|
315
+ # Custom validation logic
316
+ headers['X-Custom-Auth'] == ENV['CUSTOM_SECRET']
317
+ end
318
+ end
319
+ ```
320
+
321
+ ### Event Filtering
322
+
323
+ Filter specific events to reduce noise:
324
+
325
+ ```ruby
326
+ webhook do
327
+ endpoint "github"
328
+ events [
329
+ 'pull_request.opened',
330
+ 'pull_request.synchronize',
331
+ 'issues.opened'
332
+ ]
333
+
334
+ # Additional filters
335
+ filters do
336
+ branch 'main' # Only main branch
337
+ repository 'company/main-repo' # Specific repository
338
+ label_present 'needs-review' # Must have label
339
+ end
340
+ end
341
+ ```
342
+
343
+ ## Webhook Endpoints
344
+
345
+ ### Automatic URL Generation
346
+
347
+ Language Operator automatically generates secure webhook URLs:
348
+
349
+ ```
350
+ https://webhooks.your-cluster.com/agents/{agent-id}/webhook/{endpoint}
351
+ ```
352
+
353
+ **Examples**:
354
+ - `https://webhooks.company.com/agents/pr-reviewer-abc123/webhook/github`
355
+ - `https://webhooks.company.com/agents/payment-processor-def456/webhook/stripe`
356
+
357
+ ### Custom Paths
358
+
359
+ For custom integrations, specify custom paths:
360
+
361
+ ```ruby
362
+ webhook do
363
+ endpoint "custom"
364
+ path "/api/v1/health-check" # Custom path
365
+ methods ['POST', 'PUT'] # Allowed HTTP methods
366
+ end
367
+ ```
368
+
369
+ ## Security Features
370
+
371
+ ### Request Validation
372
+
373
+ All webhook requests are validated:
374
+ - **Signature verification**: HMAC signatures verified automatically
375
+ - **Content-type checking**: Ensures proper JSON/form data
376
+ - **Rate limiting**: Prevents abuse and DoS attacks
377
+ - **IP whitelisting**: Restrict access to known service IPs
378
+
379
+ ### Payload Sanitization
380
+
381
+ Webhook payloads are automatically sanitized:
382
+ - Potentially dangerous fields are filtered
383
+ - Large payloads are truncated if needed
384
+ - Sensitive information is masked in logs
385
+
386
+ ## Error Handling
387
+
388
+ Webhook agents handle errors gracefully:
389
+
390
+ ```ruby
391
+ main do |webhook_payload|
392
+ begin
393
+ # Normal processing
394
+ result = execute_task(:process_webhook, inputs: webhook_payload)
395
+ result
396
+ rescue => e
397
+ # Log error and return appropriate response
398
+ logger.error("Webhook processing failed: #{e.message}")
399
+
400
+ # Return error response
401
+ {
402
+ status: 'error',
403
+ message: 'Processing failed',
404
+ timestamp: Time.now
405
+ }
406
+ end
407
+ end
408
+ ```
409
+
410
+ ### Retry Logic
411
+
412
+ Failed webhooks are automatically retried:
413
+ - Exponential backoff for temporary failures
414
+ - Dead letter queue for permanent failures
415
+ - Alerting when retry limits exceeded
416
+
417
+ ## Monitoring and Debugging
418
+
419
+ ### Webhook Logs
420
+
421
+ Monitor webhook activity:
422
+
423
+ ```bash
424
+ # View webhook logs
425
+ aictl agent logs pr-reviewer --webhooks-only
426
+
427
+ # Follow webhook activity in real-time
428
+ aictl agent logs pr-reviewer --follow --filter webhook
429
+
430
+ # View specific webhook processing
431
+ aictl agent webhook-logs pr-reviewer --webhook-id abc123
432
+ ```
433
+
434
+ ### Webhook Testing
435
+
436
+ Test webhooks during development:
437
+
438
+ ```bash
439
+ # Test webhook endpoint
440
+ aictl agent test-webhook pr-reviewer \
441
+ --payload ./test-payload.json \
442
+ --event pull_request.opened
443
+
444
+ # Simulate webhook with custom data
445
+ aictl agent simulate-webhook pr-reviewer \
446
+ --github-pr 123 \
447
+ --repository company/main-repo
448
+ ```
449
+
450
+ ## Performance Optimization
451
+
452
+ ### Parallel Processing
453
+
454
+ Process webhooks efficiently using parallel task execution:
455
+
456
+ ```ruby
457
+ main do |webhook_payload|
458
+ # Process multiple aspects in parallel
459
+ results = execute_parallel([
460
+ { name: :validate_payload, inputs: webhook_payload },
461
+ { name: :fetch_context, inputs: webhook_payload },
462
+ { name: :check_permissions, inputs: webhook_payload }
463
+ ])
464
+
465
+ # Continue with main processing
466
+ if results.all? { |r| r[:valid] }
467
+ execute_task(:main_processing, inputs: webhook_payload)
468
+ end
469
+ end
470
+ ```
471
+
472
+ ### Webhook Queuing
473
+
474
+ High-volume webhooks are queued automatically:
475
+ - Asynchronous processing for non-urgent webhooks
476
+ - Priority queues for critical events
477
+ - Batch processing for similar events
478
+
479
+ ## Best Practices
480
+
481
+ ### Security
482
+ - Always use proper authentication (HMAC, API keys)
483
+ - Validate webhook sources and signatures
484
+ - Sanitize and validate all input data
485
+ - Use environment variables for secrets
486
+
487
+ ### Performance
488
+ - Process webhooks asynchronously when possible
489
+ - Use parallel execution for independent tasks
490
+ - Cache frequently accessed data
491
+ - Monitor response times and optimize bottlenecks
492
+
493
+ ### Reliability
494
+ - Implement proper error handling and retries
495
+ - Log all webhook activity for debugging
496
+ - Test webhook processing with realistic payloads
497
+ - Monitor webhook endpoint availability
498
+
499
+ ### Scalability
500
+ - Design for high webhook volumes
501
+ - Use efficient data structures and algorithms
502
+ - Consider webhook batching for similar events
503
+ - Scale webhook processing horizontally
504
+
505
+ ## Next Steps
506
+
507
+ - **[Understanding Generated Code](understanding-generated-code.md)** - Learn to read webhook agent code
508
+ - **[Using Tools](using-tools.md)** - How webhook agents use external services
509
+ - **[Agent Configuration](agent-configuration.md)** - Configure webhook settings and limits