Skip to content

Conversation

@amikofalvy
Copy link
Collaborator

No description provided.

@changeset-bot
Copy link

changeset-bot bot commented Jan 17, 2026

⚠️ No Changeset found

Latest commit: f9b65d4

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

This PR includes no changesets

When changesets are added to this PR, you'll see the packages that this PR includes changesets for and the associated semver types

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

@vercel
Copy link

vercel bot commented Jan 17, 2026

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Review Updated (UTC)
agents-docs Ready Ready Preview, Comment Jan 20, 2026 3:04am
agents-eval-api Ready Ready Preview, Comment Jan 20, 2026 3:04am
agents-manage-api Ready Ready Preview, Comment Jan 20, 2026 3:04am
agents-manage-ui Ready Ready Preview, Comment Jan 20, 2026 3:04am
agents-run-api Ready Ready Preview, Comment Jan 20, 2026 3:04am

Request Review

@claude
Copy link

claude bot commented Jan 17, 2026

Claude finished @amikofalvy's task —— View job


Staff Engineer Review: Triggers Feature Implementation

I've completed a comprehensive review of this substantial triggers feature implementation. This adds webhook-based agent invocation capabilities with authentication, payload transformation, and audit logging. Below are my key findings and recommendations.

🎯 Feature Overview

The implementation successfully delivers a webhook trigger system allowing external services to invoke agents. The feature includes input validation, payload transformation, multiple authentication methods, and comprehensive audit logging. The PRD indicates ~70% completion with core infrastructure complete but missing agent invocation integration.

⚠️ Critical Architecture Issues

1. Security: Credentials in Database Schema

High Priority

// packages/agents-core/src/validation/schemas.ts:1393-1410
authentication: z.object({
  type: z.literal('api_key'),
  data: z.object({
    value: z.string().describe('Expected API key value'), // ⚠️ Stored in plaintext
    // Also basic_auth password, bearer_token stored in plaintext
  })
})

Issue: Authentication credentials (API keys, passwords, bearer tokens) are stored in plaintext in the triggers.authentication JSONB field.

Impact: Major security vulnerability. Database compromise exposes all webhook credentials.

Recommendation:

  • Integrate with existing credentialReferences system for encrypted credential storage
  • Store credential reference IDs in triggers table instead of raw credentials
  • Add migration to encrypt existing credentials

2. Incomplete Feature: Missing Agent Invocation

High Priority

// agents-run-api/src/routes/webhooks.ts:220-226
// TODO: US-013 - Invoke agent via /api/chat endpoint
const invocationId = `inv_${Date.now()}_${Math.random().toString(36).substr(2, 9)}`;
return c.json({ success: true, invocationId }, 202);

Issue: Webhook endpoint returns 202 Accepted but never actually invokes the agent. This breaks the core user contract.

Impact: Feature appears to work but provides no business value. Users will expect agents to respond to webhooks.

Recommendation:

  • Complete US-013 implementation before merge
  • Add proper invocation logging to trigger_invocations table
  • Implement message template interpolation
  • Add error handling for failed agent invocations

3. Data Access Layer: Missing Error Handling

Medium Priority

// packages/agents-core/src/data-access/manage/triggers.ts:82-83
const result = await db.insert(triggers).values(params).returning();
return result[0] as TriggerSelect; // ⚠️ No validation result exists

Issue: Database operations assume success without validating results exist. Similar pattern in all CRUD operations.

Recommendation:

const result = await db.insert(triggers).values(params).returning();
if (!result[0]) {
  throw createApiError({ code: 'internal_server_error', message: 'Failed to create trigger' });
}
return result[0];

🔧 Code Quality Considerations

4. Type Safety: Overly Permissive Authentication Schema

// packages/agents-core/src/db/manage/manage-schema.ts:137
authentication: jsonb('authentication').$type<unknown>(), // ⚠️ Should be typed

Issue: Authentication field uses unknown type instead of the well-defined TriggerAuthenticationSchema.

Fix: .$type<z.infer<typeof TriggerAuthenticationSchema>>()

5. Template Interpolation: No Input Sanitization

// packages/agents-core/src/utils/template-interpolation.ts:72-73
return template.replace(/\{\{([^}]+)\}\}/g, (match, path: string) => {
  const value = getValue(payload, trimmedPath); // ⚠️ No XSS protection

Issue: Template interpolation doesn't sanitize output, potential XSS if templates contain user data.

Recommendation: Add optional HTML escaping parameter and sanitize interpolated values.

6. Webhook Auth: Timing Attack Vulnerability

// packages/agents-core/src/utils/trigger-auth.ts:89-95
if (credentials !== expectedCredentials) {
  return { success: false, status: 403, message: 'Invalid username or password' }; // ⚠️ String comparison
}

Issue: Basic auth uses direct string comparison instead of timing-safe comparison.

Fix: Use timingSafeEqual for all credential comparisons, not just HMAC signatures.

🏗️ Database Design Issues

7. Foreign Key Inconsistency

The trigger_invocations table references both triggers and agents directly:

CONSTRAINT "trigger_invocations_trigger_fk" FOREIGN KEY ("tenant_id","project_id","agent_id","trigger_id") REFERENCES "public"."triggers"

Issue: Redundant foreign key to agents table since triggers already cascade from agents.

Recommendation: Remove direct agent FK from invocations table - triggers FK is sufficient.

8. Index Optimization

Missing composite index for webhook URL generation:

-- Add index for webhook endpoint lookups
CREATE INDEX "triggers_tenant_project_agent_trigger_idx" ON "triggers" ("tenant_id", "project_id", "agent_id", "id");

🎨 API Design Concerns

9. Webhook URL Generation Missing

The PRD mentions webhookUrlTemplate field but it's not implemented in the API responses.

Impact: Users can't easily discover webhook URLs for their triggers.

Recommendation: Add computed webhook URL field to API responses:

webhookUrl: `${baseUrl}/tenants/${tenantId}/projects/${projectId}/agents/${agentId}/triggers/${triggerId}`

10. Error Response Inconsistency

Webhook endpoint mixes custom error format with standard API error format:

// Inconsistent - should use handleApiError pattern
return c.json({ error: authResult.error || 'Unauthorized' }, 401);

📊 Testing & Observability Gaps

11. Missing Integration Tests

Per the PRD, user stories US-014, US-016, US-018 for integration tests are incomplete.

Risk: Complex authentication flows and error cases are untested.

Recommendation: Prioritize integration tests before production deployment.

12. Limited Observability

Webhook processing lacks comprehensive logging for debugging failed invocations.

Enhancement: Add structured logging for payload transformation, authentication steps, and invocation attempts.

🚀 Positive Implementation Notes

Excellent HMAC signature verification with timing-safe comparison
Well-structured authentication system supporting multiple auth types
Comprehensive input validation with JSON schema support
Clean data access layer following established patterns
Proper database migrations with indexes and foreign key constraints
Good TypeScript usage with discriminated unions for auth types

📋 Recommendations Summary

Before Merge (Critical):

  1. Fix credential storage security vulnerability
  2. Complete agent invocation implementation (US-013)
  3. Add error handling to data access layer

Post-Merge (High Priority):
4. Fix timing attack vulnerability in basic auth
5. Complete integration tests
6. Add webhook URL generation to API responses

Enhancement (Medium Priority):
7. Improve type safety for authentication schema
8. Add comprehensive observability
9. Optimize database indexes

This is a well-architected feature with solid foundations, but the security and completeness issues need immediate attention before production deployment.

amikofalvy and others added 9 commits January 19, 2026 18:36
- Added triggers table with fields: id, tenantId, projectId, agentId, name, description, enabled, inputSchema, outputTransform, messageTemplate, authentication, signingSecret, timestamps
- Added trigger_invocations table with fields: id, tenantId, projectId, agentId, triggerId, conversationId, status, requestPayload, transformedPayload, errorMessage, createdAt
- Added foreign key constraints with cascade delete
- Updated prd.json with real user stories from ralph/prd.json

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Marked US-001 and US-002 as complete in prd.json
- Added iteration 4 details to progress.txt with implementation summary

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Added TriggerAuthenticationSchema with discriminated union for api_key, basic_auth, bearer_token, none
- Added TriggerOutputTransformSchema with jmespath and objectTransformation fields
- Added TriggerInvocationStatusEnum with pending, success, failed values
- Added TriggerSelectSchema, TriggerInsertSchema, TriggerUpdateSchema
- Added TriggerApiSelectSchema, TriggerApiInsertSchema, TriggerApiUpdateSchema
- Added TriggerInvocationSelectSchema, TriggerInvocationInsertSchema, TriggerInvocationUpdateSchema
- Added TriggerInvocationApiSelectSchema, TriggerInvocationApiInsertSchema, TriggerInvocationApiUpdateSchema
- All schemas follow existing pattern with agent-scoped API schemas
- Typecheck passes

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Created triggers.ts with CRUD operations: getTriggerById, listTriggers, listTriggersPaginated, createTrigger, updateTrigger, deleteTrigger
- Created triggerInvocations.ts with operations: getTriggerInvocationById, listTriggerInvocationsPaginated (with status and date filtering), createTriggerInvocation, updateTriggerInvocationStatus
- All functions follow agent-scoped pattern with curried database client
- Exported from data-access/index.ts
- Added TriggerSelect, TriggerInsert, TriggerUpdate types to entities.ts
- Added TriggerInvocationSelect, TriggerInvocationInsert, TriggerInvocationUpdate types to entities.ts
- Typecheck passes

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- 6/26 user stories completed (23%)
- Core database and data access foundation complete
- Ready for webhook endpoint implementation

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Implements authentication verification, signing secret verification,
and message template interpolation for trigger webhooks.

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Ralph Agent and others added 24 commits January 19, 2026 18:36
- Extended triggers.test.ts with comprehensive invocation history endpoint tests (300+ additional lines)
- Added helper function createTestInvocation() to create test invocation records directly in database
- Implemented test coverage for GET /:triggerId/invocations endpoint:
  - List invocations with pagination (empty state, multiple invocations, pagination metadata)
  - Ordering by createdAt DESC (newest first) - verified with different timestamps
  - Status filtering (success, failed, pending)
  - Date range filtering with from parameter
  - Date range filtering with both from and to parameters
  - Pagination handling (5 items, page 1, limit 3)
- Implemented test coverage for GET /:triggerId/invocations/:invocationId endpoint:
  - Get single invocation by ID
  - 404 for non-existent invocation
  - Tenant isolation (cross-tenant access returns 404)
  - Error message inclusion for failed invocations
- All tests verify response structure and exclude sensitive fields (tenantId, projectId, agentId)
- Tests use direct database access via createTriggerInvocation() from agents-core
- Follows existing integration test patterns with proper tenant isolation

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Created Trigger class in packages/agents-sdk/src/trigger.ts (110 lines)
- Implemented TriggerInterface with getId(), getName(), getConfig(), with() methods
- Added support for Zod schema conversion in inputSchema (converts to JSON Schema)
- Implemented with() method for creating customized trigger variants
- Created trigger() builder function in builderFunctions.ts
- Added comprehensive JSDoc with GitHub webhook example
- Exported Trigger class and trigger() function from SDK index
- Follows existing SDK patterns (Tool, DataComponent, ArtifactComponent)
- Handles null inputSchema properly (converts to undefined)
- Auto-generates ID from name if not provided using generateIdFromName()
- No init() or upsert() methods needed (triggers managed via manage-API)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Added triggers?: () => TriggerInterface[] to AgentConfig type
- Added getTriggers(): Record<string, Trigger> method to Agent class
- Added addTrigger(...triggers: TriggerInterface[]) method to Agent class
- Resolves triggers lazily using existing resolveGetter() helper
- Added trigger count to agent creation logging
- Exported TriggerInterface from types.ts for external use

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Added triggers field to AgentWithinContextOfProjectSchema as optional record
- Implemented triggers serialization in Agent.toFullAgentDefinition()
- Converts Zod inputSchema to JSON Schema during serialization
- Includes triggers in agent definition when present
- Typecheck passes for both agents-core and agents-sdk

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Marked US-022 as complete in prd.json
- Added detailed progress log entry documenting implementation

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Exported TriggerConfig type from trigger.ts (renamed from TriggerConfigWithZod)
- Added TriggerConfig to SDK index.ts exports
- SDK trigger serialization matches TriggerApiInsert in agents-core
- Zod inputSchema conversion to JSON Schema already handled correctly
- Typecheck passes

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Marked US-023 as complete in prd.json
- Added detailed progress log entry documenting implementation

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Added comprehensive final summary documenting:
- This session: completed US-022 and US-023 (SDK serialization and type exports)
- Overall progress: 23/26 stories complete (88%)
- Complete backend and SDK implementation
- Remaining: 3 UI stories (out of scope for this loop)

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- Created triggers management page at /agents/[agentId]/triggers
- Added TriggersTable component with inline enable/disable toggle
- Added copy webhook URL button
- Added delete trigger action with confirmation
- Created triggers API client and server actions
- Added Triggers button to agent toolbar for easy navigation
- Exported TriggerApiInsert/Select/Update schemas from agents-core client-exports

All acceptance criteria for US-024 met:
- List view showing all triggers (name, enabled status, webhook URL)
- Copy webhook URL button functional
- Toggle enabled/disabled status inline
- Typecheck passes

Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.5 <noreply@anthropic.com>
- data-access-layer.md: Documents DAL patterns, scoping, and usage
- database-architecture.md: Documents dual-database architecture (DoltGres + PostgreSQL)
Database architecture:
- Move triggerInvocations table from manage DB to runtime DB
- Invocations are transactional runtime data, not versioned config
- Update migrations for both manage and runtime schemas

API changes:
- Update manage-api trigger routes to use runtime DB for invocations
- Update run-api webhooks to write invocations to runtime DB
- Add proper cross-database query handling

UI fixes:
- Fix View conversation link to point to /traces/conversations/{id}
- Update invocations table and trigger form components

Other:
- Update permissions, validation schemas, and entity types
- Update SDK trigger and agent builder functions
- Add/update tests for new architecture
Conversation traces show no data (AI calls, timing, activity timeline)
even when agent execution succeeds. This is likely due to OpenTelemetry
tracing not being properly configured or SigNoz not running.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants