Skip to content

fix(core): install deepgram-skills-v1.8.0 by default - #154

Merged
dg-coreylweathers merged 1 commit into
mainfrom
chore/skills-v1.8.0
Nov 10, 2026
Merged

dg-coreylweathers merged 1 commit into
mainfrom
chore/skills-v1.8.0

Conversation

@dg-coreylweathers

Copy link
Copy Markdown
Contributor

Points dg skills install at the new skills release, deepgram-skills-v1.8.0. Until this ships, deepctl 0.4.0 keeps installing 1.7.0, whose CLI skill still describes deepctl 0.3.1.

Changes three constants in packages/deepctl-core/src/deepctl_core/skill_bundle.py:

Constant Was Now
DEFAULT_SKILLS_COMMIT 0fc13fa… (v1.7.0) 02bc27cb88b97c36ad552ff0e98e7c522fd06f90 (v1.8.0)
DEFAULT_SKILLS_SHA256 5b7f9753… 33a60b2a296f70f6a0cd61b77d8fe4d7565f229136edf877b399a83278731929
DEFAULT_SKILLS_RELEASE deepgram-skills-v1.7.0 deepgram-skills-v1.8.0

The sha256 is of https://codeload.github.com/deepgram/skills/tar.gz/02bc27c…. It was identical across two downloads, and the same method reproduces the old 1.7.0 value.

What 1.8.0 changes in the installed skills: Voice Agent Think Live (formerly Conversational Mode), Flux TTS in 41 languages besides English, Nova-3 mid-stream Configure and language_hint, and the CLI and setup-mcp skills updated for deepctl 0.4.0. No skill is added or removed, so there are still 14.

Verification

  • pytest: 2208 passed, 12 skipped
  • make check (ruff format, ruff lint, mypy): clean
  • Live dg skills install with a throwaway HOME: fetched the pinned 1.8.0 tarball, the checksum matched, it installed 14 skills, and voice-agent/SKILL.md contains think_live

tests/unit/fixtures/legacy_v03/allowlist.tsv still names 0fc13fa on purpose. It records what 0.2.16–0.3.2 installs fetched from main and is not tied to the pin.

🤖 Generated with Claude Code

Pins the default skills bundle to deepgram/skills v1.8.0 (02bc27c): Voice
Agent Think Live, multilingual Flux TTS, Nova-3 Configure and
language_hint, and the CLI skill tracking deepctl 0.4.0.
@dg-coreylweathers
dg-coreylweathers merged commit b5beda0 into main Nov 10, 2026
43 checks passed
@dg-coreylweathers
dg-coreylweathers deleted the chore/skills-v1.8.0 branch November 10, 2026 21:36
@linear-code

linear-code Bot commented Nov 10, 2026

Copy link
Copy Markdown

DG-2713

@github-actions github-actions Bot mentioned this pull request Nov 10, 2026
dg-coreylweathers added a commit that referenced this pull request Nov 12, 2026
…#159)

## deepctl 0.4.1

This release prevents potential logging of API keys, and fixes how dg
handles credentials, configuration, plugins and local servers.

- 0.4.1 sends no telemetry. The error-report key that 0.2.21 to 0.4.0
shipped is removed.
- dg sends your API key only to the host you chose: a regional Deepgram
API host, a host you listed in your own config, or `DEEPGRAM_BASE_URL`.
- Crash output no longer prints local variables, which could include an
API key.
- A project `deepgram.yaml` can no longer set credentials, trusted hosts
or the programs dg runs.

If you used 0.2.21 to 0.4.0, we recommend upgrading to 0.4.1 and
rotating any API key you used with it. If you logged in through your
browser, log in again after upgrading.

### What's fixed

**Credentials and network (deepctl-core, api, login, listen, speak, mcp,
debug-probe)**
- dg sends the API key only to a regional Deepgram API host
(`api.deepgram.com`, `api.eu.deepgram.com`, `api.au.deepgram.com` or
`api.in.deepgram.com`, and only over https on the default port), a host
listed in `api.allowed_hosts` in the user's own config, or
`DEEPGRAM_BASE_URL`. A `DEEPGRAM_BASE_URL` set in an AI agent session
doesn't count. `dg mcp` sends the key to `api.dx.deepgram.com`, or to a
`--base-url` host listed in `api.allowed_hosts`. Device login (`dg
login` without `--api-key`) uses `id.dx.deepgram.com` under the same
rule. Any other host is refused before a request is made.
- REST calls, WebSocket connections (live `dg listen`, `dg speak` with
Flux, `dg debug probe`) and `dg api` no longer follow redirects. Without
this change, a 3xx response could pass the key, audio or text on to
another host.
- `DEEPGRAM_CLI_INSECURE` turns off TLS verification only when it is set
to `1`/`true`, only for localhost, 127.0.0.1 and ::1, and never in an AI
agent session.

**Configuration (deepctl-core)**
- A project `deepgram.yaml` can no longer set credentials, trust
settings or the programs dg runs. Any `--config` file other than the
default `config.yaml` can no longer set trust settings or the programs
dg runs.
- The config file is written owner-only and atomically. It's locked
against concurrent saves. A config that couldn't be read is never
overwritten. Oversized or deeply nested YAML is refused.
- In an AI agent session, dg uses the trust settings in the user config
only from the file at its standard location under the real home
directory, reached without a symlink, with one hard link, owned by the
user and not writable by the group or others. It also doesn't use the
API key from a user config that another user owns or the group or others
can write.

**Plugins (deepctl-core, plugin)**
- A plugin can't replace a built-in command unless the user names it in
`plugins.allow_override`. Plugin command names have to match a strict
pattern.
- `dg plugin search` lists only plugins that Deepgram publishes.
- The plugin folders are created private (0700). In an AI agent session,
dg uses the plugin environment that `dg plugin install` manages only
from the real home directory, reached without a symlink, and skips it if
another user owns its folders or the group or others can write to them.
Plugins installed in dg's own Python environment still load.
- In an AI agent session, dg refuses `dg plugin
install`/`update`/`remove` and `dg ffprobe --path`.

**Local servers and tools (mcp, debug-probe, debug-audio, shared-utils,
ffprobe, init, install scripts)**
- `dg mcp` runs over stdio only. The SSE mode, which had no
authentication, is removed. Streamable HTTP was never supported. The
docs proxy now ships inside `deepctl-cmd-mcp` (vendored from
deepgram-mcp 0.1.1, MIT). It forwards only
`search_deepgram_knowledge_sources` and makes no network connection
until a tool is called.
- `dg debug probe` accepts connections only from native clients and
pages on localhost, 127.0.0.1 or [::1]. Requests from any other origin
get a 403 before the upstream connection opens.
- ffprobe gets its input as `file:<absolute path>`, so a file name that
starts with `-` is never read as an option. ffprobe itself is looked up
from an absolute configured path or from `PATH`, skipping relative
entries.
- `dg init` writes `.env` owner-only, adds it to `.gitignore`, and
clones with `--`.
- When `install.sh` or `install.ps1` has to install uv (no uv, pipx or
pip found), it installs a pinned uv release and checks its installer
against its sha256 before running it.

**Telemetry and crash output (telemetry, root)**
- 0.4.1 sends no telemetry. The Sentry key that 0.2.21 to 0.4.0 shipped
is removed, and there is no built-in destination, so dg sends no error
reports whatever the settings, and doesn't load the Sentry SDK. The
error-report code stays for a later opt-in, rebuilt to send only
allowlisted fields (command path, flag names, versions, OS, frame
locations) with no values; in 0.4.1 it can reach only a loopback
`DEEPCTL_TELEMETRY_DSN`, which exists for tests.
- `dg --help` ends with "This version of dg sends no telemetry." The
README says the same: no error reports, usage data or other telemetry.
dg still contacts the Deepgram API for the commands you run, and
pypi.org to check for updates.
- Crash tracebacks no longer print local variables, which could include
an API key.
- In 0.4.0, `dg login`, `dg projects` and `dg update` could erase a
`telemetry.enabled: false` opt-out, because every config save dropped
the `telemetry` section. 0.4.1 keeps it, so it is still in place if
reporting comes back.

**Other**
- Upgrade hints and `dg update` name the `deepgram` Homebrew formula.
The old hint, `brew upgrade deepctl`, failed.
- dg no longer splits a hyphenated file name into a command: `dg listen
debug-call.wav` used to read the file as `debug call.wav`. Only the
command name itself is expanded (`dg debug-audio` still works).
- `dg --help` and other output no longer crash when stdout or stderr
can't encode a character, as with a redirected or piped Windows console
(cp1252). Characters the stream can't write are escaped instead.
- A config file that can't be looked up (for example a symlink being
replaced, or a folder that can't be searched) is reported as unreadable
instead of crashing dg. It is never trusted or saved over.

### Upgrade notes

| Change | What to do |
|---|---|
| `dg mcp --transport sse` now exits with an error. `--transport
streamable-http` was never supported and still exits with an error. Only
stdio is supported. `--port` and `--host` are still accepted, and
ignored. | Remove `--transport`, `--port` and `--host` from your
editor's MCP config, or set `--transport` to `stdio`. |
| `dg mcp` exposes only `search_deepgram_knowledge_sources` and reads
the API key on each call rather than at startup. | Nothing, unless you
used another remote tool. |
| deepctl no longer depends on `deepgram-mcp`; the docs proxy ships
inside deepctl-cmd-mcp. A pip or pipx upgrade leaves the old
`deepgram-mcp` package and its `deepgram-mcp` command installed (with
pipx, inside deepctl's environment, not on your PATH). `uv tool upgrade
deepctl` removes it. | pip: `pip uninstall deepgram-mcp`. pipx: `pipx
runpip deepctl uninstall deepgram-mcp`. Point editor configs at `dg
mcp`. |
| The API key goes only to `api.deepgram.com`, `api.eu.deepgram.com`,
`api.au.deepgram.com`, `api.in.deepgram.com` (over https on the default
port only), hosts in `api.allowed_hosts`, or `DEEPGRAM_BASE_URL`. A
`DEEPGRAM_BASE_URL` set in an AI agent session doesn't count. `dg mcp`
sends it to `api.dx.deepgram.com` or a host in `api.allowed_hosts`, and
`dg login` without `--api-key` uses `id.dx.deepgram.com` under the same
rule. dg refuses a `--base-url` or profile that points anywhere else. |
For a proxy or self-hosted deployment, add its host (optionally
`host:port`) to `api.allowed_hosts` in your user `config.yaml`. |
| A plain `http://` base URL is refused unless the host is loopback
(localhost, 127.0.0.0/8 or [::1]). A loopback base URL from `--base-url`
or a profile must also be listed in `api.allowed_hosts`. Only
`DEEPGRAM_BASE_URL` is exempt, and not in an AI agent session. | Use
https, or a local server on localhost, 127.0.0.1 or [::1]. For a local
server, add its host to `api.allowed_hosts`, or set `DEEPGRAM_BASE_URL`
outside an AI agent session. |
| A project `deepgram.yaml` is read only for `output.*` settings and a
regional Deepgram `base_url`. Everything else is ignored with a warning:
`api_key`, `project_id`, the active/default profile, other `base_url`s,
and the `api`, `tools`, `telemetry`, `update` and `plugins` sections. |
Move those settings to your user `config.yaml`, or set them with env
vars or flags. |
| Any `--config` file other than the default `config.yaml` loses its
`api`, `tools`, `plugins` and `update` sections, and any non-regional
`base_url`. It can still hold credentials and profiles. | Same as above.
|
| A `--config` path that isn't a regular file (a FIFO, `<(...)` or
`/dev/stdin`) is no longer read. dg warns and runs without it. | Pass a
regular file. |
| In an AI agent session, dg doesn't use the API key or the trust
settings from a user config that another user owns or the group or
others can write. It still reads the file, but drops its API keys and
`dg_token_expires_at`, and handles its `api`, `tools`, `plugins` and
`update` sections and any non-regional `base_url` as it does for a
`--config` file. | `chmod go-w` the file and its folder, or `chown` it
to yourself. |
| In an AI agent session, a user config managed by a dotfile manager
loses its trust settings: a symlinked file or folder on the way from the
real home directory, a file with more than one hard link, or a file
found through `HOME` or `XDG_CONFIG_HOME` instead of the real home. dg
keeps using its API key, but drops `api.allowed_hosts` (the whole `api`
section), `tools`, `plugins`, `update` and any non-regional `base_url`.
| Make the file at the standard location under your real home directory
a regular file with one link, or set those values outside an AI agent
session. |
| `DEEPGRAM_CLI_INSECURE` works only for `1`/`true`, only for
localhost/127.0.0.1/[::1], and never in an AI agent session. | Use it
only against a local dev server. |
| 0.4.1 sends no telemetry. `DEEPCTL_TELEMETRY_DISABLED` and
`telemetry.enabled` are still accepted, and the new `--no-telemetry`
flag is accepted too, but none of them has an effect in this version.
`DEEPCTL_TELEMETRY_DISABLED` now reads any non-empty value except `0`,
`false`, `no` and `off` (in any case) as off; before, only `1`, `true`
and `yes` did. | Nothing. You can leave these settings in place. |
| `DEEPCTL_TELEMETRY_DSN` is honored only for a loopback host, for
tests. Any other value is ignored. There is no built-in destination. The
README section on overriding the destination was removed, and the README
now says the variable is ignored unless it points at the local machine.
| Nothing: 0.4.1 sends no reports, so a fork or self-hosted Sentry gets
none either. |
| Plugin command names must match `^[a-z][a-z0-9-]{0,63}$`. A plugin
can't replace a built-in command: dg runs the built-in and prints a
warning. A plugin whose entry point is named like a built-in command is
skipped before it's imported. | Rename the entry point. To let a trusted
plugin replace one, add the command to `plugins.allow_override` in your
user `config.yaml` (see README, "Plugins"). |
| `dg plugin search` lists only plugins that Deepgram publishes. |
Install third-party plugins by package name. |
| In an AI agent session, dg refuses `dg plugin
install`/`update`/`remove` and `dg ffprobe --path`. | Run them yourself
in a terminal. |
| A configured ffprobe path must be absolute. Relative and
current-directory entries on `PATH` are skipped. | Run `dg ffprobe
--path /absolute/path/to/ffprobe` again if needed. |
| `dg login` no longer saves `--base-url` or `DEEPGRAM_BASE_URL` to the
profile; it prints that the URL was used for this login only. | To save
it, run `dg login --save-base-url` with the URL and confirm at a
terminal. For a non-Deepgram host, this also adds the host to
`api.allowed_hosts`. |
| `dg api` resolves relative paths against the profile's base URL, not
always `api.deepgram.com`. An absolute URL to a host that isn't trusted
is sent without your key. | Pass `--allow-foreign-host=<host>` to
include the key. It must match the request host and is refused in an AI
agent session. |
| REST and WebSocket requests no longer follow redirects. A 3xx response
now fails with an error that names both origins. `dg api` instead prints
a warning that names both origins, then prints the 3xx response. | Use
the final URL directly. |
| `dg debug probe` refuses browser pages that aren't on
localhost/127.0.0.1/[::1] (403). | Serve the page from localhost. |
| The minimum versions rise for `mcp` (1.22), `websockets` in
deepctl-cmd-listen (13.1), `aiohttp` in deepctl-cmd-debug-probe (3.11)
and `sentry-sdk` in deepctl-telemetry (`>=2.35.0,<3`). sentry-sdk stays
a dependency only for a later opt-in; 0.4.1 never imports it unless a
loopback test DSN is set. | Nothing for a normal upgrade. |
| A `ClickException` or `UsageError` raised inside a command is no
longer printed after a "Command failed:" line; only the `Error:` line
remains. Exit codes are unchanged. | Nothing, unless a script matches on
"Command failed:". |
| When `install.sh` or `install.ps1` has to install uv (no uv, pipx or
pip found), it installs uv 0.12.24, checked against a pinned sha256,
instead of the latest uv. The new `DEEPCTL_UV_INSTALLER_URL` variable
points either script at a mirror of the uv installer, which must serve
the same file. | Behind a firewall, set `DEEPCTL_UV_INSTALLER_URL` to a
mirror of uv 0.12.24's installer. |

### Test results

CI on this PR runs the full matrix, Python 3.10 to 3.14 on each OS, with
0 failures:

- Linux: 3,382 passed, 9 skipped.
- macOS: 3,383 passed, 9 skipped.
- Windows: 2,716 passed, 676 skipped. The skipped tests are POSIX-only:
file modes, POSIX paths and config layout, symlinks and fork.
- Lint, types, dependency floors, the build and CodeQL pass.

Sub-package floors on deepctl-core are raised to `>=0.3.1` by hand on
the release PR, because the release sync job
(`check_dependency_floors.py --fix`) only moves the root floors. The
packages that import a deepctl-core API new in 0.3.1 are
deepctl-cmd-api, deepctl-cmd-debug-audio, deepctl-cmd-debug-probe,
deepctl-cmd-ffprobe, deepctl-cmd-init, deepctl-cmd-listen,
deepctl-cmd-login, deepctl-cmd-mcp, deepctl-cmd-plugin,
deepctl-cmd-projects, deepctl-cmd-update and deepctl-telemetry.

### Known follow-ups

- Repin the skills bundle after deepgram/skills drops the SSE guidance.
The pinned bundle (`deepgram-skills-v1.7.0`, also v1.8.0 in #154) still
tells agents to run `dg mcp --transport sse --port 8000`, which now
fails.

🤖 Generated with [Claude Code](https://claude.com/claude-code)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants