← SpeakShelfCONTENT HISTORY

Update to SpeakShelf

Snapshot Nov 13, 2026 · 00:10 UTC · version 1.0.0

Collection source: downloaded plugin package.

WHAT CHANGED

First saved snapshot

No earlier snapshot is available to establish a change.

Save SpeakShelf and check future changes in Following.

Up to 3 plugins free · no card required.

Compare saved observations

Download comparison JSON
Full technical diff · 0 changed fields
Full snapshot data
{
  "description": "Discover, browse and compare the current SpeakShelf text-to-speech catalogue by provider, family, model, voice name or locale, and handle a requested catalogue sample for a selected voice.",
  "included_files": [
    {
      "relative_path": "agents/openai.yaml",
      "size_in_bytes": 240
    },
    {
      "relative_path": "references/contract.md",
      "size_in_bytes": 4253
    },
    {
      "relative_path": "references/examples.md",
      "size_in_bytes": 3848
    }
  ],
  "name": "catalogue-discovery",
  "skill_md_contents": "---\nname: catalogue-discovery\ndescription: Discover, browse and compare the current SpeakShelf text-to-speech catalogue by provider, family, model, voice name or locale, and handle a requested catalogue sample for a selected voice.\n---\n\n# SpeakShelf catalogue discovery\n\nDraft workflow. Follow the user's explicit constraints over these guidelines.\nUse SpeakShelf's existing `search_voices` and, only for an authorized sample\nrequest, `get_voice_sample`. There is no separate options, details or comparison\ntool. Do not substitute another TTS service. If the tools are unavailable,\nexplain the missing connection instead of inventing catalogue results.\n\n## Find the requested voices\n\n1. Separate provider, family, concrete model, voice name, voice locale and\n   interface locale. A family is not a model ID; a voice name is not a unique\n   voice ID. Family identity is the pair of provider and exact family key.\n   Voice locale selects spoken-language catalogue rows. Interface locale only\n   changes labels and links; changing it must not change voice locale.\n2. Search directly when the intended filters and their exact values are known\n   from current tools or earlier usable results. Otherwise make the smallest\n   useful `search_voices` discovery request, retaining known user constraints.\n   Read `providerOptions` and `filterOptions` from that response. Do not run an\n   unfiltered discovery call before every search or repeat a call to open the\n   same widget. Reuse current results when they answer the request.\n3. Use returned provider/family `key`, model `id` and language `code` values,\n   never translated labels or guessed spellings. An echoed option with\n   `available:false` is not validation. Discover outside a conflicting scope\n   only as an explicitly described diagnostic, keeping it separate from the\n   user's requested result. Read [contract details](references/contract.md)\n   when validating dependent options, handling ambiguity or selecting a model.\n4. Put exact constraints in structured fields. Use `query` for concise residual\n   name or trait terms: its tokens are matched together, not as semantic prose.\n   Do not paste the whole request into it. Split comparison alternatives into\n   structured searches; prose such as \"A or B\" is not Boolean OR. Use only schema-supported filters.\n   A request for a style or trait can use catalogue search terms, but returned\n   metadata is descriptive, not a synthesis control or sound-quality proof.\n5. Preserve model intent: omit `model` to allow conservative inference, pass a\n   usable concrete model ID for an explicit selection, or send `model: \"\"` for\n   deliberate All models in search. Never replace All with an inferred model.\n   An ambiguous or unsupported model qualifier is not permission to select a\n   nearby model. Clarify material ambiguity or show the available choices.\n6. Read `appliedFilters`, `modelSelection`, `voices`, `total` and pagination\n   fields. Explain unexpected applied filters or an empty result. Distinguish\n   invalid identifiers, valid but incompatible filters and a genuine no-match\n   result using usable discovered options and the selected rows. The server may\n   return `total:0` for all three. If evidence cannot distinguish them, say so.\n   Never silently drop a requested constraint to manufacture results.\n\n## Browse and compare\n\nFor catalogue-wide discovery, obtain current provider options, then each\nprovider's family options as needed. Cover every currently exposed family,\nincluding unfamiliar future additions. Do not use a static family list or\nsource registry as live inventory. A page is not the whole catalogue. When the\nuser requests all rows, continue through returned cursors within a stated scope\nand report any incomplete traversal or catalogue refresh.\n\nCompare returned rows in a compact table when helpful: name, exact voice ID,\nprovider, family key/label, voice locale, eligible returned models, tier and\nrelevant traits. Keep unknown metadata unknown. Compare multiple providers\nusing separate scoped searches only when one search cannot answer the request.\nReport partial or empty sides honestly; do not invent rankings, accents,\nprices, quality claims or synthesis support. Counts describe catalogue rows,\nnot necessarily unique personas or spoken languages. Use returned `siteUrl`\nor `referralUrl` as related provider/language pages, not voice-selection links.\n\nFor next/previous pages, send the returned `nextCursor`/`previousCursor`\nunchanged with the ORIGINAL request's query, provider, voice_locale,\ninterface_locale, family, gender, tier, page_size, primary_only and model\npresence/value. In particular, do not copy an inferred `appliedFilters.model`\ninto an originally omitted `model`: auto, explicit and All have distinct cursor\nscopes. Keep the effective interface locale stable across paging. If original\nintent cannot be recovered, restart transparently rather than guess. A changed\nfilter starts a new search without the old cursor. Missing cursors mean a page\nboundary. If a stale cursor resets or fails, explain and restart the same scope;\ndo not claim uninterrupted traversal or fabricate a cursor.\n\nUse `primary_only:true` only for an Azure Primary request, with `provider:azure`\nand the intended voice locale. Primary means exact Azure-declared locale\nmetadata after BCP-47 canonicalization. It guarantees neither accent nor audio\nquality and is not a cross-provider rule. Do not derive it from a name or ID.\n\n## Handle a requested sample\n\nBrowsing and comparison do not authorize audio preparation. A sample lookup\ncan prepare owner-cost audio even though visitors are not charged. Respect the\nuser's sample permission and any no-audio constraint. Resolve the selected row\nfrom the current result; clarify ambiguous names or ordinals before calling.\n\nPreserve its exact `id` as `voice_id`, locale identity and eligible model. A\nuser's explicit eligible sample override wins; otherwise retain the concrete\napplied search model when eligible for that row. If no concrete model was\nselected, omit sample `model` to use the server's row-eligible default. Never\nsend `model:\"\"` to `get_voice_sample`; All is a search state. Do not infer a\nmodel selector from a family name or from `models:[]`. `sampleAvailable:false`\nmeans unavailable; an absent flag does not prove readiness. Do not substitute\nanother voice or model for an incompatible selection.\n\nRead [sample states](references/contract.md#sample-states) before handling a\npending or failed lookup. Explain the returned state, respect `retryAfter`,\nand avoid uncontrolled retries. Only use `refresh_after_media_error` after an\nactual failure of the returned media URL. A ready URL is not audible playback\nproof. Never substitute custom text generation, cloning, uploads, purchases or\nprivate-library actions; these are outside the exposed tools.\n\n## Present the result\n\nGive a short answer focused on the user's criteria, meaningful differences,\nconstraints and next page or sample choice. Avoid duplicating the widget's\nentire contents. Do not claim it rendered from metadata alone or claim it is\nunavailable without a host signal. When unavailable, use structured results,\ntext and returned catalogue links. Preserve exact identifiers even when prose\nor interface labels are localized. Read [examples](references/examples.md)\nfor representative edge cases; examples are not a frozen catalogue inventory.\n"
}

SHA-256 of public snapshot: 526b284b4ed42b0088e2fa6f9a6756a7b8d3f22cf6535565869e6764bf0b0040