Include examples in type checking

Remove `examples/` from the `pyrightconfig.json` ignore list and fix
the resulting type errors across all example files. Common fixes:

- Required API keys: `os.getenv("X")` -> `os.environ["X"]` so the
  return type is `str` rather than `str | None`, and misconfiguration
  fails fast.
- Narrow `LLMContextMessage` union members with `isinstance(..., dict)`
  before dict-style access.
- `assert isinstance(params.llm, ...)` before calling service-specific
  methods that aren't on the base `LLMService`.
- Guard optional frame fields (e.g. `LLMSearchResponseFrame.search_result`)
  before use.
This commit is contained in:
Mark Backman
2026-04-20 15:50:49 -04:00
parent 103ced1eaa
commit 58a17c7b1b
293 changed files with 884 additions and 1006 deletions

View File

@@ -48,7 +48,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
logger.info(f"Starting bot")
stt = AssemblyAISTTService(
api_key=os.getenv("ASSEMBLYAI_API_KEY"),
api_key=os.environ["ASSEMBLYAI_API_KEY"],
settings=AssemblyAISTTService.Settings(
model="u3-rt-pro",
),

View File

@@ -54,7 +54,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
logger.info(f"Starting bot")
stt = AzureSTTService(
api_key=os.getenv("AZURE_SPEECH_API_KEY"),
api_key=os.environ["AZURE_SPEECH_API_KEY"],
region=os.getenv("AZURE_SPEECH_REGION"),
)

View File

@@ -47,7 +47,7 @@ transport_params = {
async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
logger.info(f"Starting bot")
stt = CartesiaSTTService(api_key=os.getenv("CARTESIA_API_KEY"))
stt = CartesiaSTTService(api_key=os.environ["CARTESIA_API_KEY"])
tl = TranscriptionLogger()

View File

@@ -48,7 +48,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
logger.info(f"Starting bot")
stt = DeepgramSTTService(
api_key=os.getenv("DEEPGRAM_API_KEY"),
api_key=os.environ["DEEPGRAM_API_KEY"],
settings=DeepgramSTTService.Settings(
language=Language.EN,
),

View File

@@ -49,7 +49,7 @@ transport_params = {
async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
logger.info(f"Starting bot")
stt = ElevenLabsRealtimeSTTService(api_key=os.getenv("ELEVENLABS_API_KEY"))
stt = ElevenLabsRealtimeSTTService(api_key=os.environ["ELEVENLABS_API_KEY"])
tl = TranscriptionLogger()
vad_processor = VADProcessor(vad_analyzer=SileroVADAnalyzer())

View File

@@ -55,9 +55,12 @@ transport_params = {
async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
logger.info(f"Starting bot")
region = os.getenv("GLADIA_REGION", "us-west")
assert region in ("us-west", "eu-west"), f"Invalid GLADIA_REGION: {region}"
stt = GladiaSTTService(
api_key=os.getenv("GLADIA_API_KEY"),
region=os.getenv("GLADIA_REGION"),
api_key=os.environ["GLADIA_API_KEY"],
region=region,
settings=GladiaSTTService.Settings(
language_config=LanguageConfig(
languages=[Language.EN],

View File

@@ -47,9 +47,12 @@ transport_params = {
async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
logger.info(f"Starting bot")
region = os.getenv("GLADIA_REGION", "us-west")
assert region in ("us-west", "eu-west"), f"Invalid GLADIA_REGION: {region}"
stt = GladiaSTTService(
api_key=os.getenv("GLADIA_API_KEY"),
region=os.getenv("GLADIA_REGION"),
api_key=os.environ["GLADIA_API_KEY"],
region=region,
# settings=GladiaSTTSettings(
# language_config=LanguageConfig(
# languages=[Language.FR],

View File

@@ -289,7 +289,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
logger.info(f"Starting bot")
tts = CartesiaTTSService(
api_key=os.getenv("CARTESIA_API_KEY"),
api_key=os.environ["CARTESIA_API_KEY"],
settings=CartesiaTTSService.Settings(
voice="71a7ad14-091c-4e8e-a314-022ece01c121", # British Reading Lady
),
@@ -301,7 +301,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
model="gemini-2.5-flash",
system_instruction=conversation_system_message,
),
api_key=os.getenv("GOOGLE_API_KEY"),
api_key=os.environ["GOOGLE_API_KEY"],
# we can give the GoogleLLMService a system instruction to use directly
# in the GenerativeModel constructor. Let's do that rather than put
# our system message in the messages list.
@@ -313,7 +313,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
model="gemini-2.5-flash",
system_instruction=transcriber_system_message,
),
api_key=os.getenv("GOOGLE_API_KEY"),
api_key=os.environ["GOOGLE_API_KEY"],
)
messages = [

View File

@@ -50,7 +50,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
logger.info(f"Starting bot")
stt = GradiumSTTService(
api_key=os.getenv("GRADIUM_API_KEY"),
api_key=os.environ["GRADIUM_API_KEY"],
api_endpoint_base_url="wss://us.api.gradium.ai/api/speech/asr",
settings=GradiumSTTService.Settings(
language=Language.EN,

View File

@@ -54,7 +54,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
logger.info(f"Starting bot")
stt = MistralSTTService(
api_key=os.getenv("MISTRAL_API_KEY"),
api_key=os.environ["MISTRAL_API_KEY"],
)
tl = TranscriptionLogger()

View File

@@ -50,7 +50,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
logger.info(f"Starting bot")
stt = OpenAIRealtimeSTTService(
api_key=os.getenv("OPENAI_API_KEY"),
api_key=os.environ["OPENAI_API_KEY"],
settings=OpenAIRealtimeSTTService.Settings(
model="gpt-4o-transcribe",
prompt="Expect words related to dogs, such as breed names.",

View File

@@ -54,7 +54,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
logger.info(f"Starting bot")
stt = SonioxSTTService(
api_key=os.getenv("SONIOX_API_KEY"),
api_key=os.environ["SONIOX_API_KEY"],
)
tl = TranscriptionLogger()

View File

@@ -64,7 +64,7 @@ async def run_bot(transport: BaseTransport, runner_args: RunnerArguments):
logger.info(f"Starting bot")
stt = SpeechmaticsSTTService(
api_key=os.getenv("SPEECHMATICS_API_KEY"),
api_key=os.environ["SPEECHMATICS_API_KEY"],
settings=SpeechmaticsSTTService.Settings(
language=Language.EN,
speaker_active_format="<{speaker_id}>{text}</{speaker_id}>",