npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2025 – Pkg Stats / Ryan Hefner

@kadi.build/core

v0.0.1-alpha.15

Published

A module that is a comprehensive toolkit for developers integrating with the KADI infrastructure.

Downloads

81

Readme

@kadi.build/core

Framework for building distributed abilities with multiple transport protocols

npm version License: MIT

Installation

npm install @kadi.build/core

Quick Start

Creating an Ability

import { KadiClient, z } from '@kadi.build/core';

const ability = new KadiClient({
  name: 'math-ability',
  version: '1.0.0'
});

// Register tool with Zod schemas (recommended)
ability.registerTool({
  name: 'add',
  description: 'Add two numbers',
  input: z.object({
    a: z.number().describe('First number'),
    b: z.number().describe('Second number')
  }),
  output: z.object({
    result: z.number().describe('Sum of a and b')
  })
}, async ({ a, b }) => {
  return { result: a + b };
});

// Start serving (native, stdio, or broker)
await ability.serve('stdio');

Loading and Using Abilities

import { loadAbility } from '@kadi.build/core';

const math = await loadAbility('math-ability', 'stdio');
const result = await math.add({ a: 5, b: 3 });
console.log(result); // { result: 8 }

Tool Registration (Three Ways)

1. With Zod Schemas (Recommended)

Zod provides type-safe schemas with 70% less code than JSON Schema:

import { KadiClient, z } from '@kadi.build/core';

const ability = new KadiClient({ name: 'example' });

ability.registerTool({
  name: 'processData',
  description: 'Process user data',
  version: '1.0.0',
  input: z.object({
    name: z.string().min(1).describe('User name'),
    age: z.number().int().positive().optional().describe('User age'),
    tags: z.array(z.string()).describe('User tags')
  }),
  output: z.object({
    processed: z.boolean(),
    data: z.record(z.unknown())
  })
}, async (params) => {
  // Automatic validation of inputs and outputs
  return {
    processed: true,
    data: params
  };
});

2. With createTool() Helper

For advanced use cases with runtime validation:

import { createTool, z } from '@kadi.build/core';

const { definition, handler } = createTool({
  name: 'convert',
  description: 'Convert units',
  input: z.object({
    value: z.number(),
    from: z.enum(['km', 'miles']),
    to: z.enum(['km', 'miles'])
  }),
  output: z.object({
    result: z.number(),
    unit: z.string()
  }),
  handler: async ({ value, from, to }) => {
    // Your logic here
    return { result: value * 1.6, unit: to };
  }
});

ability.registerTool(definition, handler);

3. With JSON Schema (Backward Compatible)

Traditional approach still supported:

ability.registerTool({
  name: 'greet',
  description: 'Greet someone',
  inputSchema: {
    type: 'object',
    properties: {
      name: { type: 'string', description: 'Name to greet' }
    },
    required: ['name']
  },
  outputSchema: {
    type: 'object',
    properties: {
      greeting: { type: 'string' }
    }
  }
}, async ({ name }) => {
  return { greeting: `Hello, ${name}!` };
});

Migration from JSON Schema to Zod

Before (JSON Schema):

// 64 lines of boilerplate
ability.registerTool({
  name: 'deployToAkash',
  description: 'Deploy to Akash Network',
  inputSchema: {
    type: 'object',
    properties: {
      profile: {
        type: 'string',
        description: 'Deployment profile name'
      },
      dryRun: {
        type: 'boolean',
        description: 'Preview without deploying',
        default: false
      },
      verbose: {
        type: 'boolean',
        description: 'Enable verbose output',
        default: false
      }
    },
    required: ['profile']
  },
  outputSchema: {
    type: 'object',
    properties: {
      success: { type: 'boolean' },
      dseq: { type: 'string' },
      services: {
        type: 'array',
        items: { type: 'string' }
      }
    }
  }
}, handler);

After (Zod):

// 15 lines - clean and type-safe!
ability.registerTool({
  name: 'deployToAkash',
  description: 'Deploy to Akash Network',
  input: z.object({
    profile: z.string().describe('Deployment profile name'),
    dryRun: z.boolean().default(false).describe('Preview without deploying'),
    verbose: z.boolean().default(false).describe('Enable verbose output')
  }),
  output: z.object({
    success: z.boolean(),
    dseq: z.string(),
    services: z.array(z.string())
  })
}, handler);

Result: 77% less code!

Transport Protocols

KADI supports three transport protocols for different use cases:

Native (In-Process)

const ability = await loadAbility('my-ability', 'native');
// Direct function calls, zero IPC overhead

Stdio (Child Process)

const ability = await loadAbility('my-ability', 'stdio');
// JSON-RPC over stdin/stdout, language-agnostic

Broker (Distributed)

const ability = await loadAbility('my-ability', 'broker', {
  brokerUrl: 'ws://localhost:8080',
  networks: ['global']
});
// WebSocket-based distributed communication

Events

Publish and subscribe to events across all protocols:

// Publishing events
ability.registerTool({
  name: 'process',
  input: z.object({ data: z.string() }),
  output: z.object({ result: z.string() })
}, async (params) => {
  // Publish progress events
  await ability.publishEvent('process.started', { data: params.data });

  const result = await doWork(params.data);

  await ability.publishEvent('process.completed', { result });
  return { result };
});

// Subscribing to events
ability.subscribeToEvent('process.*', (data) => {
  console.log('Process event:', data);
});

Broker Mode

Connect to KADI broker for distributed communication:

const client = new KadiClient({
  name: 'my-agent',
  role: 'agent',
  brokers: {
    dev: 'ws://localhost:8080',
    prod: 'ws://prod.example.com:8080'
  },
  defaultBroker: 'dev',
  networks: ['global']
});

// Register tools
client.registerTool({
  name: 'greet',
  input: z.object({ name: z.string() }),
  output: z.object({ greeting: z.string() })
}, async ({ name }) => {
  return { greeting: `Hello, ${name}!` };
});

// Connect to broker
await client.serve('broker');

// Call remote tools
const result = await client.callTool('translator', 'translate', {
  text: 'Hello',
  to: 'es'
});

API Reference

KadiClient

Main class for all KADI operations:

const client = new KadiClient({
  name: 'my-ability',
  version: '1.0.0',
  role: 'ability',  // 'agent' or 'ability'
  brokers: { /* broker configs */ },
  defaultBroker: 'dev',
  networks: ['global']
});

Methods:

  • registerTool(definition, handler) - Register a tool
  • serve(mode) - Start serving ('native', 'stdio', 'broker')
  • callTool(agent, tool, params) - Call remote tool
  • publishEvent(name, data) - Publish event
  • subscribeToEvent(pattern, callback) - Subscribe to events
  • loadAbility(name, protocol, options) - Load another ability

loadAbility

Load an ability by name and protocol:

const ability = await loadAbility('ability-name', 'protocol', {
  brokerUrl: 'ws://localhost:8080',
  networks: ['global']
});

createTool

Helper for creating tools with validation:

import { createTool, z } from '@kadi.build/core';

const { definition, handler } = createTool({
  name: 'toolName',
  input: z.object({ /* ... */ }),
  output: z.object({ /* ... */ }),
  handler: async (params) => { /* ... */ }
});

Common Patterns

Error Handling

ability.registerTool({
  name: 'riskyOperation',
  input: z.object({ data: z.string() }),
  output: z.object({
    success: z.boolean(),
    result: z.string().optional(),
    error: z.string().optional()
  })
}, async (params) => {
  try {
    const result = await performOperation(params.data);
    return { success: true, result };
  } catch (error) {
    await ability.publishEvent('operation.error', {
      error: error.message,
      params
    });
    return { success: false, error: error.message };
  }
});

Health Check

ability.registerTool({
  name: 'health',
  input: z.object({}),
  output: z.object({
    status: z.string(),
    uptime: z.number(),
    memory: z.record(z.number())
  })
}, async () => {
  return {
    status: 'healthy',
    uptime: process.uptime(),
    memory: process.memoryUsage()
  };
});

Environment Variables

# Protocol selection
KADI_PROTOCOL=stdio

# Broker configuration
KADI_BROKER_URL=ws://localhost:8080
KADI_AGENT_SCOPE=project-123

Debug Mode

DEBUG=kadi:* node index.js

Troubleshooting

Broker Connection Failures

  • Verify broker URL is correct
  • Check network connectivity
  • Ensure broker is running

Events Not Arriving

  • Subscribe BEFORE triggering events
  • Verify pattern matching
  • Check that publisher and subscriber are on same network

Type Errors with Zod

  • Ensure Zod schemas match handler types
  • Use z.infer<typeof schema> for TypeScript types
  • Check that all required fields are provided

License

MIT

Related Projects


Built with ❤️ by the KADI team