@fabric-harness/temporal
v2.2.3
Published
Temporal.io durable workflow runtime adapter for TechFabric Harness.
Readme
@fabric-harness/temporal
Temporal.io durable workflow runtime adapter for TechFabric Harness.
Run agents as Temporal workflows. The agent code is unchanged — the runtime swaps. Sessions survive crashes, restarts, and human approval delays via Temporal's durable execution.
Status: production-pilot ready for controlled deployments after validating against your Temporal namespace. Main CI covers mock/unit paths, and the scheduled/manual live workflow now runs a real Temporal gRPC readiness probe plus end-to-end workflow smoke against temporalio/auto-setup.
Install
npm install @fabric-harness/temporal @fabric-harness/sdkUsage
Direct API (recommended)
Wire the Temporal runtime directly into init() via sessionRuntime. Each
prompt/skill/task/shell/checkpoint call routes through Temporal workflows:
import { init } from '@fabric-harness/sdk';
import { temporalSessionRuntime } from '@fabric-harness/temporal';
const fabric = await init({
runtime: 'temporal',
sessionRuntime: temporalSessionRuntime({
address: 'localhost:7233',
namespace: 'default',
taskQueue: 'fabric-harness',
}),
});
const session = await fabric.session();
await session.prompt('Triage issue #42');CLI-managed (alternative)
When running under fabric-harness run <agent> --temporal, the CLI constructs
the Temporal session for you and you only declare the runtime mode:
import { init } from '@fabric-harness/sdk/strict';
const fabric = await init({ runtime: 'temporal' });Run a worker:
fh temporal-worker --task-queue fabric-harness --address localhost:7233Parity and operating model
| Capability | Temporal path |
| --- | --- |
| session.prompt() / session.skill() | Durable workflow request with model/tool activities |
| session.task() | Durable task request; child-workflow shape where configured |
| session.shell() | Shell activity through the selected sandbox |
| Checkpoint create/restore | Activity-backed when the sandbox reports support |
| Approvals | Workflow waits on approval signals; no worker thread is held |
| Cancellation/retry | Temporal cancellation and activity retry semantics, propagated where provider APIs support them |
| Worker restart | Workflow state survives; idempotency keys avoid duplicated side effects |
| Usage, cost, and attachments | Model attempts persist token/cost usage; configured stores retain attachment references across workers |
AbortSignal is never serialized into workflow history. The client starts the workflow, listens for
abort, cancels the handle, and surfaces AbortError to the caller.
Unsupported inline-only features should fail explicitly rather than silently degrading.
For tests and CI without a Temporal cluster, this package also exports a mock runtime:
import { createMockTemporalRuntime } from '@fabric-harness/temporal';
const runtime = createMockTemporalRuntime({ sessionId: 'test-1' });Remote sandbox continuity
When a remote sandbox exposes encodeRef(), local activities persist a
tenant-bound sandbox_ref before the first sandbox operation. Use a shared
lease store so only one worker can control the reconnected sandbox:
import { postgresSandboxOwnershipLeaseStore } from '@fabric-harness/node';
const activities = createLocalTemporalActivities({
store,
sandbox: createRemoteSandbox,
tenantId: (sessionId) => tenantForSession(sessionId),
sandboxOwnership: {
store: postgresSandboxOwnershipLeaseStore(pg),
ownerId: process.env.HOSTNAME!,
leaseMs: 60_000,
},
});Every sandbox operation renews the lease. After worker rotation, a new worker attaches from the persisted provider reference; the former worker is fenced from reads, writes, commands, snapshots, and restores.
Documentation
License
Apache-2.0
