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
Maintainers
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 shimsAfter (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 buildProtobuf Generation Process
The library uses a modern protobuf-ts toolchain with cross-platform support:
- Input:
rootproto/proto/companion.proto- The protobuf schema - Generator:
@protobuf-ts/plugin- Modern TypeScript generator - Output:
src/proto/src/proto/companion_pb.ts- Clean TypeScript interfaces - 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.cmdbatch script - Linux/macOS: Uses
generate_proto.shshell script - Cross-platform:
npm run generate-protoautomatically 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.protoKey Generation Options
long_type_string: Use strings for 64-bit integers (browser compatibility)optimize_code_size: Generate smaller, reflection-based codeadd_pb_suffix: Add_pbsuffix 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 dependenciesAfter (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 TypeScriptKey Changes
- Import paths: Changed from proto files to named exports
- API style: Callback-based → Promise/async-await based
- Message creation: Protobuf constructors → Plain TypeScript objects
- 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:
- Run
npm run generate-prototo regenerate with protobuf-ts - Update your import statements to use the new API
- 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.contentinstead ofmessage.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:
- Ensure you're using the modern import paths
- Check that old generated files aren't being imported
- 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
- Fork the repository
- Create a feature branch
- Make changes to the protobuf schema or client code
- Run
npm run generate-prototo regenerate types - Test with
npm run compile - Submit a pull request
📄 License
MIT License - see LICENSE file for details.
Priority Software - Modern AI-Powered Business Solutions 🚀
