Tasks Package
The @ever-works/trigger-tasks package provides background task execution for the Ever Works platform using Trigger.dev. It handles long-running work generation and import operations outside the main API process, enabling reliable multi-hour workflows with automatic failure recovery, cancellation handling, and schedule-based dispatching.
Package Overview
| Property | Value |
|---|---|
| Package name | @ever-works/trigger-tasks |
| Location | platform/packages/tasks/ |
| Runtime | Node.js (Trigger.dev worker) |
| Max duration | 5 hours (generation), 2 hours (import) |
| Default machine | medium-1x |
| Retry strategy | Up to 3 attempts with exponential backoff (configurable) |
Architecture
The tasks package operates in two distinct contexts:
- API-side -- The
TriggerModuleandTriggerServicerun inside the NestJS API, dispatching payloads to Trigger.dev. - Worker-side -- Task definitions, orchestrators, and worker modules run inside Trigger.dev's isolated execution environment.
API Process Trigger.dev Worker
----------- ------------------
TriggerService workGenerationTask
.dispatchWorkGeneration() --> withWorkerContext()
createTaskContext()
TriggerGenerationOrchestrator.run()
Task Definitions
Tasks are defined in src/tasks/trigger/ using the Trigger.dev SDK.
Work Generation Task
The primary task that orchestrates AI-powered work content generation.
// src/tasks/trigger/work-generation.task.ts
export const workGenerationTask = task({
id: 'work-generation',
maxDuration: 3600 * 5, // 5 hours
onFailure: async ({ payload, error }) => {
/* ... */
},
onCancel: async ({ payload }) => {
/* ... */
},
run: async (payload: WorkGenerationPayload) => {
return withWorkerContext('WorkGeneration', async (appContext) => {
const { orchestrator, work, user } = await createTaskContext(
appContext,
payload,
TriggerGenerationOrchestrator
);
await orchestrator.run({
work,
user,
dto: payload.dto,
historyId: payload.historyId,
historyStartedAt: payload.historyStartedAt
});
return { status: 'completed', workId: payload.workId };
});
}
});
Work Import Task
Handles importing work content from external sources such as GitHub repositories.
export const workImportTask = task({
id: 'work-import',
maxDuration: 3600 * 2, // 2 hours
run: async (payload: WorkImportPayload) => {
return withWorkerContext('WorkImport', async (appContext) => {
const { orchestrator, work, user, gitToken } = await createTaskContext(
appContext,
payload,
TriggerImportOrchestrator
);
await orchestrator.run({ work, user, payload, gitToken });
return { status: 'completed', workId: payload.workId };
});
}
});
Schedule Dispatcher Task
A cron-based task that polls for due scheduled work generations and dispatches them.
export const workScheduleDispatcherTask = schedules.task({
id: 'work-schedule-dispatcher',
cron: `*/${interval} * * * *`, // configurable interval
run: async () => {
const appContext = await NestFactory.createApplicationContext(TriggerInternalModule);
const dispatcher = appContext.get(WorkScheduleDispatcherService);
const dispatched = await dispatcher.dispatchDue();
return { dispatched, intervalMinutes: interval };
}
});
TriggerService (API-Side Dispatcher)
The TriggerService runs in the NestJS API and implements both WorkGenerationDispatcher and WorkImportDispatcher interfaces. It lazily configures the Trigger.dev SDK on first use.
| Method | Description |
|---|---|
dispatchWorkGeneration(payload) | Triggers a generation task with tags for tracking |
dispatchWorkImport(payload) | Triggers an import task with source-type tags |
The service supports configurable machine sizes: micro, small-1x, small-2x, medium-1x, medium-2x, large-1x, large-2x.
Worker Context Utilities
withWorkerContext
Bootstraps a full NestJS application context inside the Trigger.dev worker, executes the provided function, and ensures cleanup.
async function withWorkerContext<T>(
loggerName: string,
fn: (appContext: INestApplicationContext) => Promise<T>,
module: Type<any> = TriggerWorkerModule
): Promise<T>;
createTaskContext
Shared bootstrap logic that hydrates plugins, fetches work context from the API, and resolves the orchestrator instance.
async function createTaskContext<T>(
appContext: INestApplicationContext,
payload: { workId: string; userId: string },
orchestratorClass: Type<T>
): Promise<{ user: User; work: Work; orchestrator: T; gitToken?: string }>;
Orchestrators
Orchestrators manage the execution lifecycle of tasks including status tracking, error handling, and notifications.
BaseOrchestrator
Abstract base class providing common functionality:
| Method | Description |
|---|---|
handleFailure(options) | Records error state, updates history, emits completion |
handleCancellation(options) | Records cancelled state with duration calculation |
handleErrorNotification(error, user, work) | Classifies errors and sends notifications |
TriggerGenerationOrchestrator
Coordinates the full generation pipeline:
- Records generation start time and status
- Runs data generation via
DataGeneratorService - Generates markdown via
MarkdownGeneratorService - Generates website via
WebsiteGeneratorService - Updates history with stats and warnings
- Handles errors with classified notifications
TriggerImportOrchestrator
Coordinates work imports from external sources:
- Records import start and status
- Delegates to
ImportExecutorServicebased on source type - Updates work item count on success
- Records import statistics in generation history
Worker Services
TriggerInternalApiClient
HTTP client for communication between the Trigger.dev worker and the main API. Uses shared secret authentication and SuperJSON serialization.
| Method | Description |
|---|---|
fetchWorkContext(workId, userId) | Fetches work and user data from the API |
callRemote(name, method, args) | Forwards method calls to API-side services via RPC |
Features automatic retry with exponential backoff (3 attempts, 500ms base delay) for 5xx errors and network failures.
TriggerPluginHydratorService
Initializes the plugin system from the filesystem within the worker environment by calling PluginBootstrapService.bootstrap({ force: true }).
LocalPluginStore
An in-memory Map-based store for plugin metadata used during worker bootstrap. Write operations (create, upsert, update, delete) execute locally while read operations fall through to the remote proxy.
Remote Proxy
The createRemoteProxy function creates a JavaScript Proxy that transparently forwards method calls to the API via TriggerInternalApiClient.callRemote(). Uses SuperJSON for serialization to preserve Date, Map, Set, and other complex types across the network boundary.
Build Configuration
The trigger.config.ts configures the Trigger.dev deployment:
- TypeScript decorators enabled via
emitDecoratorMetadata()extension - Plugin artifacts bundled via
additionalFiles({ files: ['./plugins/**'] }) - Plugin dependencies collected and installed via
collectPluginDependencies() - External packages exclude unused NestJS optional dependencies (websockets, microservices, gRPC, Kafka, MQTT, NATS, AMQP)
TriggerLogger
A custom LoggerService implementation that forwards NestJS logs to Trigger.dev's structured logger, making them visible in the Trigger.dev dashboard. Supports all log levels: log, error, warn, debug, verbose, and fatal.
Module Structure
| Module | Purpose |
|---|---|
TriggerWorkerModule | Root module for worker context |
TriggerInternalModule | Minimal module for schedule dispatcher |
TriggerFacadesModule | Facade services with remote proxies |
TriggerPipelineModule | Pipeline execution services |
TriggerPluginsModule | Plugin system with local store |
TriggerRemoteCacheModule | Cache services via remote proxy |