FabricFabricHarness
Reference

SDK entrypoints, runtimes, and targets

Understand Lite vs Full SDK imports, stateless vs inline vs Temporal execution, and deployment targets.

Fabric Harness has three independent choices. They are intentionally separate:

  1. SDK entrypoint — what you import in agent code.
  2. Runtime — how sessions execute and whether state is kept.
  3. Target — where the built or driven agent runs.

Keeping these separate lets a 10-line webhook grow into a durable background agent without changing the core init() / agent.session() / session.prompt() / session.skill() / session.task() / session.shell() primitives.

1. SDK entrypoints

EntrypointImportUse it whenIncludes
Lite SDK@fabric-harness/sdk/liteYou want the smallest authoring surface and import graph for headless, edge, serverless, or prototype agents.defineAgent, agent, init, schema, defineCommand, defineTool, session.skill(), tasks, local/empty/remote sandbox helpers, filesystem sources, and basic MCP connection.
Full SDK@fabric-harness/sdkYou are building production agents with typed I/O, policies, providers, durable stores, artifacts, telemetry, Docker/remote sandboxes, result validation, or model runtime control.Everything in Lite, plus provider implementations, policy evaluators, built-in file/shell tools, stores, telemetry, result extraction, context budgeting, Docker, remote sandbox helpers, and stdio MCP.

The Full SDK is a runtime-value superset of the Lite SDK. If an import works from @fabric-harness/sdk/lite, the same runtime export should also work from @fabric-harness/sdk.

Lite SDK entrypoint
import { defineAgent } from '@fabric-harness/sdk/lite';

export default defineAgent(async ({ init, payload }) => {
  const session = await (await init({ runtime: 'stateless' })).session();
  return { reply: await session.prompt<string>(String((payload as any)?.message ?? '')) };
}, { name: 'echo' });
Full SDK entrypoint
import { agent, schema } from '@fabric-harness/sdk';

export default agent({
  name: 'echo',
  input: schema.object({ message: schema.string() }),
  output: schema.object({ reply: schema.string() }),
  async run({ init, input }) {
    const session = await (await init({ runtime: 'stateless' })).session();
    return { reply: await session.prompt<string>(input.message) };
  },
});

2. Runtimes

RuntimeState modelBest forTradeoff
statelessNo persisted session history. Each invocation is independent.High-volume webhooks, edge/serverless agents, simple headless automations, prototypes.No durable artifacts, no stored approvals, no resumable history.
inlineRuns in the current process. Uses in-memory state by default or a configured SessionStore.Local development, Node servers, CI jobs, production web services with SQLite/Postgres/file storage.Process-local unless you configure a durable store.
temporalModel calls, shell commands, checkpoints, approvals, and child tasks run through Temporal workflows/activities.Long-running background agents, restartable jobs, approval-gated workflows, multi-day runs.Requires a Temporal server and worker process.

Runtime is not the same as SDK entrypoint. These are all valid:

await init({ runtime: 'stateless' }); // works with Lite or Full SDK
await init({ runtime: 'inline' });    // works with Lite or Full SDK
await init({ runtime: 'temporal' });  // driven through the Temporal integration

3. Targets

TargetCLIWhat it means
nodefh run ask --target node / fh build --target nodeRun or build a Node HTTP/server process. Uses inline runtime unless configured otherwise.
temporal-workerfh temporal-worker and fh run ask --target temporal-workerStart a worker and drive agents through Temporal workflows.
dockerfh build --target dockerPackage a Node build in a Docker-ready output.
cloudflarefh build --target cloudflareEmit a Cloudflare Worker-oriented build. Experimental until live Worker/R2 validation is complete.
foundry-hosted-agentfh build --target foundry-hosted-agentGenerate a hosted-agent deployment artifact.

Target is where the code runs. Runtime is how sessions execute. SDK entrypoint is what the agent imports.

Common combinations

ScenarioSDK entrypointRuntimeTarget
10-line webhookLitestatelessnode or cloudflare
Support agent with a mounted knowledge baseLite or Fullstateless or inlinenode or cloudflare
CI issue triageFullinlinenode
Durable issue triageFulltemporaltemporal-worker
Production Node serviceFullinline + SQLite/Postgres/file storenode or docker
Approval-gated background jobFulltemporaltemporal-worker

Remote coding agents can start from either entrypoint

Remote coding agents usually need a real Linux sandbox, a cloned repository, shell access, and a prompt from the caller. The Lite SDK now exposes the remote sandbox adapter helper, so a connector can provide the same SandboxEnv shape without forcing the Full SDK import:

import { createRemoteSandboxEnv, defineAgent } from '@fabric-harness/sdk/lite';

export default defineAgent(async ({ init, payload, env }) => {
  const remote = await createProviderSandbox({ apiKey: env?.SANDBOX_API_KEY });
  const sandbox = createRemoteSandboxEnv(remote.api, { cleanup: true });
  const setup = await (await init({ sandbox, runtime: 'stateless' })).session();
  await setup.shell(`git clone ${(payload as any)?.repo} /workspace/project`);
  await setup.shell('npm install', { cwd: '/workspace/project' });
  return await setup.prompt(`Work in /workspace/project. ${(payload as any)?.prompt ?? ''}`);
}, { name: 'code' });

Use the Full SDK when the coding agent also needs typed input/output, capability policy, durable artifacts, approvals, provider routing, telemetry, or runtime: 'temporal'.

Skills work in both entrypoints

Skills are not a Lite-only feature. They are part of the shared session surface:

await session.skill('triager', { args: { message: 'How do I reset my password?' } });

Full metadata agents can also declare default inline skills directly on the agent definition:

import { agent, schema } from '@fabric-harness/sdk';

export default agent({
  name: 'support',
  skills: [{ name: 'triager', content: 'Search the knowledge base and reply concisely.' }],
  input: schema.object({ message: schema.string() }),
  async run({ init, input }) {
    const session = await (await init()).session();
    return { reply: await session.skill('triager', { args: input }) };
  },
});

Workspace skills under .fabricharness/skills/ are loaded by the Node/build runtimes and are available to both Lite and Full agents.

How to choose

  • Choose Lite SDK when you want fewer imports and less ceremony.
  • Choose Full SDK when you need typed I/O, policies, providers, artifacts, telemetry, durable stores, or deployment/runtime controls.
  • Choose stateless when persistence would be wasted or harmful.
  • Choose inline when you want ordinary process-local execution, optionally backed by a store.
  • Choose temporal when the run must survive restarts, wait for approvals, or continue for a long time.

Do not create separate Lite and Full copies of the same agent. Start with the Lite entrypoint if useful; move to the Full entrypoint when you need the extra imports or metadata. The session primitives stay the same.