# gRPC Client Guide This guide explains how to connect to and interact with the Apple Intelligence gRPC server from various programming languages. ## Server Information - **Default Host:** `0.0.0.0` (all interfaces) - **Default Port:** `50051` - **Protocol:** gRPC over HTTP/2 (plaintext) - **Service:** `appleintelligence.AppleIntelligence` ## Available Methods | Method | Type | Description | |--------|------|-------------| | `Health` | Unary | Check server and model status | | `Complete` | Unary | Generate a complete response | | `StreamComplete` | Server Streaming | Generate response with streaming tokens | ## Proto Definition ```protobuf syntax = "proto3"; package appleintelligence; service AppleIntelligence { rpc Health(HealthRequest) returns (HealthResponse); rpc Complete(CompletionRequest) returns (CompletionResponse); rpc StreamComplete(CompletionRequest) returns (stream CompletionChunk); } message HealthRequest {} message HealthResponse { bool healthy = 1; string model_status = 2; } message CompletionRequest { string prompt = 1; optional float temperature = 2; optional int32 max_tokens = 3; } message CompletionResponse { string id = 1; string text = 2; string finish_reason = 3; } message CompletionChunk { string id = 1; string delta = 2; bool is_final = 3; optional string finish_reason = 4; } ``` ## Testing with grpcurl [grpcurl](https://github.com/fullstorydev/grpcurl) is a command-line tool for interacting with gRPC servers. ### Installation ```bash # macOS brew install grpcurl # Linux go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest ``` ### Health Check ```bash grpcurl -plaintext \ -proto Sources/Protos/apple_intelligence.proto \ localhost:50051 \ appleintelligence.AppleIntelligence/Health ``` Response: ```json { "healthy": true, "modelStatus": "available" } ``` ### Complete (Non-Streaming) ```bash grpcurl -plaintext \ -proto Sources/Protos/apple_intelligence.proto \ -d '{"prompt": "What is 2 + 2?"}' \ localhost:50051 \ appleintelligence.AppleIntelligence/Complete ``` Response: ```json { "id": "abc123", "text": "2 + 2 equals 4.", "finishReason": "stop" } ``` ### StreamComplete (Streaming) ```bash grpcurl -plaintext \ -proto Sources/Protos/apple_intelligence.proto \ -d '{"prompt": "Tell me a short story"}' \ localhost:50051 \ appleintelligence.AppleIntelligence/StreamComplete ``` Response (multiple chunks): ```json {"id": "xyz789", "delta": "Once", "isFinal": false} {"id": "xyz789", "delta": " upon", "isFinal": false} {"id": "xyz789", "delta": " a", "isFinal": false} {"id": "xyz789", "delta": " time", "isFinal": false} ... {"id": "xyz789", "delta": "", "isFinal": true, "finishReason": "stop"} ``` ## Python Client ### Installation ```bash pip install grpcio grpcio-tools ``` ### Generate Python Code from Proto ```bash python -m grpc_tools.protoc \ -I. \ --python_out=. \ --grpc_python_out=. \ Sources/Protos/apple_intelligence.proto ``` ### Basic Client ```python import grpc import apple_intelligence_pb2 as pb import apple_intelligence_pb2_grpc as rpc # Connect to server channel = grpc.insecure_channel('localhost:50051') stub = rpc.AppleIntelligenceStub(channel) # Health check health = stub.Health(pb.HealthRequest()) print(f"Healthy: {health.healthy}") print(f"Model Status: {health.model_status}") # Non-streaming completion response = stub.Complete(pb.CompletionRequest( prompt="What is the capital of France?" )) print(f"Response: {response.text}") # Streaming completion for chunk in stub.StreamComplete(pb.CompletionRequest( prompt="Write a haiku about coding" )): if chunk.delta: print(chunk.delta, end='', flush=True) print() # Newline at end ``` ### Async Client ```python import asyncio import grpc.aio import apple_intelligence_pb2 as pb import apple_intelligence_pb2_grpc as rpc async def main(): async with grpc.aio.insecure_channel('localhost:50051') as channel: stub = rpc.AppleIntelligenceStub(channel) # Streaming with async async for chunk in stub.StreamComplete(pb.CompletionRequest( prompt="Explain quantum computing" )): if chunk.delta: print(chunk.delta, end='', flush=True) print() asyncio.run(main()) ``` ## Node.js / TypeScript Client ### Installation ```bash npm install @grpc/grpc-js @grpc/proto-loader ``` ### Client ```javascript const grpc = require('@grpc/grpc-js'); const protoLoader = require('@grpc/proto-loader'); // Load proto const packageDef = protoLoader.loadSync('Sources/Protos/apple_intelligence.proto'); const proto = grpc.loadPackageDefinition(packageDef).appleintelligence; // Create client const client = new proto.AppleIntelligence( 'localhost:50051', grpc.credentials.createInsecure() ); // Health check client.Health({}, (err, response) => { console.log('Healthy:', response.healthy); console.log('Model Status:', response.modelStatus); }); // Non-streaming completion client.Complete({ prompt: 'Hello, how are you?' }, (err, response) => { console.log('Response:', response.text); }); // Streaming completion const stream = client.StreamComplete({ prompt: 'Tell me a joke' }); stream.on('data', (chunk) => { process.stdout.write(chunk.delta); }); stream.on('end', () => { console.log('\nStream ended'); }); ``` ## Go Client ### Installation ```bash go install google.golang.org/protobuf/cmd/protoc-gen-go@latest go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest ``` ### Generate Go Code ```bash protoc --go_out=. --go-grpc_out=. Sources/Protos/apple_intelligence.proto ``` ### Client ```go package main import ( "context" "fmt" "io" "log" "google.golang.org/grpc" "google.golang.org/grpc/credentials/insecure" pb "your-module/appleintelligence" ) func main() { // Connect conn, err := grpc.Dial("localhost:50051", grpc.WithTransportCredentials(insecure.NewCredentials())) if err != nil { log.Fatal(err) } defer conn.Close() client := pb.NewAppleIntelligenceClient(conn) ctx := context.Background() // Health check health, _ := client.Health(ctx, &pb.HealthRequest{}) fmt.Printf("Healthy: %v\n", health.Healthy) // Streaming stream, _ := client.StreamComplete(ctx, &pb.CompletionRequest{ Prompt: "What is AI?", }) for { chunk, err := stream.Recv() if err == io.EOF { break } fmt.Print(chunk.Delta) } fmt.Println() } ``` ## Swift Client ### Using grpc-swift ```swift import GRPC import NIO let group = MultiThreadedEventLoopGroup(numberOfThreads: 1) defer { try! group.syncShutdownGracefully() } let channel = try GRPCChannelPool.with( target: .host("localhost", port: 50051), transportSecurity: .plaintext, eventLoopGroup: group ) let client = Appleintelligence_AppleIntelligenceAsyncClient(channel: channel) // Health check let health = try await client.health(Appleintelligence_HealthRequest()) print("Healthy: \(health.healthy)") // Streaming for try await chunk in client.streamComplete(Appleintelligence_CompletionRequest.with { $0.prompt = "Hello!" }) { print(chunk.delta, terminator: "") } ``` ## Authentication If the server is configured with an API key, include it in the metadata: ### grpcurl ```bash grpcurl -plaintext \ -H "Authorization: Bearer YOUR_API_KEY" \ -d '{"prompt": "Hello"}' \ localhost:50051 \ appleintelligence.AppleIntelligence/Complete ``` ### Python ```python metadata = [('authorization', 'Bearer YOUR_API_KEY')] response = stub.Complete(request, metadata=metadata) ``` ### Node.js ```javascript const metadata = new grpc.Metadata(); metadata.add('authorization', 'Bearer YOUR_API_KEY'); client.Complete({ prompt: 'Hello' }, metadata, callback); ``` ## Network Access ### Local Network To connect from other devices on your network: 1. Find the server Mac's IP address: ```bash ipconfig getifaddr en0 ``` 2. Connect using the IP: ```bash grpcurl -plaintext 192.168.1.100:50051 ... ``` ### Firewall If connections fail, check macOS firewall: - System Settings → Network → Firewall - Allow incoming connections for the app ## Troubleshooting ### Connection Refused - Verify server is running - Check host and port - Ensure firewall allows connections ### Deadline Exceeded - Server may be overloaded - Increase timeout in client - Check network latency ### Unauthenticated - API key is required but not provided - API key is incorrect - Check `Authorization` header format ### Model Not Available - Apple Intelligence is not enabled on the server Mac - Check System Settings → Apple Intelligence & Siri - Ensure macOS 26+ and Apple Silicon