@okibi/a1kit
v0.1.5
Published
SDK for building agentic workflows with Okibi
Readme
Okibi SDK
A TypeScript SDK for building AI agents with Okibi.
Installation
npm install @okibi/sdkQuick Start
import { OkibiSDK } from '@okibi/sdk';
// Initialize the SDK
const okibi = new OkibiSDK({
apiKey: 'your-api-key',
modelApiKey: 'your-model-api-key',
researcherApiKey: 'your-researcher-api-key' // optional
});
// Create an agent
const agent = await okibi.createAgent({
name: 'Data Processor',
description: 'Processes and analyzes data',
parameters: {
maxProcessingTime: 30000,
batchSize: 100
}
});
// Create a workflow
const workflow = await okibi.createWorkflow({
name: 'Data Analysis Pipeline',
description: 'Process and analyze data in multiple steps',
steps: [
{
id: 'step1',
agentId: agent.id,
input: { data: 'raw-data' },
status: 'pending'
}
],
status: 'draft'
});
// Execute the workflow
await okibi.executeWorkflow(workflow.id);
// Check workflow status
const status = await okibi.getWorkflowStatus(workflow.id);Tool Definitions with Zod
The SDK uses Zod schemas for tool definitions, providing type safety and automatic JSON schema generation.
import { OkibiSDK, z } from '@okibi/sdk';
// Define tools using Zod schemas
const tools = [
{
name: 'calculator',
description: 'Perform mathematical calculations',
parameters: z.object({
expression: z.string().describe('The mathematical expression to evaluate'),
precision: z.number().optional().default(2).describe('Number of decimal places')
}),
handler: async (params) => {
const { expression, precision = 2 } = params;
const result = eval(expression); // Use a proper math library in production
return {
type: 'success',
output: `Result: ${result.toFixed(precision)}`
};
}
}
];
// Create agent with tools
const agent = await okibi.createSimpleAgent(
'Math Assistant',
'An agent that can perform calculations',
{ tools }
);
// Execute the agent
const result = await agent.execute('Calculate 15 * 7 + 23');
console.log(result.response);OAuth Credentials Management
The SDK provides OAuth credential management for integrating with external services. This is particularly useful for agents that need to access third-party APIs.
Environment Variables
REQUIRED: You must set the OKIBI_AGENT_SIGNATURE environment variable to identify your application instance:
export OKIBI_AGENT_SIGNATURE="your-signed-agent-signature"This cryptographically signed agent signature, combined with the integration name, creates a unique identifier for your OAuth credentials.
Saving OAuth Credentials
const okibi = new OkibiSDK({
apiKey: 'your-api-key',
modelApiKey: 'your-model-api-key'
});
// Save OAuth credentials for a service
await okibi.saveOAuthCredential({
agentSignature: process.env.OKIBI_AGENT_SIGNATURE, // Cryptographically signed agent identifier (only in Okibi containers)
integrationName: 'google-drive',
clientId: 'your-google-client-id',
clientSecret: 'your-google-client-secret',
accessToken: 'initial-access-token',
refreshToken: 'refresh-token',
refreshUrl: 'https://oauth2.googleapis.com/token',
expiresAt: new Date(Date.now() + 3600 * 1000) // 1 hour from now
});Retrieving OAuth Credentials
The runtime automatically handles token refresh when retrieving credentials:
// Get OAuth credentials (runtime automatically refreshes if expired)
const credentials = await okibi.getOAuthCredential(
process.env.OKIBI_AGENT_SIGNATURE!,
'google-drive'
);
// Use the access token in your API calls
const response = await fetch('https://www.googleapis.com/drive/v3/files', {
headers: {
'Authorization': `Bearer ${credentials.accessToken}`
}
});Research Functionality
The SDK provides comprehensive research capabilities. You can perform deep research tasks asynchronously or get immediate research responses.
Note: Research functionality requires a researcherApiKey to be configured in the SDK constructor. This API key is used for all research operations and cannot be overridden on individual method calls.
Creating Research Tasks
Research tasks run asynchronously and can be configured with custom output schemas:
const okibi = new OkibiSDK({
apiKey: 'your-api-key',
modelApiKey: 'your-model-api-key'
});
// Create a research task
const task = await okibi.createResearchTask({
instructions: "Research the latest developments in AI safety, focusing on recent papers and industry initiatives",
model: "researcher-ultra",
outputSchema: {
inferSchema: true,
schema: {
type: "object",
properties: {
developments: {
type: "array",
items: {
type: "object",
properties: {
title: { type: "string" },
description: { type: "string" },
source: { type: "string" },
date: { type: "string" }
}
}
},
summary: { type: "string" }
}
}
}
});
console.log('Task created:', task.taskId);Polling for Research Results
You can check the status of a research task without waiting:
// Check task status (non-blocking)
const status = await okibi.getResearchTaskStatus(task.taskId);
if (status.status === 'completed') {
console.log('Research completed!');
console.log('Results:', status.result);
} else if (status.status === 'failed') {
console.log('Research failed:', status.error);
} else {
console.log('Task still running...');
}Waiting for Research Completion
For a blocking approach, you can wait for the task to complete:
// Wait for task completion (blocking)
const result = await okibi.waitForResearchTask(task.taskId);
console.log('Research completed!');
console.log('Status:', result.status);
console.log('Results:', result.result);Immediate Research Chat
For immediate research responses, use the chat interface:
// Immediate research using chat interface
const response = await okibi.researchChat({
instructions: "Research the current state of quantum computing, focusing on recent breakthroughs and commercial applications with detailed citations",
model: "deep-researcher-mini"
});
console.log('Research response:');
console.log(response.response);Research with Jeff Bezos Example
// Create a research task about Jeff Bezos
const task = await okibi.createResearchTask({
instructions: "find out everything you can about Jezz Bezos",
model: "researcher-ultra",
outputSchema: {
inferSchema: true
}
});
// Wait for completion
const result = await okibi.waitForResearchTask(task.taskId);
console.log('Research results:', result.result);Multiple Research Tasks
You can run multiple research tasks in parallel:
// Create multiple research tasks
const tasks = await Promise.all([
okibi.createResearchTask({
instructions: "Research the latest trends in renewable energy technology",
model: "researcher-ultra",
outputSchema: { inferSchema: true }
}),
okibi.createResearchTask({
instructions: "Research the impact of AI on healthcare industry with comprehensive analysis",
model: "deep-researcher-mini",
outputSchema: { inferSchema: true }
})
]);
// Wait for all tasks to complete
const results = await Promise.all(
tasks.map(task => okibi.waitForResearchTask(task.taskId))
);
console.log('All research tasks completed!');Research Models
deep-researcher- OpenAI deep research model with web search and citations (recommended for detailed analysis)deep-researcher-mini- OpenAI mini deep research model with web search and citations (faster, cost-effective)researcher-ultra- High-quality Exa research modelresearcher- Standard Exa research model
Research Task Status
Research tasks can have the following statuses:
pending- Task is queuedprocessing- Task is being processedcompleted- Task finished successfullyfailed- Task failed with an error
File Creation System
The SDK includes a built-in file creation tool that allows agents to create files during execution. Files are automatically included in the response and displayed in the web app interface.
How It Works
- Agent Execution: When an agent executes with the
fileCreationTool, it can create files using natural language - Storage: Files are temporarily stored in the database with the execution ID
- Retrieval: Files are automatically fetched and included in the execution response
- Cleanup: Files are deleted from the database after being fetched (one-time access)
Example Usage
// Create agent with file creation capability
const agent = await okibi.createSimpleAgent(
"File Creator",
"Creates files based on user requests",
{
tools: [okibi.fileCreationTool] // Built-in file creation tool
}
);
const result = await agent.execute(
"Create a simple HTML page with CSS styling"
);
// Files are automatically included in the response
result.files.forEach(file => {
console.log(`Created: ${file.filename}`);
console.log(`Content: ${file.content}`);
});Supported File Types
The system supports all text-based file types with automatic type detection:
- Web: HTML, CSS, JavaScript, TypeScript
- Programming: Python, Java, C++, C#, Ruby, Go, Rust, etc.
- Data: JSON, XML, YAML, SQL
- Documentation: Markdown, Plain Text
- Configuration: Dockerfile, Shell scripts
AgentServer
The AgentServer class provides a unified way to expose your agent over HTTP and WebSocket on the same port:
import { AgentServer, ConsoleLogger } from '@okibi/a1kit/server'
const server = new AgentServer(agent, {
port: 3000,
logger: new ConsoleLogger()
})
await server.start()This creates a unified HTTP server that handles both HTTP requests and WebSocket connections on the same port:
GET /health- Health check endpointPOST /execute- Execute a query with the agent- Request body:
{ query: string, executionId?: string } - Response:
{ response: string, executionId: string }
- Request body:
WebSocket Support
WebSocket support is always available and the same server accepts WebSocket connections for real-time communication:
Client sends:
{
"type": "execute",
"query": "Your message here",
"executionId": "optional-execution-id"
}Server responds:
{
"type": "execution_response",
"response": "Agent's response",
"executionId": "execution-id",
"files": [
{
"id": "file-id",
"filename": "example.txt",
"content": "file content",
"mimeType": "text/plain"
}
],
"output": {
"content": "accumulated output content"
}
}Error responses:
{
"type": "error",
"message": "Error description"
}Unified Server Architecture
The AgentServer uses a unified architecture where:
- A single HTTP server handles both HTTP requests and WebSocket connections
- Both protocols share the same port and logging infrastructure
- Both use the same
AgentClient.execute()method internally for identical functionality
WebSocket vs HTTP
Both approaches provide identical functionality and behavior:
- HTTP: Traditional request-response pattern, great for simple integrations
- WebSocket: Real-time bidirectional communication, better for interactive applications
Choose WebSocket when you need:
- Real-time communication
- Lower latency for frequent requests
- Connection persistence
- Event-driven interactions
Choose HTTP when you need:
- Simple request-response patterns
- REST API compatibility
- Easier debugging and testing
- Standard HTTP tooling support
API Reference
OkibiSDK
The main class for interacting with the Okibi API.
Constructor
constructor(config: {
apiKey: string;
baseUrl?: string;
modelApiKey: string;
researcherApiKey?: string;
})Methods
createAgent(config: AgentConfig): Promise<Agent>getAgent(id: string): Promise<Agent>createSimpleAgent(name: string, description: string, options?: AgentOptions): Promise<Agent>createWorkflow(workflow: Omit<Workflow, 'id' | 'createdAt' | 'updatedAt'>): Promise<Workflow>executeWorkflow(id: string): Promise<void>getWorkflowStatus(id: string): Promise<WorkflowStatus>saveOAuthCredential(credential: OAuthCredentialInput): Promise<Omit<OAuthCredential, 'clientSecret'>>getOAuthCredential(agentSignature: string, integrationName: string): Promise<Omit<OAuthCredential, 'clientSecret'>>createResearchTask(config: ResearchTaskConfig): Promise<ResearchTask>getResearchTaskStatus(taskId: string): Promise<ResearchTask>waitForResearchTask(taskId: string): Promise<ResearchTask>researchChat(config: ResearchChatConfig): Promise<ResearchChatResponse>
Properties
fileCreationTool: Built-in tool that enables file creation capabilities for agents
Types
AgentConfig
interface AgentConfig {
name: string;
description: string;
parameters?: Record<string, unknown>;
}AgentOptions
interface AgentOptions {
tools?: ToolWithHandler[];
}Agent
interface Agent {
id: string;
execute(message: string): Promise<AgentExecutionResult>;
}AgentExecutionResult
interface AgentExecutionResult {
response: string; // Agent's text response
executionId: string; // Unique execution identifier
files: CreatedFile[]; // Array of created files
}CreatedFile
interface CreatedFile {
id: string; // Unique file identifier
filename: string; // File name with extension
content: string; // File content as plain text
createdAt: string; // ISO timestamp
executionId: string; // Associated execution ID
}Workflow
interface Workflow {
id: string;
name: string;
description: string;
steps: WorkflowStep[];
status: 'draft' | 'active' | 'archived';
createdAt: Date;
updatedAt: Date;
}WorkflowStep
interface WorkflowStep {
id: string;
agentId: string;
input: Record<string, unknown>;
output?: Record<string, unknown>;
status: 'pending' | 'running' | 'completed' | 'failed';
error?: string;
}OAuthCredentialInput
interface OAuthCredentialInput {
agentSignature: string; // Cryptographically signed agent identifier
integrationName: string;
clientId: string;
clientSecret: string;
accessToken: string;
refreshToken?: string;
refreshUrl: string;
expiresAt?: Date;
}OAuthCredential
interface OAuthCredential {
id: string;
agentSignature: string; // Cryptographically signed agent identifier
integrationName: string;
clientId: string;
accessToken: string;
refreshToken?: string;
refreshUrl: string;
expiresAt?: Date;
createdAt: Date;
updatedAt: Date;
}ResearchTaskConfig
interface ResearchTaskConfig {
instructions: string;
model?: 'researcher-ultra' | 'researcher' | 'deep-researcher' | 'deep-researcher-mini';
outputSchema?: {
inferSchema: boolean;
schema?: Record<string, unknown>;
};
}ResearchChatConfig
interface ResearchChatConfig {
instructions: string;
model?: 'researcher-ultra' | 'researcher' | 'deep-researcher' | 'deep-researcher-mini';
stream?: boolean;
}ResearchTask
interface ResearchTask {
taskId: string;
status: 'pending' | 'processing' | 'completed' | 'failed';
result?: string;
error?: string;
progress?: number;
outputItems?: Array<{
type: 'web_search_call' | 'message';
[key: string]: any;
}>;
annotations?: Array<{
url: string;
title: string;
start_index: number;
end_index: number;
}>;
}ResearchChatResponse
interface ResearchChatResponse {
response: string;
outputItems?: Array<{
type: 'web_search_call' | 'message';
[key: string]: any;
}>;
annotations?: Array<{
url: string;
title: string;
start_index: number;
end_index: number;
}>;
}Development
# Install dependencies
npm install
# Build the SDK
npm run build
# Run tests
npm test
# Lint the code
npm run lintLicense
MIT
