runtime
Health Warn
- License — License: MIT
- Description — Repository has a description
- Active repo — Last push 0 days ago
- Low visibility — Only 6 GitHub stars
Code Fail
- fs.rmSync — Destructive file system operation in apps/playground/src/cases/06-session.ts
- process.env — Environment variable access in apps/playground/src/cases/shared.ts
Permissions Pass
- Permissions — No dangerous permissions requested
No AI report is available for this listing yet.
TypeScript Agent execution-layer SDK. You write the model and tools, it runs the loop.
Helix Runtime
What is Helix Runtime?
A TypeScript Agent execution-layer SDK. It handles all the runtime plumbing — multi-turn loops, tool orchestration, event streaming, context pruning — so you only need to pick a model, write tools, and define business logic.
What does it do?
- Multi-turn conversation loop (automatically handles tool call → re-reasoning cycles)
- Tool registration, parallel/sequential execution, error handling
- Full-lifecycle event streaming (streaming output, tool execution, context compaction — all observable)
- Context management (slice / token / summary compaction strategies)
- Cancellation control (AbortSignal)
- Sub-agent orchestration (wrap an Agent as a Tool)
What does it let you build?
- Spin up a complete AI Agent fast, no need to write loop control or tool scheduling yourself
- Swap any LLM (GPT / Claude / Gemini) into the same Agent framework, switch anytime
- Chain multiple Agents into a multi-Agent system (one Agent as another's Tool)
- Full observability — streaming output, tool calls, context compaction, subscribe to every event
- Write only business code, never touch the execution layer
Quick Start
pnpm add @helix/runtime @helix/models @helix/core @helix/tools
import { Agent } from "@helix/runtime";
import { getModel } from "@helix/models";
import { bashTool, readFileTool } from "@helix/tools";
const agent = new Agent({
model: getModel({
model: "gpt-4o",
apiKey: process.env.OPENAI_API_KEY,
}),
systemPrompt: "You are a helpful assistant.",
tools: [bashTool(), readFileTool()],
});
// Observe all events
agent.subscribe((event) => {
if (event.type === "message_update") {
process.stdout.write(event.delta);
}
});
// Run
await agent.prompt("List files in the current directory");
Stateless Loop (Low-level)
import { agentLoop } from "@helix/runtime";
const context = {
systemPrompt: "You are helpful.",
messages: [],
tools: [],
};
for await (const event of agentLoop([userMsg], context, { model })) {
if (event.type === "message_update") process.stdout.write(event.delta);
if (event.type === "agent_end") context.messages.push(...event.messages);
}
Packages
| Package | Description |
|---|---|
@helix/core |
Zero-dependency shared types: AgentMessage, ToolDef, ModelAdapter, AgentContext, Skill |
@helix/runtime |
Harness core: Agent, agentLoop, ToolRegistry, ToolExecutor, Compaction, Session, Skill |
@helix/models |
LLM adapters: OpenAI-compatible, Anthropic-compatible |
@helix/tools |
Built-in tools: readFileTool, writeFileTool, globTool, bashTool |
@helix/core ← Zero-dependency shared types
↑ ↑ ↑
@helix/runtime @helix/models @helix/tools ← Each depends on core
↑
Your Agent ← Consumes the SDK
Core Concepts
Agent Class
A stateful wrapper that manages message accumulation, abort control, and event subscription.
import { Agent } from "@helix/runtime";
const agent = new Agent({
model, // ModelAdapter
systemPrompt: "You are helpful.", // System prompt
tools: [myTool], // ToolDef[]
convertToLlm: (msgs) => msgs, // Filter messages for LLM
transformContext: async (msgs) => { // Context pruning/compression
return msgs.slice(-50);
},
});
agent.subscribe(handler); // Observe events
await agent.prompt("..."); // Send user message
await agent.continue(); // Resume from context
agent.abort(); // Cancel current run
agent.clearMessages(); // Reset state
SteeringMode controls concurrent prompt handling:
"one-at-a-time"(default) — serial queue, eachprompt()waits for the previous to finish"all"— concurrent execution
const agent = new Agent({ model, steeringMode: "all" });
Tool System
Tools are plain objects with a schema and an execute function:
import type { ToolDef } from "@helix/core";
const calculator: ToolDef = {
name: "calculator",
description: "Evaluate a math expression",
parameters: {
type: "object",
properties: {
expression: { type: "string", description: "Math expression" },
},
required: ["expression"],
},
execute: async (args) => {
return { result: eval(args.expression) };
},
};
Execution modes: parallel (default) or sequential (set executionMode: "sequential" on the tool).
Loop Hooks give you control over tool execution:
const agent = new Agent({
model,
tools: [myTool],
beforeToolCall: async (ctx) => {
console.log(`About to call: ${ctx.name}`);
return "allow"; // or "block" to skip
},
afterToolCall: async (ctx) => {
console.log(`Called ${ctx.name} in ${ctx.durationMs}ms`);
},
shouldStopAfterTurn: async (ctx) => {
return ctx.turnCount >= 5; // Stop after 5 turns
},
});
A tool can signal loop termination by returning { terminate: true }.
Built-in Tools
@helix/tools provides ready-to-use tools with safety features:
import { readFileTool, writeFileTool, globTool, bashTool } from "@helix/tools";
const tools = [
readFileTool({ rootDir: "./project", maxChars: 50000 }),
writeFileTool({ rootDir: "./project", createDirs: true }),
globTool({ rootDir: "./project", maxResults: 100 }),
bashTool({
cwd: "./project",
timeoutMs: 30000,
allowedCommands: ["ls", "cat", "grep"],
blockedPatterns: ["rm -rf"],
}),
];
Sub-agent
Wrap any Agent as a tool for multi-agent orchestration:
import { createSubagentTool } from "@helix/runtime";
const specialist = new Agent({
model,
systemPrompt: "You are a domain specialist.",
tools: [domainTool],
});
const orchestrator = new Agent({
model,
tools: [
createSubagentTool({
name: "specialist",
description: "Delegate tasks to the domain specialist.",
agent: specialist,
onEvent: (e) => console.log("[specialist]", e.type),
}),
],
});
Multimodal
Both low-level and high-level APIs support image content:
import { imagePart } from "@helix/core";
// Low-level: pass ContentPart[] to agentLoop
const msg = {
role: "user",
content: [
textPart("What's in this image?"),
imagePart(base64Data, "image/png"),
],
};
// High-level: Agent.prompt accepts ContentPart[]
await agent.prompt([
textPart("Describe this"),
imagePart(imageBuffer, "image/jpeg"),
]);
Context Compaction
Built-in strategies to keep conversation context under control:
import { sliceCompaction, tokenCompaction, summaryCompaction, compose } from "@helix/runtime";
// Slice: keep last N messages
const agent = new Agent({
model,
transformContext: sliceCompaction({ keepLast: 20, triggerAt: 50 }),
});
// Token-based: keep recent tokens
const agent = new Agent({
model,
transformContext: tokenCompaction({ keepRecentTokens: 2000, triggerAtTokens: 4000 }),
});
// Summary: LLM-powered summarization
const agent = new Agent({
model,
transformContext: summaryCompaction({
summaryModel: model,
summaryInstructions: "Summarize in 2 sentences.",
triggerAtTokens: 4000,
}),
});
// Compose: chain multiple strategies
const agent = new Agent({
model,
transformContext: compose(
customPrune,
sliceCompaction({ keepLast: 20, triggerAt: 50 }),
),
});
Session Persistence
import { MemorySessionStore, FileSessionStore } from "@helix/runtime";
// In-memory (for testing)
const store = new MemorySessionStore();
// File-based (JSONL + meta)
const store = new FileSessionStore("./sessions");
const session = await store.create({ systemPrompt: "You are helpful." });
await store.save({ ...session, messages });
const loaded = await store.get(session.id);
Skill System
Skills are reusable prompt templates loaded from YAML/JSON files:
import { loadSkills, formatSkillsForPrompt } from "@helix/runtime";
const { skills, diagnostics } = await loadSkills({ dirs: ["./skills"] });
const agent = new Agent({ model, skills });
// Invoke a skill programmatically
await agent.invokeSkill("code-review", { file: "src/index.ts" });
Event System
agentLoop returns AsyncIterable<AgentEvent>. Every behavior is observable:
agent_start
turn_start
message_start / message_end (user message)
message_start
message_update (streaming delta)
thinking_update (extended thinking)
message_end (assistant reply)
tool_execution_start → tool_execution_end (tool call)
context_compacted (when compaction triggers)
turn_end
agent_end
error (on failure)
13 event types covering the full agent lifecycle.
Development
pnpm install # Install dependencies
pnpm build # Build all packages
pnpm dev # Dev mode (watch)
pnpm test # Run tests
pnpm typecheck # Type checking
pnpm lint # Lint
Run playground cases:
cd apps/playground
pnpm dev -- basics # Model streaming, Agent basics, agentLoop
pnpm dev -- tools # Tool execution, hooks, parallel/sequential
pnpm dev -- context # Compaction strategies
pnpm dev -- control # AbortSignal, steering mode, thinking level
pnpm dev -- subagent # Multi-agent orchestration
pnpm dev -- session # Session persistence
pnpm dev -- multimodal # Image support
Tech Stack
- Language: TypeScript 6, ESNext modules
- Build: tsup (ESM + DTS)
- Orchestration: Turborepo
- Package Manager: pnpm 10
Acknowledgments
Helix Runtime is inspired by and references pi — an open-source agent harness project by earendil-works. Pi's architecture of separating agent runtime from model layer directly influenced Helix's design philosophy. Huge thanks to the pi team for pioneering this approach.
License
MIT
Reviews (0)
Sign in to leave a review.
Leave a reviewNo results found