Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .cursor/skills/scaffold-elevenlabs-example/scripts/scaffold_example.py
100644 → 100755
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def pick_reference(paths: list[Path]) -> Path | None:
if not paths:
return None

return sorted(paths, key=lambda path: (path.name != "quickstart", str(path)))[0]
return min(paths, key=lambda path: (path.name != "quickstart", str(path)))


def find_reference(
Expand Down Expand Up @@ -119,7 +119,7 @@ def write_file(path: Path, content: str) -> None:

def main() -> None:
args = parse_args()
product, runtime, slug = parse_example_path(args.path)
product, runtime, _slug = parse_example_path(args.path)

target_dir = (REPO_ROOT / args.path.strip().strip("/")).resolve()
if REPO_ROOT not in target_dir.parents:
Expand Down
2 changes: 2 additions & 0 deletions agents/nextjs/guardrails/example/app/api/agent/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,6 +106,8 @@ export async function POST() {
name: "No investment recommendations",
isEnabled: true,
executionMode: "blocking",
model: "gemini-2.5-flash-lite",
historyMessageCount: 1,
prompt:
"Block any response that recommends investments, suggests specific stocks, ETFs, funds, bonds, crypto, or portfolio allocations, or otherwise gives personalized financial or investment advice. If the agent starts giving investment recommendations, end the conversation immediately.",
triggerAction: { type: "end_call" },
Expand Down
Original file line number Diff line number Diff line change
@@ -1,8 +1,23 @@
import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";
import { ElevenLabsClient, ElevenLabsError } from "@elevenlabs/elevenlabs-js";
import { NextResponse } from "next/server";

function requireApiKey(): string | null {
const key = process.env.ELEVENLABS_API_KEY;
return key?.trim() ? key : null;
}

function apiErrorMessage(err: unknown): string {
if (err instanceof ElevenLabsError) {
return err.message;
}
if (err instanceof Error) {
return err.message;
}
return "An unexpected error occurred.";
}

export async function GET(request: Request) {
const apiKey = process.env.ELEVENLABS_API_KEY;
const apiKey = requireApiKey();
if (!apiKey) {
return NextResponse.json(
{ error: "Server misconfiguration: ELEVENLABS_API_KEY is not set." },
Expand All @@ -18,17 +33,18 @@ export async function GET(request: Request) {
);
}

const client = new ElevenLabsClient({ apiKey });

try {
const { signedUrl } =
await client.conversationalAi.conversations.getSignedUrl({
agentId,
});
return NextResponse.json({ signedUrl });
} catch (e) {
const message =
e instanceof Error ? e.message : "Failed to create signed URL.";
return NextResponse.json({ error: message }, { status: 502 });
const client = new ElevenLabsClient({ apiKey });
const res = await client.conversationalAi.conversations.getWebrtcToken({
agentId,
});
return NextResponse.json({ token: res.token });
} catch (err) {
const status =
err instanceof ElevenLabsError && err.statusCode ? err.statusCode : 502;
return NextResponse.json(
{ error: apiErrorMessage(err) },
{ status: status >= 400 && status < 600 ? status : 502 }
);
}
}
9 changes: 4 additions & 5 deletions agents/nextjs/guardrails/example/app/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -112,15 +112,14 @@ function GuardrailsPage({
const res = await fetch(
`/api/conversation-token?agentId=${encodeURIComponent(trimmedId)}`
);
const data: { signedUrl?: string; error?: string } = await res.json();
if (!res.ok || !data.signedUrl) {
setSessionError(data.error ?? "Could not get signed URL.");
const data: { token?: string; error?: string } = await res.json();
if (!res.ok || !data.token) {
setSessionError(data.error ?? "Could not get conversation token.");
return;
}

await startSession({
connectionType: "websocket",
signedUrl: data.signedUrl,
conversationToken: data.token,
});
} catch (error) {
const nextMessage =
Expand Down
2 changes: 1 addition & 1 deletion agents/nextjs/guardrails/example/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@
},
"pnpm": {
"overrides": {
"livekit-client": "2.19.1"
"livekit-client": "2.16.1"
Comment thread
cursor[bot] marked this conversation as resolved.
}
}
}
2 changes: 1 addition & 1 deletion agents/nextjs/guardrails/setup.sh
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ node -e "
delete pkg.dependencies['@elevenlabs/client'];
pkg.pnpm = pkg.pnpm || {};
pkg.pnpm.overrides = pkg.pnpm.overrides || {};
pkg.pnpm.overrides['livekit-client'] = '2.19.1';
pkg.pnpm.overrides['livekit-client'] = '2.16.1';
require('fs').writeFileSync('package.json', JSON.stringify(pkg, null, 2) + '\n');
"

Expand Down
11 changes: 3 additions & 8 deletions music/python/quickstart/example/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,13 +4,12 @@
import json
import os
import sys
from typing import Any, Optional
from typing import Any

from dotenv import load_dotenv
from elevenlabs import ElevenLabs
from elevenlabs.core.api_error import ApiError


DEFAULT_PROMPT = "A chill lo-fi beat with jazzy piano chords"
OUTPUT_FILE = "output.mp3"

Expand All @@ -32,7 +31,7 @@ def _body_as_dict(error: ApiError) -> dict[str, Any]:
return {}


def _find_prompt_suggestion(obj: Any) -> Optional[str]:
def _find_prompt_suggestion(obj: Any) -> str | None:
if isinstance(obj, dict):
suggestion = obj.get("prompt_suggestion")
if suggestion:
Expand Down Expand Up @@ -111,8 +110,7 @@ def main() -> None:
music_length_ms=10000,
)
with open(out_path, "wb") as f:
for chunk in audio:
f.write(chunk)
f.writelines(audio)
except ApiError as e:
body_dict = _body_as_dict(e)
suggestion = _find_prompt_suggestion(body_dict)
Expand All @@ -126,9 +124,6 @@ def main() -> None:
except OSError as e:
print(f"Could not write {out_path}: {e}", file=sys.stderr)
raise SystemExit(1) from None
except Exception as e:
print(f"Unexpected error: {e}", file=sys.stderr)
raise SystemExit(1) from None

print(f"Saved music to {out_path}")

Expand Down
6 changes: 3 additions & 3 deletions sound-effects/python/quickstart/example/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

from dotenv import load_dotenv
from elevenlabs import ElevenLabs
from elevenlabs.core.api_error import ApiError

load_dotenv()

Expand All @@ -20,15 +21,14 @@ def main() -> int:
audio = client.text_to_sound_effects.convert(text=prompt)

with output_path.open("wb") as output_file:
for chunk in audio:
output_file.write(chunk)
output_file.writelines(audio)

print(f"Wrote generated sound effect to {output_path}")
return 0
except KeyError:
print("Missing ELEVENLABS_API_KEY. Add it to .env before running.", file=sys.stderr)
return 1
except Exception as error:
except (ApiError, OSError) as error:
print(f"Sound effect generation failed: {error}", file=sys.stderr)
return 1

Expand Down
6 changes: 5 additions & 1 deletion speech-to-text/python/quickstart/example/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from dotenv import load_dotenv
from elevenlabs import ElevenLabs
from elevenlabs.core.api_error import ApiError

load_dotenv()

Expand All @@ -25,7 +26,10 @@ def main():
except FileNotFoundError:
print(f"Error: Audio file not found: {audio_path}", file=sys.stderr)
sys.exit(1)
except Exception as e:
except KeyError:
print("Error: Missing ELEVENLABS_API_KEY", file=sys.stderr)
sys.exit(1)
except ApiError as e:
print(f"Error: Transcription failed: {e}", file=sys.stderr)
sys.exit(1)

Expand Down
9 changes: 6 additions & 3 deletions text-to-speech/python/quickstart/example/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@

from dotenv import load_dotenv
from elevenlabs import ElevenLabs
from elevenlabs.core.api_error import ApiError

load_dotenv()

Expand All @@ -22,12 +23,14 @@ def main():
)

with open("output.mp3", "wb") as f:
for chunk in audio:
f.write(chunk)
f.writelines(audio)

print("Success! Audio saved to output.mp3")

except Exception as e:
except KeyError:
print("Error: Missing ELEVENLABS_API_KEY")
sys.exit(1)
except (ApiError, OSError) as e:
print(f"Error: {e}")
sys.exit(1)

Expand Down
Loading