product agents runtime work

Build product agents without rebuilding the harness.

AI demos usually stop at one model call. Real agents need sessions, tool loops, approvals, storage, sandboxing, logs, events, streaming, and model routing. Harness Kernel gives your TypeScript app that runtime layer while your product keeps control.

Harness Kernel
the real problem not model calls

Every serious agent turns into a runtime project.

Once an agent belongs inside a product, the hard part is no longer the prompt. It is the harness around the prompt: durable sessions, controlled tools, observable events, safe execution, and host-specific policy.

Sessions and transcripts

keep conversations, cursors, branches, snapshots, and run state outside ad hoc app code

Tool loops and approvals

run tools with explicit schemas, risk, permission checks, and user approval surfaces

Storage and observability

record events, metrics, logs, tool calls, and replayable runtime facts

Sandbox and model routing

choose providers, models, execution policy, and sandboxing per host

agent behavior complete mode package
import { defineAgent } from "@harness-kernel/core/agent";
import { HarnessContextProvider } from "@harness-kernel/core/agent/context";
import { HarnessEvent } from "@harness-kernel/core/agent/event";
import { HarnessHook } from "@harness-kernel/core/agent/hook";
import { HarnessMode } from "@harness-kernel/core/agent/mode";
import { HarnessRole, NativeRoles, RoleTargets } from "@harness-kernel/core/agent/role";
import type { AgentActionSession, AgentReadSession } from "@harness-kernel/core/agent/session";
import { HarnessTool } from "@harness-kernel/core/agent/tool";
import { s, type InferInput } from "@harness-kernel/core/schema";
import { BashTool } from "@harness-kernel/tools-node";

type DevState = { checkpoints: string[]; lastModeEnter?: string };

const checkpointSchema = s.object({
  label: s.string().min(1),
});

type CheckpointInput = InferInput<typeof checkpointSchema>;

class CheckpointCreatedEvent extends HarnessEvent<{ label: string }> {
  static type = "checkpoint.created";
}

class ReviewerRole extends HarnessRole {
  label = "Reviewer";
  name = "reviewer";
  target = RoleTargets.Messages;
  nativeRole = NativeRoles.User;
  description = "A review-focused message role.";
}

class ProjectContext extends HarnessContextProvider {
  label = "Project Context";

  render(session: AgentReadSession<DevState>) {
    const state = session.state.get();
    return [
      "Mode: " + session.mode.current().type,
      "Checkpoints: " + (state.checkpoints.join(", ") || "none"),
    ].join("\n");
  }
}

class CreateCheckpointTool extends HarnessTool<CheckpointInput> {
  name = "create_checkpoint";
  description = "Save a review checkpoint in agent state.";
  schema = checkpointSchema;
  risk = "write" as const;
  requiresApproval = true;

  async execute(input: CheckpointInput, session: AgentActionSession<DevState>) {
    const next = [...session.state.get().checkpoints, input.label];
    session.state.update({ checkpoints: next });
    await session.events.emit(CheckpointCreatedEvent, { label: input.label });
    return { content: "Checkpoint saved: " + input.label };
  }
}

class DevMode extends HarnessMode {
  label = "Dev";
  model = "openai/gpt-5.1";
  prompt = "Use tools carefully and create checkpoints before risky changes.";
  providers = [new ProjectContext()];
  tools = [new BashTool(), new CreateCheckpointTool()];
  maxTurns = 8;
  toolApproval = "ask" as const;

  async onEnter(session: AgentActionSession<DevState>) {
    session.state.update({ lastModeEnter: new Date().toISOString() });
  }
}

class CheckpointHook extends HarnessHook.for(CheckpointCreatedEvent) {
  onActive(session: AgentActionSession<DevState>, event: CheckpointCreatedEvent) {
    session.log.info("checkpoint.created", { label: event.payload.label });
  }
}

const devMode = new DevMode();

export const agent = defineAgent({
  key: "dev-agent",
  label: "Dev Agent",
  sharedState: { initial: () => ({ checkpoints: [] }) },
  declaredEvents: [CheckpointCreatedEvent],
  initialMode: devMode,
  modes: [devMode],
  roles: [new ReviewerRole()],
  hooks: [new CheckpointHook()],
});
runtime host host-owned execution
import { createHarnessSessionStore } from "@harness-kernel/core/runner";
import { OpenAIProvider } from "@harness-kernel/provider-openai";

const store = await createHarnessSessionStore({
  agent: { definition: agent },
  providers: [new OpenAIProvider()],
  defaultModel: "openai/gpt-5.1",
});
the boundary stable

Build the agent your way. Keep the runtime yours.

Harness Kernel sits between hand-rolled harness code and framework-owned runtimes. It is a boundary for product agents: the agent package stays focused on behavior, while the host application owns every operational dependency and policy decision.

Open the boundary map

Agent behavior

modes, tools, hooks, roles, context providers, events, shared state

Runtime ownership

model providers, storage, sandbox, approvals, logs, resources, sessions

Coupling control

behavior packages depend on kernel contracts, not host infrastructure

Kernel contract

explicit public subpaths, namespaced model refs, and optional modules

kernel core zero deps

@harness-kernel/core is the harness contract.

Core contains contracts, sessions, schema, events, logging interfaces, model provider routing, memory storage, and a noop sandbox. It gives the runtime shape without hiding a default provider, default storage layer, default tool catalog, or default sandbox.

Agent Space

Package behavior with `defineAgent`, `HarnessMode`, mode-owned `HarnessTool` instances, agent-owned hooks, roles, context providers, custom events, and shared state.

Define behavior

Runtime Host

Compose `createHarnessSessionStore` with model providers, `defaultModel`, storage, sandbox, approvals, logging, resources, streaming, and session lifecycle policy.

Host the agent
runtime modules optional

Add modules without accepting hidden defaults.

There is no hidden runtime. The host chooses every provider, storage backend, sandbox, log sink, and tool package explicitly.

@harness-kernel/core

Zero-dependency runtime contracts, sessions, events, schema, and memory/noop infrastructure.

@harness-kernel/provider-openai

OpenAI model provider built on the AI SDK provider package.

@harness-kernel/provider-ai-sdk

Generic model provider bridge for Vercel AI SDK language models.

@harness-kernel/storage-file

File-backed run storage for transcripts, events, snapshots, metrics, and cursors.

@harness-kernel/sandbox-local

Local shell sandbox owned by the host application.

@harness-kernel/tools-node

Mode-owned Bash and filesystem tools for Node-based hosts.

@harness-kernel/logging-file

JSONL operational log sink for runtime-owned logging.

@harness-kernel/create

Scaffold and devtool package. It is not hidden infrastructure.

built for real hosts portable

The same agent can run where your app already lives.

CLI backend service web app session desktop app
start small copyable

Start with contracts, then add the host pieces you need.

$ pnpm create @harness-kernel $ pnpm docs:build