FabricFabricHarness
Deployment

Temporal Worker

Run agent sessions as durable Temporal workflows.

The Temporal worker target turns sessions into durable Temporal workflows. Prompts, skills, tasks, shell calls, checkpoints, approvals, and cancellation all route through the SessionRuntime boundary; deterministic workflow code orchestrates state, and nondeterministic work happens in activities.

Status: production-pilot ready for controlled deployments. Use it for long-running jobs, approval delays, and restart durability after validating against your Temporal namespace. The scheduled/manual live workflow now uses real Temporal gRPC readiness, DB_PORT=5432 for Postgres-backed temporalio/auto-setup, and end-to-end workflow smoke on hosted runners.

Build the worker artifact

fh build --target temporal-worker

Output:

.fabricharness/build/temporal-worker/
  dist/worker.mjs
  manifest.json
  README.temporal-worker.md

Run the worker

You can run the prebuilt artifact:

node .fabricharness/build/temporal-worker/dist/worker.mjs

Or run a worker against the live workspace (great for development):

fh temporal-worker --task-queue fabric-harness --address localhost:7233

Drive an agent on the worker

fh run ask --target temporal-worker --id ask-001 --prompt "What is Temporal?"

The CLI:

  1. Connects to Temporal,
  2. Starts (or resumes) the session workflow with id ask-001,
  3. Signals it with the prompt,
  4. Streams output back.

Workflow model

graph LR
    A[Session workflow] --> P[Prompt/skill/task request]
    A --> M[Model activity]
    A --> T[Tool activity]
    A --> S[Shell activity]
    A --> C[Checkpoint activity]
    A --> W{Approval needed?}
    W -->|yes| SIG[Wait for approval signal]
    SIG --> T
    W -->|no| R[Append result]

Runtime parity checklist

CapabilityTemporal path
session.prompt()Durable workflow request + model/tool activities
session.skill()Same prompt runtime with skill-loaded instructions
session.task()Durable task request; child-workflow shape where configured
session.shell()Shell activity through the selected sandbox
Checkpoint create/restoreActivity-backed when the sandbox reports support
ApprovalsWorkflow waits on approval signals; no worker thread is held
CancellationWorkflow/activity cancellation is propagated where provider APIs support it
Worker restartWorkflow state survives; activities are idempotency-keyed
Tenant/cost/audit eventsPropagated through session entries and store-backed events

Unsupported inline-only features should fail with explicit runtime errors rather than silently degrading.

Configuration

.fabricharness/config.ts:

export default {
  temporal: {
    address: 'localhost:7233',
    taskQueue: 'fabric-harness',
    namespace: 'default',
    workflowIdPrefix: 'fabric',
    promptWorkflowMode: 'hybrid',
    apiKeyEnv: 'TEMPORAL_API_KEY',     // for Temporal Cloud
    tls: { /* ... */ },
  },
};

Environment overrides:

VariablePurpose
FABRIC_TEMPORAL_ADDRESShost:port
FABRIC_TEMPORAL_TASK_QUEUEtask queue name
FABRIC_TEMPORAL_NAMESPACEnamespace
FABRIC_TEMPORAL_CONNECT_ATTEMPTSOptional bounded retry attempts for client/worker connection startup.
FABRIC_TEMPORAL_CONNECT_INITIAL_DELAY_MSOptional first retry delay in milliseconds.
FABRIC_TEMPORAL_CONNECT_MAX_DELAY_MSOptional max retry delay in milliseconds.

Temporal Cloud

Set address to your Temporal Cloud endpoint, configure mTLS or API key, and the worker connects normally:

export default {
  temporal: {
    address: 'my-namespace.tmprl.cloud:7233',
    namespace: 'my-namespace',
    apiKeyEnv: 'TEMPORAL_API_KEY',
    tls: { serverName: 'my-namespace.tmprl.cloud' },
  },
};

Operational notes

  • Workers are stateless. Run several behind your task queue for throughput.
  • Approval waits are signal-driven and consume no worker time.
  • Use Temporal's UI or temporal workflow show to inspect history independently of fh inspect.
  • Keep default unit/mock Temporal tests in main CI and run live Temporal smoke manually/scheduled against the namespace you operate. For local temporalio/auto-setup with Postgres, set DB_PORT=5432 and wait for a real gRPC connection rather than only checking the TCP port.
  • For production, test worker restart while a workflow is waiting for approval, retry behavior for failed activities, namespace/auth configuration, and cancellation of long shell/model work.