Commit graph

301 commits

Author SHA1 Message Date
Abhishek
c76076fb93
feat: show model pricing in configuration UI (#528)
* feat: show model pricing in configuration UI

* fix: display effective pricing rounding policy
2026-07-13 14:20:24 +05:30
Abhishek Kumar
e405457676 fix: fix superadmin impersonation 2026-07-11 15:51:36 +05:30
Sabiha Khan
2801c3156e
Feat/dybamic transfer (#521)
* feat: enable dynamic transfer destination resolution

* fix: remove approved routes, policy and fallback

* fix: review comments
2026-07-10 21:40:26 +05:30
Abhishek Kumar
aa04a41ff3 fix: fix minting correlation from right definition 2026-07-10 17:23:31 +05:30
Abhishek Kumar
43737c67dc fix: scope workflow run to org rather than user 2026-07-10 16:52:43 +05:30
Abhishek
fb4038a969
fix: fix org scoped access for resources (#517)
* fix: fix org scoped access for resources

* Fix auth and config validation regressions

* fix: track org config validation timestamp

* fix: backfill org model configuration v2 from legacy user rows

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* test: align config tests with org-level v2 resolution

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* chore: helm example values tweaks

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 23:04:33 +05:30
Abhishek
041c31a613
fix: increase concurrency limit an handle it across all call paths (#508)
* fix: increase concurrency limit an handle it across all call paths

* fix: fix review comments and test

* fix: address concurrency review findings (campaign-scoped counter, cleanup hardening, webrtc run validation)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat: emit usage_concurrent_call_limit_reached PostHog event

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: align usage event with MPS org-event convention (per-member fan-out)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* feat: cap max_call_duration at 20 min via typed workflow_configurations request

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-09 18:29:01 +05:30
Octopus
c6c3f93d72
Add MiniMax M3 model option (#513)
Expose MiniMax-M3 in the MiniMax model suggestions now that the provider integration supports MiniMax chat models.

Co-authored-by: octo-patch <266937838+octo-patch@users.noreply.github.com>
2026-07-09 10:30:39 +05:30
Komal Vardhan Lolugu
f32395f859
fix(auth): allow invited org members to start workflow runs (#509)
* fix(auth): allow invited org members to start workflow runs

Users invited to an org could not start workflows belonging to that org
because the authorization check compared actor.selected_organization_id
directly against workflow.organization_id. An invited user's selected
org correctly reflects the invited org, but if the Stack Auth token
resolves to a different org id than expected the strict equality fails.

Per api/AGENTS.md: "Whenever you read or write an organization-scoped
field, you must filter or validate by organization_id." The correct
policy is org membership, not selected-org identity.

- Add is_user_member_of_organization() to OrganizationClient; queries
  the organization_users association table directly (no lazy-load risk).
- Replace the identity check in authorize_workflow_run_start() with a
  membership lookup. Deny when actor_user.id is not in the org's member
  set; error_code stays workflow_not_found to avoid leaking existence.
- Update test: rename rejects_actor_from_another_org to
  rejects_actor_not_a_member (reflects actual policy), add positive test
  allows_invited_member that seeds membership and asserts has_quota=True.

Closes #491

* fix(auth): skip membership check for personal workflows (organization_id=None)

When workflow.organization_id is None (personal or legacy workflow with no
org), the membership lookup was still called, producing a SQL IS NULL
comparison that matched nothing and denied the run.

Guard the check so it only runs when the workflow is org-scoped.

Adds a regression test confirming that an actor with a known id can start a
personal workflow without triggering is_user_member_of_organization.

* fix(auth): fail closed on workflow membership lookup errors

---------

Co-authored-by: Abhishek Kumar <abhishek@a6k.me>
2026-07-08 17:59:20 +05:30
Tararais
a2240db45a
feat(tts): add xAI as a Voice (TTS) provider (#476)
* 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>
2026-07-08 09:05:43 +05:30
Abhishek
fdb7f92fcc
chore: cleaup mps v1 billing (#507)
* chore: cleaup mps v1 billing

* chore: remove legacy file upload path

* chore: implement review comments
2026-07-07 18:38:29 +05:30
Sabiha Khan
ac01f7775e
Feat/enhanced timestamped transcript (#501)
* feat: add additional timestamps in call transcript optionally

* fi: timestamp precision to millisec instead of micro

* fix: address enhanced transcript review issues

* fix: non vad user turn timestamp
2026-07-07 14:47:43 +05:30
Abhishek
5a822232da
fix: fix agent stream contract with cloudonix (#504) 2026-07-06 23:58:04 +05:30
Abhishek
7e2750f83f
fix: forward billing-v2 protocol on textchat KB retrieval and node summaries (#503)
Two call sites dropped the MPS billing-v2 protocol, so orgs on model
config v2 got 400 "Service Key uses billing v2" from MPS:

- text_chat_runner built PipecatEngine without embeddings_provider
  (extracted but never passed), so knowledge-base retrieval fell through
  to the plain OpenAI-compatible client instead of DograhEmbeddingService
  and sent no correlation_id/mps_billing_version metadata. Also pass
  endpoint/api_version for Azure BYOK parity with run_pipeline.
- node_summary built its QA LLM without the run's correlation id, unlike
  its sibling call in qa/analysis.py.

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 22:58:53 +05:30
Abhishek
4fb3193eb5
fix: gate OSS email/password auth endpoints outside local auth mode (#500)
* fix: gate OSS email/password auth endpoints outside local auth mode

The /auth signup/login/me routes were mounted unconditionally, so the
SaaS deployment accepted unauthenticated signups that created oss_*
provider-id users (and auto-provisioned MPS service keys) bypassing
Stack Auth entirely.

Gate them with a router-level dependency that 404s when AUTH_PROVIDER
is not "local", rather than conditionally mounting the router, so the
OpenAPI spec and the clients generated from it stay identical across
deployment modes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>

* fix: keep current user route available in stack auth

---------

Co-authored-by: Claude Fable 5 <noreply@anthropic.com>
2026-07-06 22:18:04 +05:30
Sabiha Khan
b3e09be9b0
fix: clean up ARI transferred call legs on participant hangup (#498) 2026-07-06 07:46:56 +05:30
Abhishek
ceb01a16a3
feat: client gen default configurations (#499) 2026-07-04 18:37:50 +05:30
Abhishek
a54ab519b8
chore: refactor file upload mechanism to avoid NFS dependency (#496)
* chore: refactor file upload mechanism to avoid NFS dependency

* add regression test for deregistration of calls

* fix: fix minio upload issue

* fix: make transcript upload async
2026-07-03 20:01:52 +05:30
Abhishek
79a4a3c9f1
chore: improve upon mcp prompts (#494)
* chore: improve upon mcp prompts

* Update api/mcp_server/instructions.py

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

---------

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
2026-07-03 18:14:03 +05:30
Abhishek Kumar
9966940624 feat: add template variable rendering for transfer call destination 2026-07-02 13:36:29 +05:30
Mohamed-Mamdouh
65d46bc313
Implement cost calculator for Tuber (#471)
* Adding cost calculation in tuner for BYOK

* fix

* implement cost calculator for Tuner

* Update api/services/integrations/tuner/completion.py

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

* feat: expose render_options in node spec

* Update api/services/integrations/registry.py

Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>

---------

Co-authored-by: mohamed salem <259547077+mohamedsalem-bot@users.noreply.github.com>
Co-authored-by: cubic-dev-ai[bot] <191113872+cubic-dev-ai[bot]@users.noreply.github.com>
Co-authored-by: Abhishek Kumar <abhishek@a6k.me>
2026-07-02 12:51:14 +05:30
Abhishek
6937e01b49
feat: better interrupt strategies (#479)
* 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
2026-06-30 14:52:17 +05:30
Abhishek
090d042a78
Fix realtime initial greeting handling (#481) 2026-06-29 17:25:42 +05:30
Sabiha Khan
d9800fddd6
feat: support inbound vonage calls (#480)
* feat: support inbound vonage calls

* fix: drift check

* feat: add warning with missing signature secret

* docs: vonage inbound steps

* chore: upgrade pipecat submodule
2026-06-29 16:27:19 +05:30
Abhishek
b192d4ada7
chore: drain active calls before rolling updates (#474)
* chore: drain active calls before rolling updates

* fix: add a devops secret header

* fix: implement PR review
2026-06-29 06:00:31 +05:30
Abhishek Kumar
327ec561d5 feat: add cartesia ink 2 in STT models 2026-06-28 10:22:36 +05:30
Abhishek Kumar
efb25a0cc5 fix: enable knowledge base with Dograh config v2 2026-06-25 22:21:11 +05:30
nuthalapativarun
d675fd1fda
feat(twilio): add Answering Machine Detection (AMD) support via telephony config (#443)
* 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>
2026-06-25 14:45:13 +05:30
Abhishek
29c5be298c
chore: refactor status processor (#465)
* chore: refactor status processor

* fix: fix billing duration when billsec is None for Cloudonix
2026-06-24 22:07:35 +05:30
Haoqian
d817d50056
fix: support Gemini JSON schema tools (#463)
* fix: support Gemini JSON schema tools

* fix: harden Dograh Gemini adapter wiring

* fix: route Gemini Live tool schemas through parameters_json_schema

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Abhishek Kumar <abhishek@a6k.me>
Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-24 18:50:44 +05:30
Abhishek Kumar
978fb9c262 fix: pass s3 compose settings into storage 2026-06-24 18:37:20 +05:30
Sky Moore
1e2a276a61
feat: support other s3 sig versions so it works with s3 (#461) 2026-06-24 18:36:34 +05:30
Abhishek Kumar
811b9e9803 fix: chat serialization and deserialization in text runner
Related Issue: #455
2026-06-24 17:53:54 +05:30
Abhishek Kumar
1e5e556a4d fix: remove gemini 2.0 flash from supported models 2026-06-24 13:33:18 +05:30
Abhishek Kumar
ca598933ef feat: support flux for dograh multi 2026-06-24 12:45:07 +05:30
Abhishek Kumar
0956157029 feat: add voice selector for Dograh model configs 2026-06-23 18:33:04 +05:30
Abhishek Kumar
8006d0edcd chore: fix dograh v2 speed option 2026-06-19 21:24:48 +05:30
Abhishek Kumar
c554256db1 chore: fix phantom user creation in posthog 2026-06-19 21:08:09 +05:30
Abhishek Kumar
a67c984e1a feat: sync groups in posthog 2026-06-19 20:37:06 +05:30
Abhishek Kumar
eb0b807a38 fix: send correlation ID in QA analysis 2026-06-19 18:54:55 +05:30
Abhishek Kumar
da4a8a005a chore: update documentation 2026-06-19 18:11:35 +05:30
nuthalapativarun
7d053320df
fix: disable duplicate trigger nodes in workflow builder (#402)
* 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>
2026-06-19 15:59:30 +05:30
Mubashir R
6e194f4b59
fix(qa): tolerate non-dict JSON from QA LLM instead of crashing (#408)
* fix(qa): tolerate non-dict JSON from QA LLM instead of crashing

parse_llm_json is explicitly designed to return a list when the model emits a
top-level JSON array (it has a dedicated test for that). The QA analyzers then
call parsed.get("tags", ...) directly on the result. When parsed is a list,
that raises AttributeError, which is NOT caught by the surrounding
except (json.JSONDecodeError, ValueError) — so a single stray array response
from the QA model crashed the entire QA analysis run instead of degrading to
empty results.

The live variable-extraction path already guards this exact case with an
isinstance(..., dict) check; mirror it in both QA analysis call sites
(_run_qa_analysis per-node and _run_whole_call_qa_analysis fallback) so a
non-dict parse result coerces to {} and the run produces empty defaults.

Adds a regression test that drives the whole-call analyzer with an array
response and asserts empty results rather than a crash.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

* fix(qa): log non-object QA JSON responses

---------

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Co-authored-by: Abhishek Kumar <abhishek@a6k.me>
2026-06-19 14:10:53 +05:30
Mubashir R
ed06de73a3
fix(workflow): detect duplicate trigger paths when first node has no id (#409)
validate_trigger_paths used seen_paths.get(trigger_path) and treated a None
result as "path not seen yet". But None is also what node.get("id") returns
for a node without an id, so when the first trigger node sharing a path had no
id, it was stored as None and every later node with the same path was silently
accepted as unique — duplicate trigger paths slipped through validation.

Use a membership test (trigger_path not in seen_paths) so "first occurrence"
and "node_id happens to be None" are no longer conflated. Behavior is
unchanged for nodes that have ids.

Adds a regression test that fails before and passes after.

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
2026-06-19 13:53:34 +05:30
Manasseh
fc37d5058f
feat: add Inworld TTS provider support (#420)
* Add Inworld TTS provider integration

* chore: move from HTTP Service to Websocket Service

---------

Co-authored-by: Abhishek Kumar <abhishek@a6k.me>
2026-06-19 13:23:27 +05:30
Harshita Jain
bec8a23dfb
fix: sync Smallest AI voice dropdown with selected model (#451)
Add model_options to SmallestAITTSConfiguration's voice field so the UI
renders the correct voice list per model — 15 standard voices for
lightning_v3.1 and 6 premium voices (meher, rhea, aviraj, cressida,
willow, maverick) for lightning_v3.1_pro. All 21 voice IDs verified
against the Smallest AI API. The frontend's existing model_options
machinery already handles dropdown filtering and auto-reset on model
change, so no UI changes are needed.
2026-06-18 14:36:08 +05:30
nuthalapativarun
788ff94cec
fix: add language field to CartesiaTTSConfiguration and pass to Cartesia TTS service (#442)
* 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>
2026-06-18 13:23:27 +05:30
Sabiha Khan
951e73a645
feat: add custom sarvam tts voice (#449)
* feat: add custom sarvam tts voice

* chore: refactor registry and add deepgram multi

---------

Co-authored-by: Abhishek Kumar <abhishek@a6k.me>
2026-06-18 12:33:21 +05:30
Abhishek Kumar
344c8220de chore: bump pipecat submodule to 1.4.0 2026-06-18 12:17:36 +05:30
Abhishek
d2cda85b78
fix: validate workflow status filter to prevent 500 on invalid enum value (#450)
* Validate workflow status filter to prevent 500 on invalid enum value

The /workflow/fetch and /workflow/summary endpoints accepted a free-form
status query param and passed it straight into a query that casts to the
workflow_status PG enum (active/archived). Any other value — e.g. an
external caller passing 'published' (a workflow_definitions version state,
not a workflow status) — failed deep in Postgres as
InvalidTextRepresentationError, surfacing as an unhandled HTTP 500.

Add _validate_status_filter() to reject values outside WorkflowStatus with
a clean 422 before any DB query, for both the single and comma-separated
paths. Add route tests covering invalid, valid-single, comma-separated, and
mixed valid/invalid cases.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>

* chore: add tests

---------

Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
2026-06-18 08:39:59 +05:30