Files
97aab3e9b9 refactor(search): always send searches as incognito (#14)
Hardcode is_incognito: true in the Perplexity request and remove the
toggle surface: the incognito tool parameter, PI_PERPLEXITY_INCOGNITO
env var, config file field, /perplexity-config prompt, and TUI status
indicators. Config and resolveDefaultModel are now model-only.

Supersedes the incognito portion of PR #4.

Co-authored-by: Ivan Pereira <183991+ivanrvpereira@users.noreply.github.com>
2026-07-16 15:28:02 +01:00

4.0 KiB

pi-perplexity

Stack

  • TypeScript extension for @earendil-works/pi-coding-agent; loaded directly via jiti, no build artifact.
  • Node >=18.14.1 runtime APIs only: fetch, crypto.randomUUID(), Buffer.from(..., "base64url"), Intl.
  • Pi-bundled packages live in peerDependencies with "*": @earendil-works/pi-tui, @earendil-works/pi-ai. Type is re-exported by @earendil-works/pi-ai; do not depend on typebox directly.

Commands

npm run typecheck
npm test
node --no-deprecation --import ./node_modules/@earendil-works/pi-coding-agent/node_modules/jiti/lib/jiti-register.mjs --input-type=module -e "import('./src/index.ts').then((m)=>{ const entry = m.default?.default ?? m.default; if (typeof entry !== 'function') throw new Error('default export missing'); })"

File-Scoped Commands

Task Command
Single test file npm run test:build && node --test --experimental-test-module-mocks ".tmp-test/test/search/stream.test.js"
Live E2E opt-in PI_PERPLEXITY_E2E=1 npm test

Structure

  • src/index.ts — extension entry and perplexity_search tool definition.
  • src/auth/ — JWT extraction, email OTP login, token storage.
  • src/search/ — Perplexity SSE request, stream merge, result formatting, models.
  • src/render/ — TUI renderers for tool calls and results.
  • src/commands/ — slash commands such as login/config.
  • test/ — automated Node test suite; .tmp-test/ is generated by npm run test:build.
  • local_tests/ — manual/debug scripts and captured dumps; do not treat as automated coverage.
  • docs/design-decisions.md — rationale for non-obvious behavior.

Extension Conventions

  • Entry point exports a default factory from src/index.ts.
  • Tool name is perplexity_search.
  • Tool execute signature is (toolCallId, params, signal, onUpdate, ctx).
  • Tool results use { content: [{ type: "text", text }], details: { ... } }.
  • String enum params use StringEnum from @earendil-works/pi-ai; Type.Union([Type.Literal(...)]) breaks Google models.
  • Stream/API types stay loose: all reverse-engineered event fields are optional.

Perplexity Protocol Gotchas

  • Endpoint: POST https://www.perplexity.ai/rest/sse/perplexity_ask.
  • Required Perplexity constants live in src/constants.ts.
  • Searches always send is_incognito: true to avoid polluting user history; there is no toggle.
  • The response is data: JSON lines with [DONE], not a fully standard SSE stream.
  • Events are incremental snapshots: shallow-merge top level, merge blocks by intended_usage, splice markdown via chunk_starting_offset, accumulate sources.
  • Completion is event.final === true or event.status === "COMPLETED".
  • Answer extraction order: markdown blocks → ask_text blocks → event text.
  • Source extraction order: web_results block → sources_list; deduplicate by URL.

Auth Gotchas

  • Auth tries macOS app token first via defaults read ai.perplexity.mac authToken, unless PI_AUTH_NO_BORROW=1.
  • Email OTP fallback uses ctx.ui.input().
  • Tokens are stored at ~/.config/pi-perplexity/auth.json with mode 0600.
  • Stored tokens have no expiry tracking; loadToken() returns any cached token and expiry surfaces as 401/403 at request time.
  • AUTH errors preserve the cached token; users explicitly clear/re-auth with /perplexity-login --force.

Boundaries

Always

  • Pass AbortSignal through to network calls.
  • Return user-readable error text from tool execution instead of throwing raw errors.
  • Keep runtime dependency-free; use platform APIs for HTTP, SSE parsing, JWT decoding, and UUIDs.

Ask First

  • Changing Perplexity request headers, model IDs, or auth flow behavior.
  • Adding package dependencies or generated build artifacts.
  • Deleting captured local test dumps or token-related files.

Never

  • Never commit secrets, credentials, .env, cached auth tokens, or live Perplexity response dumps containing private data.
  • Never clear cached auth automatically on transient 401/403 responses.