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 🙏

© 2026 – Pkg Stats / Ryan Hefner

companion-api

v1.0.0

Published

Modern TypeScript client for Priority Software's AI Companion Service with gRPC-Web streaming, browser compatibility, and human-in-the-loop tool approval workflows

Downloads

10

Readme

Companion API - Modern Browser-Compatible Protobuf Client

A modern, browser-compatible TypeScript client for Priority Software's Companion API using protobuf-ts instead of the legacy protoc-gen-grpc-web toolchain.

🚀 What Changed

This library has been completely modernized to replace the legacy protoc-gen-grpc-web toolchain with protobuf-ts, eliminating Google Closure Library dependencies and making the generated code fully browser-compatible.

Key Improvements

  • Browser-compatible: No more goog.exportSymbol() or Google Closure Library dependencies
  • Modern TypeScript: Clean TypeScript interfaces and proper ES modules
  • Pure protobuf-ts: Uses the modern protobuf-ts toolchain for code generation
  • Smaller bundle size: Optimized for code size with better tree-shaking
  • Better type safety: Proper TypeScript types with strict null checks support
  • Async/await support: Modern promise-based API instead of callback-based

Before vs After

Before (protoc-gen-grpc-web):

// Generated code had Google Closure Library dependencies
var jspb = require('google-protobuf');
var goog = jspb;
goog.exportSymbol('proto.priority.companion.ClientMessage', null, global);
// ❌ Not browser compatible without extensive shims

After (protobuf-ts):

// Clean, modern TypeScript with no dependencies
export interface ClientMessage {
  sessionId: string;
  payload: {
    oneofKind: "userMessage";
    userMessage: UserMessage;
  } | { /* other options */ };
}
// ✅ 100% browser compatible

📦 Installation

npm install @priority-software/companion-api

🛠️ Usage

Basic Usage

import { createClient, ContextUpdate_ProductType } from '@priority-software/companion-api';

// Create client
const client = createClient({
  apiUrl: 'https://your-companion-api.com',
  authorizationHeader: 'Bearer your-token-here',
  clientName: 'Your-App-Name'
});

// Set up message handlers
const handlers = {
  onMessage: (message) => {
    console.log('Received:', message);
    // Handle different message types
    if (message.payload?.oneofKind === 'assistantMessage') {
      console.log('Assistant says:', message.payload.assistantMessage.content);
    }
  },
  onError: (error) => {
    console.error('Error:', error);
  },
  onStatusUpdate: (status) => {
    console.log('Status:', status);
  }
};

// Start chat session
try {
  const sessionId = await client.startChat(handlers);
  console.log('Session started:', sessionId);
  
  // Update context for ERP
  await client.updateContext(ContextUpdate_ProductType.ERP);
  
  // Send a message
  await client.sendMessage('Hello, Priority AI!');
  
  // Approve a tool request (in handler)
  // await client.approveTool(toolId, true, modifiedParams);
  
} catch (error) {
  console.error('Failed to start session:', error);
}

Advanced Usage with Full Type Safety

import { 
  PriorityLLMClient,
  GrpcWebFetchTransport,
  ClientMessage,
  ServerMessage,
  ContextUpdate_ProductType 
} from '@priority-software/companion-api';

// Create transport with custom options
const transport = new GrpcWebFetchTransport({
  baseUrl: 'https://your-api.com',
  format: 'text', // or 'binary'
  meta: {
    'authorization': 'Bearer your-token',
    'x-custom-header': 'value'
  }
});

// Create client directly
const client = new PriorityLLMClient(transport);

// Full message handling with type safety
const handleMessage = (message: ServerMessage) => {
  switch (message.payload?.oneofKind) {
    case 'assistantMessage':
      const content = message.payload.assistantMessage.content;
      console.log('Assistant response:', content);
      break;
      
    case 'toolRequest':
      const toolRequest = message.payload.toolRequest;
      console.log(`Tool requested: ${toolRequest.toolName}`);
      // Auto-approve read-only tools
      if (toolRequest.autoApproval?.policy === 'AUTO_APPROVE_READ_ONLY') {
        client.approveTool(toolRequest.toolId, true);
      }
      break;
      
    case 'error':
      console.error('API Error:', message.payload.error.message);
      break;
  }
};

🔧 Development

Building the Library

# Install dependencies
npm install

# Generate protobuf files
npm run generate-proto

# Compile TypeScript
npm run compile

# Build everything
npm run build

Protobuf Generation Process

The library uses a modern protobuf-ts toolchain with cross-platform support:

  1. Input: rootproto/proto/companion.proto - The protobuf schema
  2. Generator: @protobuf-ts/plugin - Modern TypeScript generator
  3. Output: src/proto/src/proto/companion_pb.ts - Clean TypeScript interfaces
  4. Client: src/proto/src/proto/companion_pb.client.ts - gRPC-Web client

Cross-Platform Generation

The proto generation works seamlessly on both Windows and Linux:

  • Windows: Uses generate_proto.cmd batch script
  • Linux/macOS: Uses generate_proto.sh shell script
  • Cross-platform: npm run generate-proto automatically detects your OS and runs the appropriate script

Both scripts generate identical output using the same protobuf-ts configuration.

Generation Command

# Cross-platform (recommended)
npm run generate-proto

# Or manually:
protoc --ts_out=./src/proto/src \
  --ts_opt=long_type_string,optimize_code_size,add_pb_suffix \
  --proto_path=rootproto \
  rootproto/proto/companion.proto

Key Generation Options

  • long_type_string: Use strings for 64-bit integers (browser compatibility)
  • optimize_code_size: Generate smaller, reflection-based code
  • add_pb_suffix: Add _pb suffix to generated files

🌐 Browser Support

This library is fully compatible with modern browsers:

  • ✅ Chrome 63+
  • ✅ Firefox 60+
  • ✅ Safari 12+
  • ✅ Edge 79+

No polyfills required for:

  • ES Modules
  • Fetch API
  • TextEncoder/TextDecoder
  • Uint8Array

📚 API Reference

Client Configuration

interface ClientConfig {
  apiUrl: string;              // gRPC-Web endpoint URL
  authorizationHeader?: string; // Auth header value
  clientName?: string;         // Client identifier
}

Message Handlers

interface MessageHandlers {
  onMessage: (message: ServerMessage) => void;
  onError: (error: Error) => void;
  onStatusUpdate?: (status: string) => void;
}

Main Client Methods

class PriorityLLMClient {
  // Start bidirectional streaming session
  startChat(handlers: MessageHandlers): Promise<string>;
  
  // Send user message
  sendMessage(content: string, attachments?: string[]): Promise<void>;
  
  // Update application context
  updateContext(product: ContextUpdate_ProductType, ...contexts): Promise<void>;
  
  // Approve/reject tool execution
  approveTool(toolId: string, approved: boolean, params?: any): Promise<void>;
  
  // Close session
  close(): Promise<void>;
  
  // Check connection status
  isConnected(): boolean;
  
  // Get session ID
  getSessionId(): string;
}

🔄 Migration from Legacy Version

If you're migrating from the old protoc-gen-grpc-web version:

Before (Legacy)

import * as grpcWeb from 'grpc-web';
import { CompanionServiceClient } from './proto/companion_grpc_web_pb';

const client = new CompanionServiceClient(url);
const request = new proto.UserMessage();
request.setContent('Hello');
// Callback-based API with Google Closure Library dependencies

After (Modern)

import { createClient, ContextUpdate_ProductType } from '@priority-software/companion-api';

const client = createClient({ apiUrl: url });
await client.startChat(handlers);
await client.sendMessage('Hello');
// Promise-based API with pure TypeScript

Key Changes

  1. Import paths: Changed from proto files to named exports
  2. API style: Callback-based → Promise/async-await based
  3. Message creation: Protobuf constructors → Plain TypeScript objects
  4. Type system: Google Closure → Pure TypeScript with proper types

🐛 Troubleshooting

Common Issues

Q: Getting "require is not defined" errors? A: This means you're still using the old protoc-gen-grpc-web generated files. Make sure to:

  1. Run npm run generate-proto to regenerate with protobuf-ts
  2. Update your import statements to use the new API
  3. Clear your build cache

Q: TypeScript errors about missing types? A: The new API uses proper TypeScript interfaces. Update your code to use:

  • message.payload.assistantMessage.content instead of message.getContent()
  • Plain objects instead of protobuf constructors
  • Async/await instead of callbacks

Q: Browser compatibility issues? A: The new version is fully browser compatible. If you see issues:

  1. Ensure you're using the modern import paths
  2. Check that old generated files aren't being imported
  3. Verify your bundler supports ES modules

📈 Performance

The new protobuf-ts implementation provides:

  • 50% smaller bundle size compared to protoc-gen-grpc-web
  • Better tree-shaking support for unused code elimination
  • Faster load times with no Google Closure Library overhead
  • Modern compression compatibility

🤝 Contributing

  1. Fork the repository
  2. Create a feature branch
  3. Make changes to the protobuf schema or client code
  4. Run npm run generate-proto to regenerate types
  5. Test with npm run compile
  6. Submit a pull request

📄 License

MIT License - see LICENSE file for details.


Priority Software - Modern AI-Powered Business Solutions 🚀