Files
Benjamin Taylor 8ebdd33998 fix(packages): raise the published Node engines floor to 20
Seven published packages declared `engines.node: ">=18"`, but CI has never
run Node 18 and Node 18 reached end of life on 2025-04-30. The claim
pointed at a runtime nothing tests and that receives no security patches.

Raise those seven to `">=20"`, the lowest version the unit matrix
(20.x, 22.x, 24.x) actually proves, and raise the root manifest to match.

Also give `@copilotkit/runtime` its first `engines` field. It declared
none, while #7089 moved it to pino 10, which drops Node 18. Pino ships no
`engines` of its own, so a consumer on Node 18 installed cleanly and
failed later, at runtime.

Closes #7107

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-12 14:25:05 -05:00
..

@copilotkit/voice

Audio transcription providers for CopilotKit.

Setup

pnpm add @copilotkit/voice openai
import { CopilotRuntime, createCopilotEndpoint } from "@copilotkit/runtime";
import { TranscriptionServiceOpenAI } from "@copilotkit/voice";
import OpenAI from "openai";

const runtime = new CopilotRuntime({
  agents: { default: yourAgent },
  transcriptionService: new TranscriptionServiceOpenAI({
    openai: new OpenAI({ apiKey: process.env.OPENAI_API_KEY }),
  }),
});

Once configured, the chat UI shows a microphone button. Users can record audio, which gets transcribed and inserted into the input field as text.

TranscriptionServiceOpenAI

Uses OpenAI Whisper for transcription.

new TranscriptionServiceOpenAI({
  openai: new OpenAI({ apiKey: "..." }), // required
  model: "whisper-1", // default
  language: "en", // optional, ISO-639-1 code
  prompt: "Technical discussion context", // optional, helps with domain terms
  temperature: 0, // optional, 0 = deterministic
});

Custom providers

Extend TranscriptionService from runtime:

import {
  TranscriptionService,
  TranscribeFileOptions,
} from "@copilotkit/runtime";

class MyTranscriptionService extends TranscriptionService {
  async transcribeFile(options: TranscribeFileOptions): Promise<string> {
    // options.audioFile, options.mimeType, options.size
    return "transcribed text";
  }
}