Prime Agent Contracts Package: Key TypeScript Interfaces Defined

The contracts package in PrimeIntellect-ai/prime-agent defines the core TypeScript interfaces—AgentMessage, AgentEvent, ModelRequest, ModelResponse, ToolCall, ToolResult, SessionState, and LoginCredentials—that enforce type safety across the daemon, TUI, AI provider layer, and coding-agent subsystem.

The Prime Agent contracts package serves as the centralized boundary layer within the PrimeIntellect-ai/prime-agent monorepo. By codifying data shapes in TypeScript, these interfaces ensure that messages exchanged between the daemon, frontend clients, and AI providers remain type-safe and decoupled from implementation specifics.

Core Agent Communication Interfaces

The foundational contracts for inter-process communication reside in packages/agent/src/types.ts. These definitions govern how the daemon broadcasts state changes and how clients interpret incoming events.

AgentMessage

AgentMessage represents the base envelope for every transmission from the daemon to connected clients. It employs a discriminated union pattern via the type field, allowing TypeScript to exhaustively check message handlers.

In packages/agent/src/types.ts, this interface includes a mandatory type discriminator and an optional payload property that carries domain-specific data.

AgentEvent

AgentEvent defines the event taxonomy emitted by the daemon during session lifecycle changes. Events such as sessionStarted, modelResponse, and error implement this interface, enabling the TUI and VS Code extension to react to state transitions predictably.

SessionState

SessionState describes the serializable persistence layer for interactive sessions. Defined in packages/agent/src/types.ts, it captures conversation history, active model identifiers, and environment variable snapshots. The daemon rehydrates this state on startup to restore user context.

AI Provider Contracts

The packages/ai/src/types.ts file contains the contracts that normalize interactions with large language model providers, abstracting vendor-specific APIs into a unified interface.

ModelRequest

ModelRequest structures the payload sent to AI providers. It includes:

  • model: The identifier string (e.g., "gpt-4o")
  • messages: An array of role-based conversation turns
  • stream: Boolean flag enabling SSE responses
  • Optional tool-call specifications

ModelResponse

ModelResponse standardizes provider outputs across different vendors. It carries generated text content, token usage statistics, tool invocation results, and a stop boolean indicating completion status.

ToolCall and ToolResult

ToolCall represents a single function invocation generated by the model, containing:

  • id: Unique invocation identifier
  • name: Tool identifier (e.g., "fs.readFile")
  • args: JSON-serialized arguments

ToolResult completes the round-trip, returning the execution outcome to the model with the corresponding toolCallId, success status, and serialized output.

Authentication Contracts

LoginCredentials

LoginCredentials in packages/ai/src/env-api-keys.ts standardizes provider authentication shapes. This interface maps environment variables—API keys, OAuth tokens, or AWS Bedrock credentials—into a uniform structure consumed by the credential detection logic.

Implementation Examples

The following patterns demonstrate how these contracts facilitate type-safe communication across Prime Agent components.

Sending Model Requests from the Daemon

import { ModelRequest, AgentMessage } from '@prime-agent/agent';

// Construct a streaming completion request
const request: ModelRequest = {
  model: 'gpt-4o',
  messages: [{ role: 'user', content: 'Explain quantum tunneling.' }],
  stream: true,
};

// Wrap in the generic AgentMessage contract
const msg: AgentMessage = {
  type: 'modelRequest',
  payload: request,
};

daemonChannel.send(msg);

Handling Streaming Responses in the TUI

import { AgentEvent, ModelResponse } from '@prime-agent/agent';

daemonChannel.on('data', (event: AgentEvent) => {
  if (event.type !== 'modelResponse') return;

  const resp = event.payload as ModelResponse;
  if (resp.text) ui.appendToOutput(resp.text);
  if (resp.stop) ui.finishStreaming();
});

Dispatching Tool Calls from the Coding Agent

import { ToolCall, AgentMessage } from '@prime-agent/agent';

function requestFileRead(path: string) {
  const toolCall: ToolCall = {
    id: crypto.randomUUID(),
    name: 'fs.readFile',
    args: JSON.stringify({ path, encoding: 'utf-8' })
  };

  const msg: AgentMessage = {
    type: 'toolCall',
    payload: toolCall,
  };
  daemonChannel.send(msg);
}

Summary

  • AgentMessage and AgentEvent in packages/agent/src/types.ts form the RPC boundary between the daemon and clients, using discriminated unions for exhaustive type checking.
  • ModelRequest and ModelResponse in packages/ai/src/types.ts normalize AI provider interactions, supporting streaming and tool-call workflows.
  • ToolCall and ToolResult enable the coding-agent to execute filesystem and shell operations while maintaining type safety.
  • SessionState provides durable persistence for conversation context across daemon restarts.
  • LoginCredentials abstracts authentication mechanisms across multiple AI providers.

Frequently Asked Questions

Where are the contracts package interfaces defined in the Prime Agent repository?

The interfaces are distributed across the monorepo's package structure rather than a single folder named "contracts." Core communication types reside in packages/agent/src/types.ts, AI provider contracts live in packages/ai/src/types.ts, and authentication shapes are defined in packages/ai/src/env-api-keys.ts.

How does AgentMessage enable type-safe communication?

The AgentMessage interface employs a discriminated union pattern through its mandatory type field. This design forces TypeScript to validate that all possible message types are handled in switch statements, preventing runtime errors when new event types are introduced to the protocol.

What is the purpose of the ToolCall and ToolResult interfaces?

These interfaces standardize the request-response cycle for AI-generated function invocations. ToolCall captures the model's intent to execute a specific tool with arguments, while ToolResult packages the execution output—including success status and serialized data—back to the model for continued reasoning.

Why does the contracts package avoid optional any fields?

The interfaces deliberately use strict typing and discriminated unions instead of any types to maximize compile-time safety. This approach ensures that consumers cannot silently ignore payload properties, and the TypeScript compiler enforces exhaustive handling of all contract variants during development.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →