PE

perplexity-local-dev-loop

Configures local mocking and testing for Perplexity APIs to save costs and speed up the development feedback loop.

Install

mkdir -p .claude/skills/perplexity-local-dev-loop && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/4798" && unzip -o skill.zip -d .claude/skills/perplexity-local-dev-loop && rm skill.zip

Installs to .claude/skills/perplexity-local-dev-loop

Activation

This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.

Configure Perplexity local development with mocking, testing, and hot
69 charsno explicit “when” trigger
Intermediate

Key capabilities

  • Configure mock fixtures for offline development
  • Implement type-safe client wrappers
  • Enable live integration testing gated by API keys
  • Set up hot-reload development workflows
  • Capture API responses for test fixtures

How it works

The skill establishes a development loop using mock fixtures to simulate API responses. This allows developers to work offline and avoid costs during the iteration cycle.

Inputs & outputs

You give it
Development code and test queries
You get back
Mocked API responses or live test results

When to use perplexity-local-dev-loop

  • Configure local development with mock responses
  • Speed up test cycles for search features
  • Safely iterate on search result parsing
  • Enable offline development for API integrations

About this skill

Perplexity Local Dev Loop

Overview

Set up a fast, cost-effective local development workflow for Perplexity Sonar API. Key challenge: every real API call performs a web search and costs money, so mocking and caching are essential for development.

Prerequisites

  • Completed perplexity-install-auth setup
  • Node.js 18+ with npm/pnpm
  • vitest for testing

Instructions

Step 1: Project Structure

my-perplexity-project/
├── src/
│   ├── perplexity/
│   │   ├── client.ts       # OpenAI client wrapper for Perplexity
│   │   ├── search.ts       # Search functions with citation handling
│   │   └── types.ts        # Response type extensions
│   └── index.ts
├── tests/
│   ├── fixtures/           # Saved API responses for mocking
│   │   └── sonar-response.json
│   ├── perplexity.test.ts
│   └── setup.ts
├── .env.local              # API key (git-ignored)
├── .env.example            # Template
└── package.json

Step 2: Type-Safe Client Wrapper

// src/perplexity/client.ts
import OpenAI from "openai";

export interface PerplexityResponse extends OpenAI.ChatCompletion {
  citations?: string[];
  search_results?: Array<{
    title: string;
    url: string;
    snippet: string;
  }>;
  related_questions?: string[];
}

export type PerplexityModel = "sonar" | "sonar-pro" | "sonar-reasoning-pro" | "sonar-deep-research";

export function createClient(apiKey?: string): OpenAI {
  return new OpenAI({
    apiKey: apiKey || process.env.PERPLEXITY_API_KEY,
    baseURL: "https://api.perplexity.ai",
  });
}

export async function search(
  client: OpenAI,
  query: string,
  opts: {
    model?: PerplexityModel;
    systemPrompt?: string;
    maxTokens?: number;
    searchRecencyFilter?: "hour" | "day" | "week" | "month";
    searchDomainFilter?: string[];
  } = {}
): Promise<PerplexityResponse> {
  const response = await client.chat.completions.create({
    model: opts.model || "sonar",
    messages: [
      ...(opts.systemPrompt
        ? [{ role: "system" as const, content: opts.systemPrompt }]
        : []),
      { role: "user" as const, content: query },
    ],
    max_tokens: opts.maxTokens,
    ...(opts.searchRecencyFilter && { search_recency_filter: opts.searchRecencyFilter }),
    ...(opts.searchDomainFilter && { search_domain_filter: opts.searchDomainFilter }),
  } as any);

  return response as unknown as PerplexityResponse;
}

Step 3: Save Fixtures for Offline Development

// scripts/capture-fixture.ts
import { createClient, search } from "../src/perplexity/client";
import { writeFileSync } from "fs";

async function captureFixture() {
  const client = createClient();
  const response = await search(client, "What is TypeScript 5.5?");

  writeFileSync(
    "tests/fixtures/sonar-response.json",
    JSON.stringify(response, null, 2)
  );
  console.log("Fixture saved with", (response.citations || []).length, "citations");
}

captureFixture();

Step 4: Mock Client for Tests

// tests/setup.ts
import { vi } from "vitest";
import fixture from "./fixtures/sonar-response.json";

export function mockPerplexityClient() {
  return {
    chat: {
      completions: {
        create: vi.fn().mockResolvedValue(fixture),
      },
    },
  };
}

Step 5: Write Tests

// tests/perplexity.test.ts
import { describe, it, expect } from "vitest";
import { mockPerplexityClient } from "./setup";
import { search } from "../src/perplexity/client";

describe("Perplexity Search", () => {
  it("returns answer with citations", async () => {
    const client = mockPerplexityClient() as any;
    const result = await search(client, "test query");

    expect(result.choices[0].message.content).toBeDefined();
    expect(result.citations).toBeDefined();
    expect(result.citations!.length).toBeGreaterThan(0);
  });

  it.skipIf(!process.env.PERPLEXITY_API_KEY)(
    "live API returns citations",
    async () => {
      const { createClient, search } = await import("../src/perplexity/client");
      const client = createClient();
      const result = await search(client, "What is Node.js?", {
        model: "sonar",
        maxTokens: 100,
      });
      expect(result.citations!.length).toBeGreaterThan(0);
    }
  );
});

Step 6: Dev Scripts

{
  "scripts": {
    "dev": "tsx watch src/index.ts",
    "test": "vitest",
    "test:watch": "vitest --watch",
    "test:live": "PERPLEXITY_API_KEY=$PERPLEXITY_API_KEY vitest --run",
    "capture-fixtures": "tsx scripts/capture-fixture.ts"
  }
}

Error Handling

ErrorCauseSolution
Fixture missingNever capturedRun npm run capture-fixtures once
Tests hit real APIMissing mockEnsure mock client is injected
Stale fixturesAPI response format changedRe-capture fixtures
High dev costsMaking live calls in loopUse fixtures; reserve live calls for CI

Output

  • Type-safe Perplexity client wrapper
  • Fixture-based test suite that runs offline
  • Live integration test gated on API key presence
  • Hot-reload dev server

Resources

Next Steps

See perplexity-sdk-patterns for production-ready code patterns.

Prerequisites

Node.js 18+ with npm/pnpmvitest for testing

Limitations

  • Requires manual capture of fixtures
  • Stale fixtures if API response format changes

How it compares

It shifts the development workflow from live API calls to a fixture-based testing model, significantly reducing costs and latency during coding.

Compared to similar skills

perplexity-local-dev-loop side by side with the closest alternatives in the catalog.

SkillInstallsUpdatedSafetyDifficulty
perplexity-local-dev-loop (this skill)127dReviewIntermediate
zod-4127moNo flagsIntermediate
develop-ai-functions-example56moReviewIntermediate
indicator-buffer11moNo flagsAdvanced

Try saying

Example prompts that trigger this skill in your AI assistant.

More by jeremylongshore

View all by jeremylongshore

analyzing-logs

jeremylongshore

Analyze application logs to detect performance issues, identify error patterns, and improve stability by extracting key insights.

14123

ollama-setup

jeremylongshore

Configure auto-configure Ollama when user needs local LLM deployment, free AI alternatives, or wants to eliminate hosted API costs. Trigger phrases: "install ollama", "local AI", "free LLM", "self-hosted AI", "replace OpenAI", "no API costs". Use when appropriate context detected. Trigger with relevant phrases based on skill purpose.

1167

backtesting-trading-strategies

jeremylongshore

Backtest crypto and traditional trading strategies against historical data. Calculates performance metrics (Sharpe, Sortino, max drawdown), generates equity curves, and optimizes strategy parameters. Use when user wants to test a trading strategy, validate signals, or compare approaches. Trigger with phrases like "backtest strategy", "test trading strategy", "historical performance", "simulate trades", "optimize parameters", or "validate signals".

1071

generating-database-seed-data

jeremylongshore

Process this skill enables AI assistant to generate realistic test data and database seed scripts for development and testing environments. it uses faker libraries to create realistic data, maintains relational integrity, and allows configurable data volumes. u... Use when working with databases or data models. Trigger with phrases like 'database', 'query', or 'schema'.

1033

cursor-codebase-indexing

jeremylongshore

Execute set up and optimize Cursor codebase indexing. Triggers on "cursor index setup", "codebase indexing", "index codebase", "cursor semantic search". Use when working with cursor codebase indexing functionality. Trigger with phrases like "cursor codebase indexing", "cursor indexing", "cursor".

885

testing-mobile-apps

jeremylongshore

Execute mobile app testing on iOS and Android devices/simulators. Use when performing specialized testing. Trigger with phrases like "test mobile app", "run iOS tests", or "validate Android functionality".

810

Search skills

Search the agent skills registry