@helix-agents/runtime-temporal
Temporal runtime for durable agent execution. Provides crash recovery, automatic retries, and distributed execution using Temporal workflows.
Installation
bash
npm install @helix-agents/runtime-temporalAgentRegistry
Maps agent type names to configurations.
typescript
import { AgentRegistry } from '@helix-agents/runtime-temporal';
const registry = new AgentRegistry();
// Register agents
registry.register(ResearchAgent);
registry.register(SummarizerAgent);
// Get agent by name
const agent = registry.get('research-assistant');
// Check if registered
const exists = registry.has('research-assistant');
// Use default global registry
import { defaultAgentRegistry } from '@helix-agents/runtime-temporal';GenericAgentActivities
Activity implementations for Temporal workflows. No decorators—wrap these with platform-specific activity decorators.
typescript
import { GenericAgentActivities } from '@helix-agents/runtime-temporal';
const activities = new GenericAgentActivities({
registry, // AgentRegistry
stateStore, // StateStore
streamManager, // StreamManager
llmAdapter, // LLMAdapter
logger, // Optional: Logger
});
// Available activity methods:
activities.initializeAgentState(input);
activities.executeAgentStep(input);
activities.executeToolCall(input);
activities.registerSubAgents(input);
activities.recordSubAgentResult(input);
activities.markAgentFailed(input);
activities.markAgentAborted(input);
activities.endAgentStream(input);
activities.failAgentStream(input);
activities.checkExistingState(input);
activities.updateAgentStatus(input);runAgentWorkflow
Core workflow logic function. Wrap with Temporal workflow decorators.
typescript
import { runAgentWorkflow } from '@helix-agents/runtime-temporal/workflow-exports';
import type { AgentWorkflowActivities } from '@helix-agents/runtime-temporal/workflow-exports';
// In your workflow file
export async function agentWorkflow(input: AgentWorkflowInput): Promise<AgentWorkflowResult> {
const activities = proxyActivities<AgentWorkflowActivities>({
startToCloseTimeout: '5m',
});
return runAgentWorkflow(input, activities, {
startChildWorkflow: async (childInput) => {
return executeChild(agentWorkflow, {
workflowId: childInput.runId,
args: [childInput],
});
},
isCancellation: (error) => isCancellation(error),
log: {
info: (msg, data) => log.info(msg, data),
warn: (msg, data) => log.warn(msg, data),
error: (msg, data) => log.error(msg, data),
},
});
}Options:
startChildWorkflow- Function to start sub-agent workflowsisCancellation- Check if error is Temporal cancellationlog- Workflow-safe logger
TemporalAgentExecutor
Executor that starts and manages Temporal workflows. Same API as JSAgentExecutor.
typescript
import { TemporalAgentExecutor } from '@helix-agents/runtime-temporal';
const executor = new TemporalAgentExecutor({
client, // Temporal Client
taskQueue, // Task queue name
stateStore, // StateStore
streamManager, // StreamManager
logger, // Optional
});
// Execute agent
const handle = await executor.execute(MyAgent, 'Hello');
// Get existing handle
const handle = await executor.getHandle(MyAgent, 'run-123');
// Check if resumable
const result = await executor.canResume(MyAgent, 'run-123');DTOs
Type-safe schemas for workflow and activity inputs/outputs.
Workflow DTOs
typescript
import {
AgentWorkflowInputSchema,
AgentWorkflowResultSchema,
type AgentWorkflowInput,
type AgentWorkflowResult,
} from '@helix-agents/runtime-temporal';
interface AgentWorkflowInput {
agentType: string;
runId: string;
streamId: string;
message: string;
initialState?: Record<string, unknown>;
parentAgentId?: string;
}
interface AgentWorkflowResult {
status: 'completed' | 'failed' | 'cancelled';
output?: unknown;
error?: string;
}Activity DTOs
typescript
import {
InitializeAgentInputSchema,
ExecuteAgentStepInputSchema,
ExecuteToolCallInputSchema,
AgentStepResultSchema,
ToolCallResultSchema,
// ... and more
} from '@helix-agents/runtime-temporal';Signal DTOs
typescript
import {
PauseAgentSignalSchema,
ResumeAgentSignalSchema,
AbortAgentSignalSchema,
} from '@helix-agents/runtime-temporal';Cancellation Helpers
typescript
import {
type CancellationSignalProvider,
defaultCancellationSignalProvider,
createLinkedAbortController,
isActivityCancelled,
} from '@helix-agents/runtime-temporal';
// Check if activity is cancelled
if (isActivityCancelled()) {
throw new Error('Activity cancelled');
}
// Create linked abort controller
const controller = createLinkedAbortController();Heartbeat Helpers
typescript
import {
type HeartbeatProvider,
defaultHeartbeatProvider,
HeartbeatManager,
} from '@helix-agents/runtime-temporal';
// Manage heartbeats for long activities
const heartbeat = new HeartbeatManager({
intervalMs: 5000,
onHeartbeat: () => console.log('Heartbeat'),
});
heartbeat.start();
// ... do work ...
heartbeat.stop();Complete Example
activities.ts
typescript
import { GenericAgentActivities, AgentRegistry } from '@helix-agents/runtime-temporal';
import { InMemoryStateStore, InMemoryStreamManager } from '@helix-agents/store-memory';
import { VercelAIAdapter } from '@helix-agents/llm-vercel';
import { MyAgent } from './agent.js';
const registry = new AgentRegistry();
registry.register(MyAgent);
export function createActivities() {
const activities = new GenericAgentActivities({
registry,
stateStore: new InMemoryStateStore(),
streamManager: new InMemoryStreamManager(),
llmAdapter: new VercelAIAdapter(),
});
return {
initializeAgentState: activities.initializeAgentState.bind(activities),
executeAgentStep: activities.executeAgentStep.bind(activities),
executeToolCall: activities.executeToolCall.bind(activities),
registerSubAgents: activities.registerSubAgents.bind(activities),
recordSubAgentResult: activities.recordSubAgentResult.bind(activities),
markAgentFailed: activities.markAgentFailed.bind(activities),
markAgentAborted: activities.markAgentAborted.bind(activities),
endAgentStream: activities.endAgentStream.bind(activities),
failAgentStream: activities.failAgentStream.bind(activities),
checkExistingState: activities.checkExistingState.bind(activities),
updateAgentStatus: activities.updateAgentStatus.bind(activities),
};
}workflows.ts
typescript
import { proxyActivities, executeChild, isCancellation, log } from '@temporalio/workflow';
import type { AgentWorkflowActivities } from '@helix-agents/runtime-temporal/workflow-exports';
import { runAgentWorkflow } from '@helix-agents/runtime-temporal/workflow-exports';
import type { AgentWorkflowInput, AgentWorkflowResult } from '@helix-agents/runtime-temporal';
const activities = proxyActivities<AgentWorkflowActivities>({
startToCloseTimeout: '5m',
retry: {
initialInterval: '1s',
maximumInterval: '30s',
backoffCoefficient: 2,
maximumAttempts: 3,
},
});
export async function agentWorkflow(input: AgentWorkflowInput): Promise<AgentWorkflowResult> {
return runAgentWorkflow(input, activities, {
startChildWorkflow: async (childInput) => {
return executeChild(agentWorkflow, {
workflowId: childInput.runId,
args: [childInput],
parentClosePolicy: 'ABANDON',
});
},
isCancellation: (error) => isCancellation(error),
log: { info: log.info, warn: log.warn, error: log.error },
});
}worker.ts
typescript
import { Worker, bundleWorkflowCode, NativeConnection } from '@temporalio/worker';
import { createActivities } from './activities.js';
async function main() {
const connection = await NativeConnection.connect({ address: 'localhost:7233' });
const workflowBundle = await bundleWorkflowCode({
workflowsPath: './workflows.ts',
});
const worker = await Worker.create({
connection,
taskQueue: 'my-agents',
workflowBundle,
activities: createActivities(),
});
await worker.run();
}