MVP / Alpha · v0.5.0 on npm

FabricFabricHarness

A headless TypeScript framework for durable, deployable autonomous agents. No TUI, no GUI — just an SDK and a CLI.

$npm install -g @fabric-harness/cli

Databricks · first-party

Build governed agents on Databricks

One databricks() call wires the agent's brain (Mosaic AI Model Serving), tools (governed SQL, Unity Catalog, AI Functions, Genie, Lakeflow, Vector Search, Feature Serving), durable state (Lakebase), and cost controls — all under a single Unity Catalog principal. Layered on top of UC; it never re-implements your permissions.

Mosaic AI servingUnity CatalogVector SearchGenieLakeflowLakebaseAgent Bricks
.fabricharness/agents/analytics-copilot.ts
1import { agent } from '@fabric-harness/sdk';
2import { databricks } from '@fabric-harness/databricks';
3
4// One call wires the brain, tools, governance, and state — under one UC principal.
5const dbx = databricks({
6 host: process.env.DATABRICKS_HOST!,
7 principal: { kind: 'service-principal', /* clientId, clientSecret, host */ },
8 model: 'databricks-meta-llama-3-3-70b-instruct', // Mosaic AI Model Serving
9 warehouseId: process.env.DATABRICKS_WAREHOUSE_ID!, // governed SQL
10 vectorSearch: { index: 'main.kb.docs', textColumn: 'chunk' }, // RAG
11 genie: { spaceId: 'space-123' }, // NL → SQL analytics
12 governance: { stewardAudience: 'data-steward' }, // Unity Catalog + approvals
13});
14
15export default agent({
16 run: async ({ init }) => {
17 const fabric = await init({ modelProvider: dbx.modelProvider, tools: dbx.tools, policy: dbx.policy });
18 return (await fabric.session()).prompt('How many orders shipped last week?');
19 },
20});

Unity Catalog governance, RAG, deploy to Databricks Apps / Agent Bricks · full Databricks guide →

Databricks is first-party — Fabric also speaks every major model provider: Anthropic, OpenAI, Azure OpenAI, Bedrock, Google Vertex, Cohere, Mistral, Groq, and Cloudflare Workers AI. Model providers →

Authoring

Start fast. Go strict when you need to.

The bare @fabric-harness/sdk import gives you a working agent in 8 lines — headless defaults injected on every init(). Switch to @fabric-harness/sdk/strict for Temporal-backed durability or compliance workloads where every option must be declared.

.fabricharness/agents/echo.ts
1import { agent } from '@fabric-harness/sdk';
2
3export default agent<{ message: string }>({
4 name: 'echo',
5 triggers: { webhook: true },
6 run: async ({ init, input }) => {
7 const session = await (await init()).session();
8 return { reply: await session.prompt<string>(input.message) };
9 },
10});

Defaults injected on every init(): runtime: stateless, sandbox: virtual, loopRuntime: pi-agent-core, compaction: { enabled: true }. Override any value per call.

Sandboxes

Same agent code, swap the sandbox

One init({ sandbox }) call picks where the shell, filesystem, and tools execute. Edge, durable workflow, hosted, remote dev box, GPU — pick what fits.

.fabricharness/agents/cloudflare.ts
1import { agent } from '@fabric-harness/sdk';
2import { getCloudflareSandbox } from '@fabric-harness/cloudflare';
3
4export default agent({
5 run: async ({ init, env }) => {
6 const sandbox = await getCloudflareSandbox(env.SANDBOX, 'session-1');
7 const session = await (await init({ sandbox })).session();
8 return await session.prompt('hello edge');
9 },
10});

edge worker · full Cloudflare guide →

Sources

Mount any knowledge base — no embeddings

Filesystem sources mount Markdown, MDX, or any text into a sandbox so the agent's built-in grep, glob, and read tools see it as ordinary files. Supports Fumadocs, Mintlify (local or hosted MCP), Cloudflare R2, S3, Azure Blob, and arbitrary HTTP.

.fabricharness/agents/runbook.ts
1import { agent, fumadocsSource, withFilesystemSources } from '@fabric-harness/sdk';
2
3export default agent<{ alert: string }>({
4 name: 'runbook',
5 triggers: { webhook: true },
6 run: async ({ init, input }) => {
7 const sandbox = withFilesystemSources('virtual', [
8 { mountAt: '/workspace/runbooks', source: fumadocsSource('./runbooks') },
9 ]);
10 const session = await (await init({ sandbox })).session();
11 return { plan: await session.prompt<string>(`Alert: "${input.alert}". Match a runbook.`) };
12 },
13});