Call our endpoints from server-side or browser environments.
The Pi Labs JavaScript SDK provides convenient, type-safe access to the Pi Client REST API from server-side TypeScript or JavaScript applications. This guide covers installation, basic usage, configuration, and advanced features.Documentation is also available at the GitHub repository.The SDK supports a wide range of JavaScript runtimes:
Web Browsers
Modern browsers including Chrome, Firefox, Safari, and Edge
Node.js
Node.js 18 LTS or later (non-EOL versions)
Alternative Runtimes
Deno v1.28.0+, Bun 1.0+, Cloudflare Workers, Vercel Edge Runtime
Testing & Frameworks
Jest 28+ with “node” environment, Nitro v2.6+
React Native is not currently supported. If you need support for additional runtime environments, please contact us.
const scores = await pi.scoringSystem.score({ llm_input: "What are some good day trips from Milan by train?", llm_output: "Milan is an excellent hub for day trips by train. You can take a short ride to the stunning shores of Lake Como to explore picturesque towns like Bellagio and Varenna. Alternatively, the historic hilltop city of Bergamo is another charming and easily accessible option. For a spectacular alpine adventure, consider the Bernina Express scenic train journey through the Swiss Alps. Cities like Turin and Verona are also just an hour or two away via high-speed train.", scoring_spec: [ { question: "Does the response maintain a professional tone?" }, { question: "Did the response fulfill the intent of the user's query?" }, { question: "Did the response only present data relevant to the user's query?" } ],});console.log('Total Score:', scores.total_score);console.log('Question Scores:', scores.question_scores);
You should receive a response with the scores Pi Scorer assigned to the generation.
Note that because the SDK is generated with Stainless, function parameters use
snake_case names rather than camelCase.
The SDK includes comprehensive TypeScript definitions for type safety:
Copy
import PiClient from 'withpi';const pi = new PiClient();// Type-safe parametersconst params: PiClient.ScoringSystemScoreParams = { llm_input: "What are some good day trips from Milan by train?", llm_output: "Milan is an excellent hub for day trips by train. You can take a short ride to the stunning shores of Lake Como to explore picturesque towns like Bellagio and Varenna. Alternatively, the historic hilltop city of Bergamo is another charming and easily accessible option. For a spectacular alpine adventure, consider the Bernina Express scenic train journey through the Swiss Alps. Cities like Turin and Verona are also just an hour or two away via high-speed train.", scoring_spec: [ { label: "Professional Tone", question: "Does the response maintain a professional tone?" }, { label: "Intent Fulfillment", question: "Did the response fulfill the intent of the user's query?" }, { label: "Relevance Check", question: "Did the response only present data relevant to the user's query?" } ],};// Type-safe responseconst scoringSystemMetrics: PiClient.ScoringSystemMetrics = await pi.scoringSystem.score(params);
The SDK throws subclasses of APIError for different scenarios:
Copy
try { const result = await pi.scoringSystem.score({ llm_input: "What are some good day trips from Milan by train?", llm_output: "Milan is an excellent hub for day trips by train. You can take a short ride to the stunning shores of Lake Como to explore picturesque towns like Bellagio and Varenna. Alternatively, the historic hilltop city of Bergamo is another charming and easily accessible option.", scoring_spec: [ { question: "Does the response maintain a professional tone?" }, { question: "Did the response fulfill the intent of the user's query?" }, { question: "Did the response only present data relevant to the user's query?" } ], });} catch (err) { if (err instanceof PiClient.APIError) { console.log('Status:', err.status); // e.g., 400 console.log('Error Type:', err.name); // e.g., BadRequestError console.log('Headers:', err.headers); // Response headers } else { throw err; // Re-throw non-API errors }}
Access the underlying Response object for headers and other metadata:
Copy
const response = await pi.scoringSystem .score({ llm_input: "What are some good day trips from Milan by train?", llm_output: "Milan is an excellent hub for day trips by train. You can take a short ride to the stunning shores of Lake Como to explore picturesque towns like Bellagio and Varenna.", scoring_spec: [{ question: "Does the response maintain a professional tone?" }], }) .asResponse();console.log(response.headers.get('X-My-Header'));console.log(response.statusText);
By default, this library uses a stable agent for all http/https requests to reuse TCP connections, eliminating many TCP & TLS handshakes and shaving around 100ms off most requests.If you would like to disable or customize this behavior, for example to use the API behind a proxy, you can pass an httpAgent which is used for all requests (be they http or https), for example:
Copy
import http from 'http';import { HttpsProxyAgent } from 'https-proxy-agent';// Global configurationconst client = new PiClient({ httpAgent: new HttpsProxyAgent(process.env.PROXY_URL),});// Per-request configurationawait client.scoringSystem.score({ llm_input: "What are some good day trips from Milan by train?", llm_output: "Milan is an excellent hub for day trips by train. You can take a short ride to the stunning shores of Lake Como.", scoring_spec: [{ question: "Does the response maintain a professional tone?" }]}, { httpAgent: new http.Agent({ keepAlive: false }),});