
Security News
US Government Forces Anthropic to Pull Claude Fable Days After Launch
Anthropic says the directive cited national security concerns over a narrow jailbreak, but offered no specific technical details.
@olane/o-context
Advanced tools
Generic async context primitive with platform-specific implementations (AsyncLocalStorage for Node, variable swap for browser/RN)
The kernel layer of Olane OS - an agentic operating system where AI agents are the users, and you build tool nodes as applications.
o-core is the kernel layer of Olane OS - the foundational runtime for building tool nodes that AI agents use. Think of it as the Linux kernel: it defines how processes work (lifecycle, IPC, addressing, routing) but doesn't implement specific transport layers.
AI Agents (LLMs|Humans) → use → Tool Nodes (you build) → run on → Olane OS (o-core)
This is NOT a network framework or API library - it's the abstract operating system layer that makes inter-process communication (IPC), resource addressing, and hierarchical organization possible.
o:// protocol for filesystem-like tool node addressingpnpm install @olane/o-core @olane/o-protocol
Note:
oCoreis an abstract base class. For production use, extend higher-level packages likeoNodeTool(from@olane/o-node),oLaneTool(from@olane/o-lane), orMcpTool(from@olane/o-mcp). The example below demonstrates the core concepts.
import { oCore, oAddress, NodeType, NodeState } from '@olane/o-core';
import { oRequest, oResponse } from '@olane/o-core';
// Extend oCore to create your tool node
class MyToolNode extends oCore {
constructor(config: { address: oAddress }) {
super({
address: config.address,
type: NodeType.AGENT, // Type remains AGENT for now (legacy naming)
description: 'My first tool node',
methods: {
greet: {
name: 'greet',
description: 'Greets the user',
parameters: {
name: { type: 'string', required: true }
}
}
}
});
}
// Implement required abstract methods
async execute(request: oRequest): Promise<any> {
const { method, params } = request;
if (method === 'greet') {
return { message: `Hello, ${params.name}!` };
}
throw new Error(`Unknown method: ${method}`);
}
configureTransports(): any[] {
// Configure your transport layer (libp2p, HTTP, etc.)
return [];
}
async connect(nextHop: oAddress, target: oAddress) {
// Implement connection logic
return this.connectionManager.connect({ nextHop, target });
}
initializeRouter(): void {
// Initialize routing logic
this.router = new MyRouter();
}
async register(): Promise<void> {
// Register with parent or leader node
console.log('Tool node registered');
}
async unregister(): Promise<void> {
// Cleanup registration
console.log('Tool node unregistered');
}
}
// Create and start your tool node
// IMPORTANT: Use simple (non-nested) addresses in constructors.
// Nested addresses like 'o://company/customer-service' are created
// automatically at runtime during parent-child registration.
const toolNode = new MyToolNode({
address: new oAddress('o://customer-service')
});
await toolNode.start();
// AI agents can now use this tool node via its o:// address
const response = await toolNode.use(
new oAddress('o://customer-service'),
{
method: 'greet',
params: { name: 'Alice' }
}
);
// Response follows the standard wrapping structure:
// response.result.success - boolean indicating success/failure
// response.result.data - the returned data on success
// response.result.error - error details on failure
if (response.result.success) {
console.log(response.result.data); // { message: "Hello, Alice!" }
}
// Stop the tool node gracefully
await toolNode.stop();
// Tool Node A can communicate with Tool Node B using o:// addresses
// Use simple addresses in constructors; nested addresses are created at runtime
const salesTool = new MyToolNode({ address: new oAddress('o://sales') });
const analyticsTool = new MyToolNode({ address: new oAddress('o://analytics') });
await salesTool.start();
await analyticsTool.start();
// Sales tool calls analytics tool (inter-process communication)
const result = await salesTool.use(
new oAddress('o://analytics'),
{
method: 'analyze',
params: { data: salesData }
}
);
// Create a parent-child hierarchy of tool nodes
// Use simple addresses in constructors - nested addresses are created at runtime
const parent = new MyToolNode({ address: new oAddress('o://company') });
// Children use simple addresses with a parent reference
// During registration, child addresses become nested (e.g., 'o://company/sales')
const child1 = new MyToolNode({ address: new oAddress('o://sales') });
const child2 = new MyToolNode({ address: new oAddress('o://marketing') });
await parent.start();
await child1.start();
await child2.start();
// Register children with parent - this creates the nested addresses
parent.addChildNode(child1);
parent.addChildNode(child2);
// After registration:
// child1.address -> 'o://company/sales'
// child2.address -> 'o://company/marketing'
// Routing happens automatically through the hierarchy
Tool nodes (processes) transition through the following states:
STOPPED - Initial state, tool node is not runningSTARTING - Tool node is initializingRUNNING - Tool node is active and processing requestsSTOPPING - Tool node is shutting down gracefullyERROR - Tool node encountered an errorconsole.log(toolNode.state); // NodeState.RUNNING
await toolNode.stop();
console.log(toolNode.state); // NodeState.STOPPED
Addresses in Olane OS follow a hierarchical filesystem-like pattern:
// Hierarchical addresses exist at runtime after parent-child registration.
// They are created by the system, not by constructors directly.
// For example, after registration a child address may become:
const address1 = new oAddress('o://company/finance/accounting');
const address2 = new oAddress('o://users/alice/inbox');
// Address operations
console.log(address1.paths); // "company/finance/accounting"
console.log(address1.root); // "o://company"
console.log(address1.validate()); // true
// Static vs dynamic addresses
const staticAddr = address1.toStaticAddress();
console.log(staticAddr.toString()); // "o://accounting"
// IMPORTANT: When creating nodes in constructors, always use simple
// (non-nested) addresses. Nested addresses are created automatically
// during parent-child registration at runtime.
// ✅ new oAddress('o://my-tool')
// ❌ new oAddress('o://parent/my-tool') -- violates validateNotNested()
📖 For complete details on address resolution, routing algorithms, and custom resolvers, see the Router System documentation.
All inter-process communication (IPC) follows a request/response pattern using JSON-RPC 2.0:
// Making a request from one tool node to another
// Full signature: use(address: oAddress, data?: { method: string, params: any, id?: string }, options?: UseOptions)
const response: oResponse = await toolNode.use(
new oAddress('o://target-toolnode'),
{
method: 'processData',
params: { key: 'value' },
id: 'unique-request-id'
}
);
// Always check the response structure
if (response.result.success) {
console.log('Data:', response.result.data);
} else {
console.error('Error:', response.result.error);
}
// Transport-level errors throw exceptions
try {
const response = await toolNode.use(targetAddress, requestData);
// Check response.result.success for application-level errors
} catch (error) {
if (error instanceof oError) {
console.error(`Transport error ${error.code}: ${error.message}`);
}
}
📖 Learn more about JSON-RPC messaging, request states, and connection lifecycle in the Connection System documentation.
When you call use(), the response follows a standard wrapping structure created by the ResponseBuilder. In higher-level packages (@olane/o-node, @olane/o-tool, @olane/o-lane), responses are wrapped with success, data, and error fields:
const response = await toolNode.use(targetAddress, {
method: 'processData',
params: { key: 'value' }
});
// Standard response structure:
// {
// jsonrpc: "2.0",
// id: "request-id",
// result: {
// success: boolean, // Whether the operation succeeded
// data: any, // The returned data (on success)
// error?: string // Error details (on failure)
// }
// }
// Always check success before accessing data
if (response.result.success) {
const data = response.result.data;
console.log('Result:', data);
} else {
console.error('Error:', response.result.error);
}
Important: Access data via
response.result.data, notresponse.resultdirectly. Theresultobject contains the wrapping fields (success,data,error), not the raw return value.
Every tool node tracks metrics automatically:
// Access tool node metrics
console.log(toolNode.metrics.successCount);
console.log(toolNode.metrics.errorCount);
// Built-in logging
toolNode.logger.debug('Debug message');
toolNode.logger.info('Info message');
toolNode.logger.warn('Warning message');
toolNode.logger.error('Error message');
oCore is an abstract base class that provides:
start(), stop(), initialize(), teardown()use(), useDirect(), connect()router, initializeRouter()addChildNode(), removeChildNode(), hierarchyManagerstate, NodeState enummetrics, logger, requestManagerHierarchical addressing and intelligent routing for tool nodes
const addr = new oAddress('o://domain/subdomain/resource');
addr.validate(); // Check if address is valid
addr.toStaticAddress(); // Convert to static address
addr.toCID(); // Convert to Content ID
// Router determines the next hop in the network
const { nextHopAddress, targetAddress } = await router.translate(
address,
node
);
📚 View detailed Router System documentation →
Inter-Process Communication (IPC) layer for tool-node-to-tool-node messaging
// Connections are cached and reused
const connection = await connectionManager.connect({
nextHop: nextHopAddress,
target: targetAddress
});
// Send data over the connection
const response = await connection.send({
address: 'o://target/service',
payload: { key: 'value' }
});
📚 View detailed Connection System documentation →
Manages parent-child relationships between tool nodes
toolNode.hierarchyManager.addChild(childAddress);
toolNode.hierarchyManager.removeChild(childAddress);
console.log(toolNode.hierarchyManager.children);
import { oTransport, TransportType, oConnection, oConnectionConfig } from '@olane/o-core';
class MyCustomTransport extends oTransport {
constructor() {
super(TransportType.CUSTOM);
}
async send(data: any): Promise<any> {
// Implement your transport logic (HTTP, WebSocket, etc.)
}
}
// Custom connection implementation
class MyConnection extends oConnection {
async transmit(request: oRequest): Promise<oResponse> {
// Implement your connection logic
const response = await fetch(this.nextHopAddress.toString(), {
method: 'POST',
body: request.toString()
});
return new oResponse(await response.json());
}
}
class MyToolNode extends oCore {
configureTransports(): any[] {
return [new MyCustomTransport()];
}
}
📖 For connection pooling, retry logic, middleware, and transport-specific implementations, see the Connection System documentation.
import { oRouter, RouteResponse } from '@olane/o-core';
class MyRouter extends oRouter {
async translate(address: oAddress, node: oCore): Promise<RouteResponse> {
// Implement custom routing logic
return {
nextHopAddress: calculatedNextHop,
targetAddress: address
};
}
isInternal(address: oAddress, node: oCore): boolean {
// Determine if address is internal to this node
return address.root === node.address.root;
}
async route(request: oRouterRequest, node: oCore): Promise<RouteResponse> {
// Handle routing requests
}
}
📖 For advanced routing patterns, custom resolvers, and hierarchical routing strategies, see the Router System documentation.
import { oError, oErrorCodes } from '@olane/o-core';
// In your execute method
async execute(request: oRequest): Promise<any> {
if (!isValid(request.params)) {
throw new oError(
oErrorCodes.INVALID_PARAMS,
'Invalid parameters provided'
);
}
try {
return await processRequest(request);
} catch (error) {
throw new oError(
oErrorCodes.EXECUTION_ERROR,
error.message
);
}
}
import { setupGracefulShutdown } from '@olane/o-core';
const toolNode = new MyToolNode({ address: new oAddress('o://my-toolnode') });
await toolNode.start();
// Setup graceful shutdown handlers
setupGracefulShutdown(async () => {
console.log('Shutting down gracefully...');
await toolNode.stop();
});
// Tool node will automatically stop on SIGINT/SIGTERM
Abstract base class for building tool nodes.
address: oAddress - The tool node's hierarchical addressstate: NodeState - Current lifecycle statemetrics: oMetrics - Performance and usage metricshierarchyManager: oHierarchyManager - Manages child nodesrouter: oRouter - Routing logicconnectionManager: oConnectionManager - Connection poolingasync start(): Promise<void> - Start the tool nodeasync stop(): Promise<void> - Stop the tool node gracefullyasync use(address: oAddress, data?: UseDataConfig, options?: UseOptions): Promise<oResponse> - Communicate with another tool node (IPC). The options parameter supports noRouting, isStream, onChunk, readTimeoutMs, drainTimeoutMs, and abortSignal.async useDirect(address: oAddress, data?: UseDataConfig): Promise<oResponse> - Send a request without routing (equivalent to use() with { noRouting: true })async useStream(address: oAddress, data: UseDataConfig, options: UseStreamOptions): Promise<oResponse> - Send a streaming request to another tool nodeasync execute(request): Promise<any> - Execute a request (abstract - you implement this)addChildNode(node): void - Add a child tool noderemoveChildNode(node): void - Remove a child tool nodeasync whoami(): Promise<any> - Get tool node informationvalidate(): boolean - Validate address formattoStaticAddress(): oAddress - Convert to static addresstoString(): string - Get string representationequals(other): boolean - Compare addressesasync toCID(): Promise<CID> - Convert to Content IDnew oError(code: oErrorCodes, message: string, data?: any)
toJSON(): object - Serialize errorstatic fromJSON(json): oError - Deserialize error# Run tests
pnpm test
# Run tests in Node.js
pnpm run test:node
# Run tests in browser
pnpm run test:browser
# Install dependencies
pnpm install
# Build the package
pnpm run build
# Run in development mode
pnpm run dev
# Lint the code
pnpm run lint
o-core enables you to:
@olane/o-protocol - Protocol definitions and types@olane/o-node - Complete node implementation (extends o-core)@olane/o-tool - Tool system for agent capabilities@olane/o-storage - Storage layer for agent state@olane/o-network-cli - CLI for managing agent networksFor in-depth documentation on specific o-core components, see:
o:// protocol, address resolution, routing logic, and custom resolversWe welcome contributions! Please see our Contributing Guide for details.
ISC © Olane Inc.
Part of the Olane OS ecosystem - An agentic operating system where AI agents are the users and you build tool nodes as applications.
FAQs
Generic async context primitive with platform-specific implementations (AsyncLocalStorage for Node, variable swap for browser/RN)
The npm package @olane/o-context receives a total of 63 weekly downloads. As such, @olane/o-context popularity was classified as not popular.
We found that @olane/o-context demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?

Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.

Security News
Anthropic says the directive cited national security concerns over a narrow jailbreak, but offered no specific technical details.

Security News
A network of 152 Chrome live wallpaper extensions hid ad tracking and made extension-driven traffic look like Google search clicks.

Company News
Socket’s first CISO brings deep experience securing high-growth SaaS companies as open source supply chain threats accelerate.