* 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>
|
||
|---|---|---|
| .agents/skills | ||
| .devcontainer | ||
| .github | ||
| .vscode | ||
| api | ||
| config/coturn | ||
| deploy | ||
| docs | ||
| evals | ||
| examples | ||
| nginx | ||
| pipecat@aadd1d5dd6 | ||
| scripts | ||
| sdk | ||
| ui | ||
| .dockerignore | ||
| .gitignore | ||
| .gitmodules | ||
| .nvmrc | ||
| .python-version | ||
| .release-please-manifest.json | ||
| AGENTS.md | ||
| CHANGELOG.md | ||
| CLAUDE.md | ||
| CONTRIBUTING.md | ||
| docker-compose-local.yaml | ||
| docker-compose.yaml | ||
| LICENSE | ||
| README.ja-JP.md | ||
| README.md | ||
| README.zh-CN.md | ||
| release-please-config.json | ||
| remote_up.sh | ||
| SECURITY.md | ||
Dograh AI
The open-source, self-hostable alternative to Vapi & Retell — build production voice agents with a visual workflow builder, test them in minutes, and let AI coding assistants help design and edit them through MCP.
📖 Docs · 📜 BSD 2-Clause · 🌐 中文 · 🌐 日本語
- 100% open source, self-hostable — no vendor lock-in, unlike Vapi or Retell
- Full control & transparency — every line of code is open, with flexible LLM / TTS / STT integration
- Maintained by YC alumni and exit founders, committed to keeping voice AI open
🎥 Featured
⚖️ Dograh vs Vapi vs Retell
An honest comparison on the axes that matter most to teams evaluating voice AI platforms.
| Dograh | Vapi | Retell | |
|---|---|---|---|
| License | BSD 2-Clause (open source) | Proprietary | Proprietary |
| Self-hostable | ✅ Yes — one Docker command | ❌ SaaS only | ❌ SaaS only |
| Pricing | Free (self-host) · usage-based (cloud) | Per-minute SaaS | Per-minute SaaS |
| Bring your own LLM / STT / TTS | ✅ Any provider, or use Dograh's stack | Configurable within their integrations | Configurable within their integrations |
| Source-level customization | ✅ Every line is yours to modify | ❌ Closed source | ❌ Closed source |
| Data residency | Your infra, your rules | Their cloud | Their cloud |
| Vendor lock-in | None | Full | Full |
🚀 Get Started
Download and setup Dograh on your Local Machine
Note
We collect anonymous usage data to improve the product. You can opt out by setting
ENABLE_TELEMETRY=falsebefore running the startup script.
Note
If you wish to run the platform on a remote server instead, checkout our Documentation
curl -o docker-compose.yaml https://raw.githubusercontent.com/dograh-hq/dograh/main/docker-compose.yaml && curl -o start_docker.sh https://raw.githubusercontent.com/dograh-hq/dograh/main/scripts/start_docker.sh && chmod +x start_docker.sh && ./start_docker.sh
⚡ Prefer an AI agent to set it up for you? If you use Claude Code or Codex, install the official Dograh setup skill and let your agent handle installation, configuration, and troubleshooting — it detects your OS, picks the right deploy path, runs Dograh's own setup scripts, and verifies the result.
# In Claude Code /plugin marketplace add dograh-hq/dograh-plugins /plugin install dograh@dograhThen start a new session and ask it to "set up Dograh" (or run
/dograh-setup). Codex is supported too — see the plugin repo.
Note
First startup may take 2-3 minutes to download all images. Once running, open http://localhost:3010 to create your first AI voice assistant! For common issues and solutions, see 🔧 Troubleshooting.
🎙️ Your First Voice Bot
- Open http://localhost:3010 in your browser.
- Pick Inbound or Outbound, name your bot (e.g. Lead Qualification), and describe the use case in 5–10 words (e.g. Screen insurance form submissions for purchase intent).
- Click Test Agent.
- Use Test Audio to talk to your agent in the browser, or Test Chat to iterate faster in text. In Test Chat, you can edit or replay user turns and Dograh will regenerate the agent's replies and node transitions from that point.
🔑 No API keys needed. Dograh ships with auto-generated keys and its own LLM / TTS / STT stack. Connect your own keys for LLM, TTS, STT, or Telephony (e.g. Twilio, Vonage, Telnyx) anytime.
Build Agents with MCP
Dograh ships with an MCP server, so coding agents can work directly inside your Dograh workspace.
Connect Codex, Claude Code, Cursor, or any MCP client to inspect existing agents, search Dograh docs, fetch node schemas, create new workflows, and save draft edits from natural language.
When asking your coding agent to build a voice agent, share a short script for the use case instead of only a one-line prompt. Include the agent persona, call flow, rules, objection handling, success criteria, and a sample conversation if you have one.
See the MCP guide to connect your assistant.
Features
Voice Agent Builder
- Visual workflow builder with start nodes, agent nodes, global instructions, tools, transitions, and end-call outcomes
- Test Agent panel with Test Audio for browser voice testing and Test Chat for fast prompt iteration
- QA node, knowledge bases, webhooks, embeds, and tool calling for production workflows
Voice & Telephony
- Built-in telephony integrations including Twilio, Vonage, Telnyx, Plivo, Vobiz, Cloudonix, and Asterisk ARI
- Human handoff with call transfer on supported telephony providers
- Bring your own LLM, TTS, STT, and telephony providers; store artifacts in bundled MinIO or AWS/S3-compatible storage
Developer Experience
- One-command Docker setup for self-hosting
- Python backend and modular provider architecture for customization
- Python and Node SDKs for programmatic agent creation and outbound calls
Deployment Options
Local Development
Refer Local Setup
Self-Hosted Deployment
For detailed deployment instructions including remote server setup with HTTPS, see our Docker Deployment Guide.
Cloud Version
Visit https://www.dograh.com for our managed cloud offering.
📚Documentation
You can go to https://docs.dograh.com for our documentation.
📦 SDKs
- Python SDK — pypi.org/project/dograh-sdk
- Node SDK — npmjs.com/package/@dograh/sdk
🤝Community & Support
👋 Coming from the Better Stack video? Drop your use case in our pinned GitHub Discussion — we read every reply and the founders personally onboard early adopters.
- Slack — the cornerstone of Dograh AI contributions. Connect with maintainers, discuss features before coding, get help with setup, and stay current on contribution sprints.
- GitHub Discussions — share use cases, ask questions, swap workflow recipes.
- GitHub Issues — report bugs or request features.
👉 Join us → Dograh Community Slack
🙌 Contributing
We love contributions! Dograh AI is 100% open source and we intend to keep it that way.
Getting Started
- Fork the repository
- Create your feature branch (git checkout -b feature/AmazingFeature)
- Commit your changes (git commit -m 'Add some AmazingFeature')
- Push to the branch (git push origin feature/AmazingFeature)
- Open a Pull Request
⭐ Star History
📄 License
Dograh AI is licensed under the BSD 2-Clause License- the same license as projects that were used in building Dograh AI, ensuring compatibility and freedom to use, modify, and distribute.
🏢 About
Built with ❤️ by Dograh (Zansat Technologies Private Limited) Founded by YC alumni and exit founders committed to keeping voice AI open and accessible to everyone.