* docs: flesh out stub node pages for Global, Start Call, Agent, End Call, QA
Each page was previously a stub (1 sentence or a single <Note>). Now contains:
- Plain-English explanation of what the node does and when it runs
- Fields/configuration reference
- Common mistakes section
- Next Steps with CardGroup links
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* docs: fix heading structure, Warning placement, variable formatting in node pages
- qa.mdx: promote Viewing QA Results from h3 to h2 (was incorrectly nested under Where it sits on the canvas)
- end-call.mdx: move Warning inside Common Mistakes, directly after the bullet it relates to
- start-call/agent/end-call/qa.mdx: wrap bare gathered_context and initial_context in backticks in Card descriptions
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* docs: correct node page errors found by cross-checking against live API + DTO
start-call:
- Fix Node Name description (canvas label, not agent spoken name)
- Split Greeting Text and Prompt into separate documented fields (were conflated)
- Add Delayed Start field (real config option, was missing entirely)
- Fix Common Mistakes (remove wrong Agent Name claim)
- Add Pre-recorded Audio note with link
end-call:
- Remove incorrect <Note> claiming one End Call per workflow
- DTO has no max_instances constraint; llm_hint explicitly says multiple are supported
- Fix Common Mistakes to reflect correct guidance (multiple allowed)
agent:
- Add Extracting variables section documenting extraction_enabled, extraction_prompt,
extraction_variables fields with a concrete example
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* docs: fix field names and QA model against live platform schemas
- qa.mdx: replace fictional criteria-list concept with accurate
qa_system_prompt field; document default output format (tags, score,
sentiment, summary); add sampling/duration/voicemail filter settings
- global.mdx: correct prompt-merge order (global prepended, not appended)
- start-call.mdx: update stale "Greeting Prompt" reference in common
mistakes to match renamed field "Greeting Text"
Verified against live node schemas via Dograh MCP get_node_type.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* docs: fix em dash violations and appended/prepended contradiction
- global.mdx: "silently appended" contradicted "global content first";
changed to "prepended" for internal consistency and schema accuracy
- qa.mdx: remove two em dashes (hard no per style rules)
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* docs: correct node docs against live workflow SDK evidence
- start-call: replace invented fixed edge labels with accurate explanation
that edge labels and conditions are user-defined; add real examples
- end-call: rename "Final Message" to "Prompt" to match SDK field name
used in all real workflows; update all references
- global: add Start Call to Add Global Prompt toggle coverage
(startCall has add_global_prompt: true by default per schema)
- qa: replace informal tag descriptions with actual default tag names
from the qa_system_prompt schema
All changes verified against live Dograh MCP node schemas and
real workflow SDK code (workflow IDs 7764, 8291).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* docs: flesh out all 5 voice agent node pages with accurate UI fields
Complete rewrite of stub docs for global, start-call, agent, end-call,
and qa nodes. Field names, toggle labels, and section headings now match
the actual Dograh UI exactly. Covers all fields visible in each node
edit panel including Allow Interruption, Add Global Prompt, Delayed Start,
Enable Variable Extraction, Pre-Call Data Fetch, and QA settings table.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* docs: remove Allow Interruption from End Call node
End Call does not expose an Allow Interruption toggle in the UI.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* docs: address cubic and greptile review comments on node pages
- agent.mdx, end-call.mdx: remove/correct gathered_context claims -
it is not available in any node's Prompt, only in Webhook payloads
and the run record (confirmed against context-and-variables.mdx)
- global.mdx: fix appended -> prepended in frontmatter description
and Common Mistakes (contradicted How It Works section)
- introduction.mdx: update End Call node-type table - multiple End
Call nodes are supported, not just one
- agent.mdx, end-call.mdx, qa.mdx, start-call.mdx: tag bare code
fences as text for Mintlify syntax highlighting
- global.mdx, start-call.mdx, agent.mdx, end-call.mdx, qa.mdx:
convert absolute internal links to relative paths per style guide
* docs: embed video tutorials on all 5 node pages, fix cubic grammar comment
- Add Video Tutorial section (iframe embed) to global, start-call,
agent, end-call, and qa node pages, matching the pattern already
used in webhook.mdx
- global.mdx: fix "Global Node contain" -> "Global Node contains" in
frontmatter description, per cubic review on 09c5ff31
* docs: fix appended/prepended in introduction.mdx node table
Global node's node-type summary still said the prompt is "appended"
after Add Global Prompt is enabled, contradicting the corrected
"prepended" behavior documented everywhere else. Caught by greptile
P1 review on commit b7fe2d0d.
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
* ViciDial Working
* feat(telephony): add FreeSWITCH provider to upstream-PBX seam
Generalize the upstream-PBX capture and control paths to dispatch by
provider. FreeSWITCH bridges in with X-PBX-* headers and is driven over
the Event Socket Library (uuid_kill / uuid_transfer) by the channel UUID,
alongside the existing VICIdial ra_call_control path.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* add vici specific configs
* feat(telephony): env-based VICIdial config + address3 post-call routing
Move VICIdial agent/non-agent API and FreeSWITCH ESL connection settings
out of hardcoded POC values into environment variables so the same image
works against a PBX on another server.
Add VICIdial update_lead forwarding: X-VICI-UPDATE-LEAD_* extracted
variables are mapped to lead columns and pushed via the non-agent API
before a transfer, with reserved API-control params dropped.
Add hardcoded address3 disposition routing (Y/N -> in-group transfer,
else hang up) and a synchronous final variable extraction so the
transfer path sees the freshest conversation state. Skip upstream_pbx
capture on non-PJSIP channels to avoid Asterisk 500s.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* chore: run formatter
* feat: make vici configurable from UI
* chore: clean up PR
* fix: incorporate review comments
* chore: incorporate review comments
* chore: generate client
* chore: incporporate review comments
* chore: incorporate review comments
---------
Co-authored-by: Dograh POC <payment@dograh.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix(api): validate pagination bounds on run-list endpoints (#553)
GET /workflow/{id}/runs and GET /campaign/{id}/runs declared bare
`page: int = 1` / `limit: int = 50` params, then computed
`total_pages = (total_count + limit - 1) // limit`. A `?limit=0` raised an
unhandled ZeroDivisionError (HTTP 500), and negative limit/page produced a
negative offset and nonsensical pagination.
Add `Query(ge=1, le=100)` / `Query(1, ge=1)` bounds to both endpoints,
matching the sibling list endpoints (/usage/runs and the superuser runs
endpoint) that already validate these. Out-of-range values now return 422.
Adds a regression test covering limit=0/-5/101 and page=0 on both endpoints.
Fixes#553
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
* chore(docs): regenerate openapi.json for run-list pagination bounds (#553)
The added Query(ge/le) bounds on the workflow-run and campaign-run list
endpoints changed the OpenAPI schema; regenerate the committed spec via
`python -m scripts.dump_docs_openapi` so the drift-check passes. Only the
limit/page parameter schemas for those two endpoints change.
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
---------
Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Abhishek Kumar <abhishek@a6k.me>
* feat: add tool test panel for HTTP API tools
Lets developers run a saved HTTP API tool against its real endpoint
from the tool detail page, without needing a live call. Reuses the
production execute_http_tool path so test behavior matches call-time
behavior.
- New POST /tools/{tool_uuid}/test route
- Test panel with per-parameter typed inputs and auto-detected
context variable inputs (from preset parameter templates)
- Validate parameter name uniqueness on save, matching the existing
transferParameters check
- Fix stale FunctionCallsFromLLMInfoFrame import causing test
collection failures against pipecat-ai 1.5.0
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: revert local-venv pipecat drift fix, apply ruff import formatting
test_custom_tools.py and test_unregistered_function_call.py were edited
locally to drop FunctionCallsFromLLMInfoFrame after hitting an
ImportError — that error was from a stale local pipecat-ai package, not
a real drift. CI's pipecat build emits this frame and the test asserted
on it, so removing it broke test_llm_calls_custom_tool_handler and its
unregistered-call counterpart. Reverted both files to match main.
Also applied ruff's import-sort/format fix to test_mcp_tool_route.py to
clear the drift-check job (split the aliased import into its own
`from ... import (...)` block, wrapped a long monkeypatch.setattr call).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: avoid pytest collecting test_tool import as a test, sync OpenAPI spec
pytest's default discovery matches any top-level test_* name in a test
module, including imported functions — importing the route handler as
`test_tool as test_tool_route` still matched the pattern, so pytest
tried to run it as a test and failed injecting fixtures for tool_uuid/
request/user. Renamed the alias to call_test_tool_route.
Also regenerated docs/api-reference/openapi.json for the new
POST /tools/{tool_uuid}/test route and its two schemas (couldn't run
the dump script locally — pipecat-ai version mismatch documented
separately — so hand-built the diff to exactly match FastAPI's
get_openapi() output format, verified against neighboring routes).
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: address cubic review findings on test panel
- Resolve dotted context-variable keys into nested objects before
posting the test request. render_template's get_nested_value walks
nested dicts, so a flat key like "runtime_configuration.realtime_model"
never matched — templates referencing nested context always resolved
to empty.
- Restrict isHttpApiTool to an explicit category equality check instead
of inferring it from exclusions. native/integration tools are
currently disabled in the create-tool UI so this wasn't reachable
today, but the exclusion list silently goes stale as new categories
are added.
- Stop showing a green success badge for non-2xx responses.
execute_http_tool returns status: "success" for any HTTP exchange
that completes, regardless of status code — only transport-level
errors (timeout, connection failure) get status: "error". The test
panel now checks status_code is in the 2xx range before treating the
call as a success.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: address second round of cubic/greptile findings
- Guard setNestedValue against prototype-pollution keys (__proto__,
constructor, prototype) in the dotted context-var path before
traversing.
- Normalize status to "error" in the test route when the upstream
status_code is >= 400. execute_http_tool only distinguishes
transport-level failures (timeout, connection error) from
"success" — a completed 4xx/5xx exchange still came back as
"success" from the executor.
- Seed testArgValues defaults for number/boolean parameters via a
useEffect keyed on the parameters array, so a required number or
boolean field isn't silently omitted from the test request if the
user never touches its input.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: only seed test-arg defaults for required number/boolean params
Seeding optional number/boolean parameters silently changed the test
request — an optional boolean flag the tester never touched was sent
as true, which can flip upstream behavior unintentionally. Restrict
seeding to required parameters.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix: match whitespace and fallback-filter syntax in context var detection
extractContextVars required an exact {{initial_context.foo}} with no
whitespace and no filter suffix, but the backend's TEMPLATE_VAR_PATTERN
(and render_template) accepts {{ initial_context.foo }} and
{{initial_context.foo | fallback:value}}. A preset parameter saved with
either of those forms resolved fine in production but showed no input
in the test panel, so testing always sent it empty context.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(tool-test): add hint and request_* fields to ToolTestResponse
Extends ToolTestResponse with hint, request_method, request_url,
request_body, and request_params so the frontend can surface what was
actually sent and a human-readable hint about why a test call failed.
* feat(tool-test): add status-code hints and request_method/url/body/params to test_tool()
* style: ruff-format test_mcp_tool_route.py
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(tool-test): wire hint banner and request block into result panel
Backend has returned hint/request_method/request_url/request_body/
request_params since d45ea851/60aaf31d but the frontend never
displayed them. Extends ToolTestResult with the new fields and renders
an amber hint banner (for 400/401/403/404/405/408/409/415/422/429/5xx)
plus a Request block above the response showing exactly what was sent.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* fix(tool-test): include resolved preset params in request_body/params
Found via live GET/POST testing: the Request preview showed only the
model-provided arguments, not what execute_http_tool actually sends.
execute_http_tool merges resolved_arguments = {**arguments,
**preset_arguments} before building the outbound body/params — preset
params (e.g. {{initial_context.metadata.channel}}) are invisible to
the model but still go out on the wire. The preview now mirrors that
merge via the same _resolve_preset_parameters helper, so a dev sees
exactly what was sent, not just what the model provided.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(tool-test): add generateSampleValue helper for sample-fill button
* feat(tool-test): add Fill sample values button for arguments and context vars
Moved generateSampleValue out of page.tsx into a sibling helpers module:
Next.js's typed-route checker rejects extra named exports on a page.tsx
file (tsc error TS2344 on .next/types), so the helper and its test import
now live in testPanelHelpers.ts instead.
* feat(tool-test): add JSON edit modal state and handlers
* feat(tool-test): collapsed preview + edit modal for object/array test parameters
* fix(tool-test): validate JSON on modal open, not just on edit
Opening the JSON edit modal on an untouched object/array param (no value
yet in testArgValues) loaded an empty draft with jsonEditError hardcoded
to null, so Save was enabled despite invalid JSON and silently no-op'd on
click. Now runs the same JSON.parse check used by the live textarea
validation when the modal opens.
* chore: regenerate openapi.json for ToolTestResponse hint/request_* fields
drift-check on PR #547 was failing because the earlier hint/request_method/
request_url/request_body/request_params fields added to ToolTestResponse
were never reflected in the dumped spec. Regenerated via
scripts.dump_docs_openapi.
* fix(tool-test): serialize object/array args for GET/DELETE query params, add unsaved-changes banner
httpx raises a TypeError when a query param value is a dict/list, which
was silently caught and surfaced as a generic tool-execution error —
this is what actually broke test requests, not just the "[object
Object]" display. JSON-stringify object/array arguments before they
become query params, in both the live execute_http_tool() path and the
test route's request_params display shaping.
Also adds an unsaved-changes warning banner above Test Tool, shown
when the live form state diverges from the last-saved HTTP API config,
since Test Tool always runs the saved config.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* fix(tool-test): keep empty request body in preview; normalize headers in snapshot
- POST/PUT/PATCH with no arguments now shows `{}` in the request body
preview instead of null — matches what execute_http_tool actually sends
over the wire (json={})
- buildHttpToolTestSnapshot normalizes headers from KeyValueItem[] to a
deduped key→value map before serializing, matching the shape saved to
the backend; duplicate header keys no longer cause a false unsaved-
changes warning
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* test(tool-test): update assertion for empty POST body preview
test_tool_test_no_arguments_leaves_body_and_params_none expected
request_body=None for a POST with no arguments. The fix to preserve {}
in the preview makes request_body={} the correct assertion.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat(tools): refine HTTP tool testing
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Abhishek Kumar <abhishek@a6k.me>
* docs: add video-embedded getting-started pages for API Trigger, Webhook, Telephony, Tools & Knowledge Base
Four new tutorial pages inserted after Your First Agent in 5 Minutes, each
pairing a walkthrough video with a step-by-step practical guide sourced
from the recorded demo: Trigger Calls Automatically (API Trigger), Send
Call Data Back Automatically (Webhook), Connect Your Phone Number
(Twilio telephony), and Give Your Agent Real Data (HTTP tools + KB).
* docs: address greptile review feedback on PR #535
* docs: link Twilio Verified Caller IDs page directly
* Restructure the documents
* docs: embed agent builder walkthrough video on first-agent page
* docs: match link text to renamed Connect with Telephony title
* docs: warn that default outbound telephony config is required for API Trigger
---------
Co-authored-by: Abhishek Kumar <abhishek@a6k.me>
* feat: add ElevenLabs realtime STT provider support (#512)
Wire ElevenLabs scribe_v2_realtime into the STT registry and pipeline factory so BYOK transcribers can use the same provider already supported for TTS.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix: address ElevenLabs STT review feedback for language, commits, and host
Pass custom language codes through instead of defaulting to English, use ElevenLabs VAD commit strategy because Dograh VAD runs downstream of STT, and document hostname-only realtime base_url handling.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix: preserve ElevenLabs STT endpoint port in realtime host parsing
Use urlparse netloc instead of hostname so validated BYOK/proxy base URLs keep non-default ports when Pipecat builds the websocket endpoint.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix: preserve ElevenLabs STT proxy path prefix and remove duplicate tests
Include URL path segments in realtime host normalization for BYOK proxies and delete shadowed pytest definitions.
Co-authored-by: Cursor <cursoragent@cursor.com>
* fix: allow custom ElevenLabs model input
* fix: normalize ElevenLabs websocket URLs
---------
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Abhishek Kumar <abhishek@a6k.me>
* feat(auth): gate OSS signup behind ENABLE_SIGNUP flag
## Problem
The `POST /api/v1/auth/signup` endpoint is unconditionally exposed on
every OSS install. Operators running an invite-only deployment (private
customer instances, staging environments, internal-only tenants) have
no way to disable public account creation without patching the codebase.
The UI also shows the "Sign up" link on `/auth/login` regardless of
whether signup is available, so a locked-down deployment leaves broken
navigation on the login page.
## Fix
Introduce a single `ENABLE_SIGNUP` env var (default `true` — no behavior
change for existing installs) that controls signup end-to-end:
- **Backend** — `api/constants.ENABLE_SIGNUP` is read at module load.
The signup handler returns 403 when it's false. Also exposed on
`GET /api/v1/health` as `signup_enabled: bool` so the UI can mirror
the operator's choice at runtime instead of at bundle-build time.
- **UI** — `getSignupEnabled()` in `lib/auth/config.ts` proxies the
health field, `/api/config/auth` surfaces it to the browser, the
login page conditionally renders the "Sign up" link via a one-shot
`fetch("/api/config/auth")` in `useEffect`, and the middleware
redirects `/auth/signup` → `/auth/login` when disabled (fires before
Next.js can serve the statically-prerendered signup page).
- **Helm** — `config.enableSignup` (default `true`) is rendered into
the ConfigMap as `ENABLE_SIGNUP` so operators can flip it via
`--set config.enableSignup=false` at install/upgrade time.
Fallbacks default to `signupEnabled: true` in every layer so a fresh
install "just works" and matches the backend default.
* address review: rollout on ConfigMap change, cache TTL, no signup-link flash
Four review points on #514:
**P1 — ConfigMap Change Skips Rollout** (`configmap.yaml`). `helm upgrade
--set config.enableSignup=false` updated the ConfigMap but did NOT roll
the api pods, so running processes kept the ENABLE_SIGNUP env from
startup and continued serving the old signup behavior — including
divergence between replicas mid-upgrade.
Fix: add the standard `checksum/config` pod-template annotation on the
four backend Deployments that `envFrom` the ConfigMap (`web`,
`arq-worker`, `ari-manager`, `campaign-orchestrator`). Verified with
`helm template`: all four Deployments share the same checksum on any
given render, and flipping `config.enableSignup` changes the checksum
uniformly so kubectl sees a pod-template diff and rolls all four.
**P1 — Signup Flag Stays Cached (server)** (`ui/src/lib/auth/config.ts`).
Module-scoped cache had no TTL. `revalidate: 300` was passed on the
underlying `fetch()` but the in-memory short-circuit above ran first, so
the value never refreshed until the UI pod restarted.
Fix: add `AUTH_CONFIG_TTL_MS = 5 * 60 * 1000` (matching the fetch
revalidate hint) so the module cache and the Next fetch cache stay in
sync. Backend flag flips propagate within 5 minutes without a pod
restart.
**P1 — Middleware Redirect Uses Stale State** (`ui/src/middleware.ts`).
Same shape as above — a separate module cache with no expiry could keep
redirecting `/auth/signup → /auth/login` after signup was re-enabled, or
keep serving the statically-prerendered signup page after lockdown.
Fix: same `SERVER_CONFIG_TTL_MS = 5 * 60 * 1000` TTL on the middleware
cache.
**P2 — Signup link flash on login page** (`ui/src/app/auth/login/page.tsx`).
Initial `signupEnabled` state was `null`, so `{signupEnabled && ...}`
hid the link on first paint and it popped in after the fetch resolved
— a CLS on every login-page load on stock installs where signup is
enabled.
Fix: initialise the state to `true` (matches the backend default). The
fetch still overrides to `false` when the operator has actually
disabled signup, so the lockdown UI behavior is unchanged; only the
happy-path flash is gone.
* simplify signup flag: drop TTL caches and middleware redirect
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
* resolve signup flag server-side to avoid signup link flicker
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
---------
Co-authored-by: prabhat pankaj <prabhatiitbhu@gmail.com>
Co-authored-by: Abhishek Kumar <abhishek@a6k.me>
Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
* feat(tts): add xAI as a Voice (TTS) provider
pipecat already ships an xAI TTS service (XAITTSService, WebSocket
streaming) but dograh never wired it into the service configuration, so
xAI could not be selected as a Voice provider in the cascading pipeline.
Wire it through:
- registry: ServiceProviders.XAI + XAITTSConfiguration (voices
eve/ara/leo/rex/sal, language, computed model) registered in TTSConfig
- service_factory: build XAITTSService in create_tts_service
- check_validity: api-key validation hook
- tests for the factory + docs
The Voice provider dropdown is schema-driven, so xAI appears with no UI
changes.
* fix(tts): validate xAI API key and drop misleading auto-language hint
Addresses review feedback on the xAI Voice provider:
- check_validity: replace the no-op xAI key check with real validation
against xAI's OpenAI-compatible API (models.list on https://api.x.ai/v1),
so a bad BYOK key is caught at configuration time instead of at call time.
- registry: remove the "auto" language hint from the field description.
pipecat's Language enum has no "auto" member, so the factory fell back to
English silently; the description no longer advertises detection we don't do.
- tests: cover xAI key validation (registered, accepts valid, rejects bad).
* fix(tts): validate xAI key against the TTS voices endpoint
xAI supports endpoint-scoped API keys, so a key scoped to Text-to-Speech
may lack the /v1/models ACL and would be wrongly rejected by the previous
models.list() check. Validate against GET /v1/tts/voices instead — the
scope the key actually needs for TTS — treating 401/403 as an invalid key
and connection errors as a clean, actionable message.
* fix: harden xAI TTS integration
---------
Co-authored-by: Sabiha Khan <sabihak89@gmail.com>
Co-authored-by: Sabiha Khan <87858386+chewwbaka@users.noreply.github.com>
* chore: drain active calls before rolling updates
* Use provisional VAD interruption strategy
* feat: wire provisional VAD configuration
* chore: refactor user turn strategies
* chore: bump pipecat
* feat(twilio): add Answering Machine Detection (AMD) support via telephony config
Closes#339
* chore: regenerate OpenAPI spec to fix drift-check
The openapi.json snapshot had drifted from the FastAPI app definition
because main gained new organization endpoints (billing, credits,
context) after this branch was created. Regenerate it with
'python -m scripts.dump_docs_openapi' to bring it back in sync.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* feat: add provider-level AMD hooks
* fix: handle db error while persisting amd result
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Sabiha Khan <sabihak89@gmail.com>
Co-authored-by: Sabiha Khan <87858386+chewwbaka@users.noreply.github.com>
* feat(scripts): generate REDIS_PASSWORD on setup, plumb through compose
Per the discussion on #453, this takes the recommended path of extending
the setup scripts rather than introducing a parallel compose file.
- scripts/setup_remote.sh now generates REDIS_PASSWORD alongside
OSS_JWT_SECRET and POSTGRES_PASSWORD and writes it to the rendered
.env (with a short comment noting it can be rotated, unlike the
postgres password which is baked into the volume on first init).
- scripts/start_docker.sh now generates REDIS_PASSWORD on first run
if missing, mirroring the existing OSS_JWT_SECRET pattern (reuses
generate_secret, which falls back through python3 → openssl →
/dev/urandom).
- docker-compose.yaml and docker-compose-local.yaml now interpolate
${REDIS_PASSWORD:-redissecret} in the redis --requirepass, the redis
healthcheck, and the api REDIS_URL.
The :-redissecret fallback preserves backwards compatibility for users
with an existing .env that predates this change — they keep the old
value until they regenerate. New installs (via either script) get a
secure random hex.
Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
* Harden local Docker secret setup
---------
Co-authored-by: Claude Opus 4.7 <noreply@anthropic.com>
Co-authored-by: Abhishek Kumar <abhishek@a6k.me>
* update tuner documentation
* docs: update Tuner integration walkthrough video
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
---------
Co-authored-by: mohamed salem <259547077+mohamedsalem-bot@users.noreply.github.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* fix: disable duplicate trigger nodes in workflow builder
AddNodePanel: disable trigger buttons and show tooltip when a trigger
already exists on the canvas, using bySpecName to identify trigger-
category specs from the live node list.
useWorkflowState: preflight in saveWorkflow rejects saves with multiple
trigger nodes via a sonner toast before the network request is made.
text_chat_session_service: include the original exception message in
TextChatSessionExecutionError so the HTTP 500 detail surfaces the root
cause without DB inspection.
Closes#378
* style: format test_text_chat_session_service.py with ruff
* chore: retrigger CI checks
* fix(workflow): enforce node instance constraints
---------
Co-authored-by: Abhishek Kumar <abhishek@a6k.me>
* fix: add language field to CartesiaTTSConfiguration and pass to TTS service
Closes#432
* chore: regenerate OpenAPI spec to fix drift-check
The openapi.json snapshot had drifted from the FastAPI app definition
because main gained new organization endpoints (billing, credits,
context) after this branch was created. Regenerate it with
'python -m scripts.dump_docs_openapi' to bring it back in sync.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
* chore: clarify Cartesia language schema
---------
Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Abhishek Kumar <abhishek@a6k.me>
* docs: design spec for lead-gen surfaces (Credits & Billing, Hire-an-Expert, Top-up, Enterprise)
Add brainstorming spec for: sidebar OBSERVE→MANAGE rename + Credits & Billing
link + Hire-an-Expert footer button; new /billing page with extracted Dograh
Model Credits card + CTAs; Top-up / Hire-an-Expert / Enterprise intake modals
with inline math captcha; and a workflow-builder Hire-an-Expert nudge. Frontend
only; submissions fire PostHog events via a submitLead() seam for a future
MongoDB endpoint. Also gitignore .superpowers/ brainstorm mockups.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* docs: implementation plan for user-onboarding lead-gen surfaces
14 bite-sized tasks: PostHog events, shared helpers (field options,
work-email blocklist, submitLead seam, math captcha), three intake modals
(enterprise/hire/top-up), LeadFormsProvider context, AppLayout mount, sidebar
MANAGE rename + Credits & Billing link + footer Hire button, extracted
DograhCreditsCard, /billing page, credits removal from Agent Runs, builder
nudge, and a full verification/dogfood pass.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(lead-gen): register PostHog events for lead-gen surfaces
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(lead-gen): shared field options, work-email validation, and submit seam
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(lead-gen): inline math captcha field
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(lead-gen): enterprise intake modal
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(lead-gen): hire-an-expert modal with enterprise link
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(lead-gen): top-up modal with >20k volume-pricing gate
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(lead-gen): shared lead-forms context provider
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(lead-gen): mount LeadFormsProvider in app layout
Wrap the sidebar branch of AppLayout with LeadFormsProvider so the shared
lead modals are available to the sidebar, billing card, and builder nudge.
Includes eslint import-order auto-fixes in TopUpModal and LeadFormsContext.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(lead-gen): rename OBSERVE to MANAGE, add Credits & Billing link and Hire-an-Expert footer button
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(lead-gen): extract DograhCreditsCard with top-up + hire CTAs
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(lead-gen): add Credits & Billing page
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* refactor(lead-gen): move Dograh Model Credits card out of Agent Runs to /billing
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(lead-gen): delayed Hire-an-Expert nudge on the workflow builder
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* ci(ui): add lint:lead-flow guard script
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(ui): restructure lead forms, self-serve Buy Credits, dialog blur
Revised lead-capture surfaces and credits bar:
- Dialog overlay gains backdrop blur (bg-black/60 backdrop-blur-sm).
- Shared primitives: LeadModalShell (icon/eyebrow header, scrollable body,
sticky footer, trust-line slot), PhoneField (react-international-phone,
dark, E.164 out), FormTrustLine ("Average response: under 10 minutes...").
- HireExpertModal: Name, Company, Job title, agent goal, Phone (required),
monthly volume. EnterpriseModal: + work email (required logged-out),
conditional deployment (yes/no/maybe, source-gated), agent goal.
OnboardingModal: drop useCase. Phone mandatory except onboarding.
- Volume buckets match the backend qualifier (0-5k/5k-100k/100k+/not-sure).
- Delete TopUpModal; DograhCreditsCard now self-serve Buy Credits (amount
chips $5/$10/$25/$50/$100 + custom min $5 → startTopUp seam) + Hire an
Expert + dashed custom-pricing link opening Enterprise (billing_custom_pricing).
- PostHog events: drop topup_*, add buy_credits_clicked,
buy_credits_amount_selected, custom_pricing_clicked. LeadFormsContext
drops topup; LeadKind/LeadSource updated.
- Introduce a single --cta warm accent token (CTAs + focus rings only).
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat(ui): split-screen auth + enterprise CTA + dark theme default
- AuthShell: dark two-column auth layout (brand/value panel with CSS-only
waveform motif + proof points + Bland-style enterprise CTA block on the
left, zinc-900 form card on the right; single-column on mobile).
- AuthEnterpriseCTA: "Talk to our team" → dograh.com/contact?intent=enterprise.
- stack-theme: dark StackTheme token overrides synced to globals.css.
- page.tsx: wrap StackHandler (non-fullPage) in AuthShell + StackTheme;
local-auth fallback preserved inside the shell. BackButton slimmed for the card.
- Dark locked as default: <html className="dark">, next-themes ThemeProvider
(defaultTheme="dark", enableSystem=false); inline no-FOUC script defaults dark.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* ui rezig, onboarding, billing, hire us & on prem cues
* ui changes
* chore: update comment
* chore: untrack docs/superpowers and gitignore it
* feat: refactor user configuration table
* feat(ui): 'check your email' confirmation on lead forms
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* added email and country in form submissions
* chore: update leads api
* fix: wrap dograh model config in card
---------
Co-authored-by: Pritesh <pritesh@dograh.com>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
* feat: add Smallest AI TTS and STT provider integration
Integrates Smallest AI's Waves (TTS) and Pulse (STT) APIs as selectable
providers in the Dograh platform. Dograh's pipecat fork already contains
the pipecat-level service implementations; this wires them into the API
configuration registry and service factory.
- Added `SMALLEST = "smallest"` to `ServiceProviders` enum
- Registered `SmallestAITTSConfiguration` (lightning-v3.1/v2, voices,
language, speed) and `SmallestAISTTConfiguration` (pulse model, 30+
languages) Pydantic config classes with the TTS/STT registries
- Added factory branches in `create_tts_service` and `create_stt_service`
routing to `SmallestTTSService` and `SmallestSTTService` from pipecat
* fix: update Smallest AI models to v4 naming convention
- TTS: rename lightning-v3.1 → lightning_v3.1, add lightning_v3.1_pro, drop deprecated lightning-v2
- STT: keep pulse only (pulse-pro is not a streaming model)
* fix: change default TTS voice from emily to sophia for lightning_v3.1
emily is not a verified lightning_v3.1 voice; sophia is the pipecat
SmallestTTSService default and confirmed to work with the standard pool.
* fix: replace 9 invalid lightning_v3.1 voice IDs with verified ones
jasmine, james, michael, aria, lara, asel, sarah, rishi, deepika do not
exist in the lightning_v3.1 voice catalog. Replaced with avery, liam,
lucas, olivia, freya, devansh, maya, dhruv, maithili — all verified
against the API.
* fix: smallest ai config validation and tts model compatibility
* chore: ruff fix
* chore: updated smallest ai schema in openapi.json
---------
Co-authored-by: Sabiha Khan <sabihak89@gmail.com>
Co-authored-by: Sabiha Khan <87858386+chewwbaka@users.noreply.github.com>