
Research
/Security News
Mini Shai-Hulud Campaign Hits Red Hat Cloud Services npm Packages
A mini Shai-Hulud campaign compromised Red Hat Cloud Services npm packages to steal developer and CI/CD secrets during installation.
@agentick/shared
Advanced tools
Platform-independent types and utilities for Agentick. Works in both Node.js and browser environments.
pnpm add @agentick/shared
Reference data for known LLM models including context windows and capabilities. Supports runtime registration for custom/fine-tuned models.
Use registerModel() to add custom or fine-tuned models that aren't in the built-in catalog:
import { registerModel } from "@agentick/shared";
// Register a custom fine-tuned model
registerModel("myorg/custom-model-v1", {
name: "My Custom Model",
provider: "myorg",
contextWindow: 32768, // 32k context
maxOutputTokens: 8192,
supportsToolUse: true,
supportsVision: false,
isReasoningModel: false,
});
// Register multiple models at once
import { registerModels } from "@agentick/shared";
registerModels({
"myorg/model-small": {
name: "My Model Small",
provider: "myorg",
contextWindow: 16384,
maxOutputTokens: 4096,
supportsToolUse: true,
},
"myorg/model-large": {
name: "My Model Large",
provider: "myorg",
contextWindow: 128000,
maxOutputTokens: 8192,
supportsToolUse: true,
supportsVision: true,
},
});
import { getModelInfo, getContextWindow, getContextUtilization } from "@agentick/shared";
// Get full model info
const info = getModelInfo("gpt-4o");
console.log(info?.contextWindow); // 128000
console.log(info?.supportsVision); // true
// Just get context window
const contextWindow = getContextWindow("claude-3-5-sonnet");
console.log(contextWindow); // 200000
// Calculate utilization percentage
const utilization = getContextUtilization("gpt-4o", 64000);
console.log(utilization); // 50
interface ModelInfo {
name: string; // Display name
provider: string; // Provider name (openai, anthropic, google, etc.)
contextWindow: number; // Context window size in tokens
maxOutputTokens?: number; // Max output tokens
releaseDate?: string; // Model release date
supportsVision?: boolean; // Supports image input
supportsToolUse?: boolean; // Supports tool/function calling
isReasoningModel?: boolean; // Extended thinking model (o1, etc.)
}
The catalog includes models from:
When using adapters, model info from the adapter takes precedence over the catalog:
import { getEffectiveModelInfo, getEffectiveContextWindow } from "@agentick/shared";
// Adapter metadata overrides catalog values
const effectiveInfo = getEffectiveModelInfo(
{ contextWindow: 256000 }, // Adapter reports 256k
"custom-model",
);
// Priority: adapter > runtime registry > static catalog
const contextWindow = getEffectiveContextWindow(adapterMetadata, modelId);
import { formatContextWindow } from "@agentick/shared";
formatContextWindow(128000); // "128K"
formatContextWindow(1000000); // "1M"
formatContextWindow(2097152); // "2.1M"
Normalized response format type for structured output across providers:
import type { ResponseFormat } from "@agentick/shared";
// Free-form text (default behavior)
const text: ResponseFormat = { type: "text" };
// JSON output (provider ensures valid JSON)
const json: ResponseFormat = { type: "json" };
// Structured output conforming to a JSON Schema
const structured: ResponseFormat = {
type: "json_schema",
schema: {
type: "object",
properties: {
name: { type: "string" },
age: { type: "number" },
},
required: ["name"],
},
name: "person", // optional
};
ResponseFormat is accepted on both ModelInput (per-call) and ModelConfig (adapter default). Each adapter maps it to the provider's native format.
Content blocks represent different types of content in messages:
import type {
ContentBlock,
TextBlock,
ImageBlock,
ToolUseBlock,
ToolResultBlock,
} from "@agentick/shared";
// Text content
const text: TextBlock = {
type: "text",
text: "Hello, world!",
};
// Image content
const image: ImageBlock = {
type: "image",
source: {
type: "base64",
mediaType: "image/png",
data: "iVBORw0KGgo...",
},
};
// Tool use (model calling a tool)
const toolUse: ToolUseBlock = {
type: "tool_use",
id: "call_123",
name: "calculator",
input: { expression: "2 + 2" },
};
// Tool result (response to tool use)
const toolResult: ToolResultBlock = {
type: "tool_result",
toolUseId: "call_123",
content: [{ type: "text", text: "4" }],
};
import type { Message, UserMessage, AssistantMessage } from "@agentick/shared";
const userMessage: UserMessage = {
role: "user",
content: [{ type: "text", text: "Hello!" }],
};
const assistantMessage: AssistantMessage = {
role: "assistant",
content: [{ type: "text", text: "Hi there!" }],
};
Events emitted during streaming responses:
import type {
StreamEvent,
ContentDeltaEvent,
MessageEndEvent,
ToolCallEvent,
ContextUpdateEvent,
} from "@agentick/shared";
// Text streaming
const delta: ContentDeltaEvent = {
type: "content_delta",
delta: "Hello",
contentIndex: 0,
};
// Context utilization update
const contextUpdate: ContextUpdateEvent = {
type: "context_update",
modelId: "gpt-4o",
modelName: "GPT-4o",
provider: "openai",
contextWindow: 128000,
inputTokens: 1500,
outputTokens: 500,
totalTokens: 2000,
utilization: 1.56, // percentage
supportsVision: true,
supportsToolUse: true,
};
Typed errors with codes for proper error handling:
import {
AgentickError,
ValidationError,
AbortError,
isAbortError,
isAgentickError,
} from "@agentick/shared";
// Check error types
try {
await operation();
} catch (error) {
if (isAbortError(error)) {
console.log("Operation was cancelled");
} else if (isAgentickError(error)) {
console.log(`Error [${error.code}]: ${error.message}`);
}
}
// Throw typed errors
throw new ValidationError("email", "Invalid email format");
throw new AbortError("User cancelled");
throw AbortError.timeout(30000); // Timeout via AbortError factory
Utilities for normalizing various input formats:
import { normalizeContent, normalizeMessage } from "@agentick/shared";
// Normalize string to content blocks
const content = normalizeContent("Hello!");
// [{ type: "text", text: "Hello!" }]
// Normalize various message formats
const message = normalizeMessage("Hello!");
// { role: "user", content: [{ type: "text", text: "Hello!" }] }
const message2 = normalizeMessage({
role: "user",
content: "Hello!",
});
// { role: "user", content: [{ type: "text", text: "Hello!" }] }
The transport layer abstracts the connection between @agentick/client and an Agentick backend. Transport types live in @agentick/shared so both @agentick/client and @agentick/core can implement transports without circular dependencies.
import type {
ClientTransport,
TransportState,
TransportEventData,
TransportEventHandler,
TransportConfig,
} from "@agentick/shared";
The core transport interface. All transports implement this — SSE/HTTP, WebSocket, and local (in-process).
| Method | Description |
|---|---|
connect() | Establish connection |
disconnect() | Close connection |
send(input, sessionId?) | Send a message, returns AsyncIterable<TransportEventData> with .abort() |
subscribeToSession(id) | Subscribe to session events |
abortSession(id, reason?) | Abort a running execution |
closeSession(id) | Close a session |
submitToolResult(sessionId, toolUseId, result) | Submit tool confirmation result |
onEvent(handler) | Register event handler, returns unsubscribe function |
onStateChange(handler) | Register state change handler |
All transport events share this structure:
interface TransportEventData {
type: string; // Event type (e.g., "content_delta", "execution_end")
sessionId?: string; // Session this event belongs to
executionId?: string;
data?: unknown; // Structured event payload
}
The data field contains the original stream event payload. It is never spread into the top level — this prevents property collisions and makes the wire format predictable.
Wire format: The gateway sends EventMessage envelopes ({ type: "event", event: "<type>", sessionId, data }). The unwrapEventMessage() utility normalizes these to TransportEventData, promoting event to type and preserving data as-is.
"disconnected" | "connecting" | "connected" | "error"
| Transport | Package | Description |
|---|---|---|
| SSE/HTTP | @agentick/client | Default remote transport (HTTP + Server-Sent Events) |
| WebSocket | @agentick/client | Bidirectional via createWSTransport(config) |
| Unix Socket | @agentick/gateway | NDJSON over Unix domain socket (Node.js only) |
| Local | @agentick/core | In-process bridge via createLocalTransport(app) |
WebSocket and Unix socket transports are built on the shared createRPCTransport factory, which provides all protocol machinery (request correlation, event streaming, reconnection, session operations). Each transport is a thin delegate that provides wire-specific I/O.
See packages/shared/src/transport.ts for the ClientTransport interface and packages/shared/src/rpc-transport.ts for the RPC factory.
import type { ToolDefinition, ToolCall, ToolResult } from "@agentick/shared";
const tool: ToolDefinition = {
name: "calculator",
description: "Performs mathematical calculations",
inputSchema: {
type: "object",
properties: {
expression: { type: "string", description: "Math expression" },
},
required: ["expression"],
},
};
MIT
FAQs
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.

Research
/Security News
A mini Shai-Hulud campaign compromised Red Hat Cloud Services npm packages to steal developer and CI/CD secrets during installation.

Research
/Security News
The North Korean malware loader hides in a Packagist-listed package and its GitHub branch to fetch and execute remote code in a likely Contagious Interview-style lure.

Security News
The Rust project is moving toward formal rules on LLM use in contributions after months of internal debate over maintainer burden, code quality, and contributor experience.