feat: add Tuner Integration to Dograh (#311)

* Add tuner integration

* bump pipecat version

* chore: update pipecat submodule to match upstream and use tuner-pipecat-sdk 0.2.0

Update pipecat submodule from 0.0.109.dev23 to 13e98d0d9 (the exact commit
upstream dograh-hq/dograh uses after v1.30.1). This installs pipecat-ai as
1.1.0.post277 via setuptools_scm, satisfying tuner-pipecat-sdk 0.2.0's
pipecat-ai>=1.0.0 requirement.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>

* wire tuner

* feat: refactor integrations into self contained packages

* chore: simplify ensure_public_access_token

* fix: remove NodeSpec and make DTOs the source of truth

* feat: send relevant signal to mcp using to_mcp_dict

* fix: fix tests

* cleanup: remove nango integrations

* feat: add agents.md for integrations

---------

Co-authored-by: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-authored-by: Abhishek Kumar <abhishek@a6k.me>
This commit is contained in:
Mohamed-Mamdouh 2026-05-20 10:07:33 +01:00 committed by GitHub
parent afa78fe859
commit 5f28c1b2a9
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
93 changed files with 3388 additions and 3414 deletions

View file

@ -1,6 +1,6 @@
# generated by datamodel-codegen:
# filename: dograh-openapi-XXXXXX.json.VXwJZQpZrH
# timestamp: 2026-05-19T11:05:11+00:00
# filename: dograh-openapi-XXXXXX.json.bGP2QR1Vrx
# timestamp: 2026-05-20T08:41:57+00:00
from __future__ import annotations

View file

@ -127,8 +127,8 @@ def _format_docstring(text: str, indent: int = 4) -> str:
_FILE_HEADER = '''"""GENERATED — do not edit by hand.
Regenerate with `python -m dograh_sdk.codegen` against the target
Dograh backend. Source of truth: each node's NodeSpec in the backend's
`api/services/workflow/node_specs/` directory.
Dograh backend. Source of truth: the backend's model-backed node-spec
catalog served from `/api/v1/node-types`.
"""
from __future__ import annotations

View file

@ -10,6 +10,7 @@ from dograh_sdk.typed.global_node import GlobalNode
from dograh_sdk.typed.qa import Qa
from dograh_sdk.typed.start_call import StartCall
from dograh_sdk.typed.trigger import Trigger
from dograh_sdk.typed.tuner import Tuner
from dograh_sdk.typed.webhook import Webhook
from dograh_sdk.typed._base import TypedNode
@ -20,6 +21,7 @@ __all__ = [
"Qa",
"StartCall",
"Trigger",
"Tuner",
"TypedNode",
"Webhook",
]

View file

@ -1,8 +1,8 @@
"""GENERATED — do not edit by hand.
Regenerate with `python -m dograh_sdk.codegen` against the target
Dograh backend. Source of truth: each node's NodeSpec in the backend's
`api/services/workflow/node_specs/` directory.
Dograh backend. Source of truth: the backend's model-backed node-spec
catalog served from `/api/v1/node-types`.
"""
from __future__ import annotations
@ -16,8 +16,8 @@ from dograh_sdk.typed._base import TypedNode
@dataclass(kw_only=True)
class AgentNode_Extraction_variablesRow:
"""
Each entry declares one variable to capture from the conversation, with
its name, type, and per-variable hint.
Each entry declares one variable to capture, with its name, data type,
and extraction hint.
"""
name: str
@ -70,8 +70,7 @@ class AgentNode(TypedNode):
extraction_enabled: bool = False
"""
When true, runs an LLM extraction pass on transition out of this node to
capture variables from the conversation.
When true, runs an LLM extraction pass for this node.
"""
extraction_prompt: Optional[str] = None
@ -81,8 +80,8 @@ class AgentNode(TypedNode):
extraction_variables: list[AgentNode_Extraction_variablesRow] = field(default_factory=list)
"""
Each entry declares one variable to capture from the conversation, with
its name, type, and per-variable hint.
Each entry declares one variable to capture, with its name, data type,
and extraction hint.
"""
tool_uuids: list[str] = field(default_factory=list)

View file

@ -1,8 +1,8 @@
"""GENERATED — do not edit by hand.
Regenerate with `python -m dograh_sdk.codegen` against the target
Dograh backend. Source of truth: each node's NodeSpec in the backend's
`api/services/workflow/node_specs/` directory.
Dograh backend. Source of truth: the backend's model-backed node-spec
catalog served from `/api/v1/node-types`.
"""
from __future__ import annotations
@ -26,11 +26,11 @@ class EndCall_Extraction_variablesRow:
"""
type: Literal['string', 'number', 'boolean'] = 'string'
"""
The data type of the extracted value.
Data type of the extracted value.
"""
prompt: Optional[str] = None
"""
Per-variable hint describing what to look for in the conversation.
Per-variable hint describing what to look for.
"""
@dataclass(kw_only=True)

View file

@ -1,8 +1,8 @@
"""GENERATED — do not edit by hand.
Regenerate with `python -m dograh_sdk.codegen` against the target
Dograh backend. Source of truth: each node's NodeSpec in the backend's
`api/services/workflow/node_specs/` directory.
Dograh backend. Source of truth: the backend's model-backed node-spec
catalog served from `/api/v1/node-types`.
"""
from __future__ import annotations

View file

@ -1,8 +1,8 @@
"""GENERATED — do not edit by hand.
Regenerate with `python -m dograh_sdk.codegen` against the target
Dograh backend. Source of truth: each node's NodeSpec in the backend's
`api/services/workflow/node_specs/` directory.
Dograh backend. Source of truth: the backend's model-backed node-spec
catalog served from `/api/v1/node-types`.
"""
from __future__ import annotations

View file

@ -1,8 +1,8 @@
"""GENERATED — do not edit by hand.
Regenerate with `python -m dograh_sdk.codegen` against the target
Dograh backend. Source of truth: each node's NodeSpec in the backend's
`api/services/workflow/node_specs/` directory.
Dograh backend. Source of truth: the backend's model-backed node-spec
catalog served from `/api/v1/node-types`.
"""
from __future__ import annotations
@ -17,7 +17,7 @@ from dograh_sdk.typed._base import TypedNode
class StartCall_Extraction_variablesRow:
"""
Each entry declares one variable to capture, with its name, data type,
and per-variable extraction hint.
and extraction hint.
"""
name: str
@ -97,8 +97,7 @@ class StartCall(TypedNode):
extraction_enabled: bool = False
"""
When true, runs an LLM extraction pass on transition out of this node to
capture variables from the opening turn.
When true, runs an LLM extraction pass for this node.
"""
extraction_prompt: Optional[str] = None
@ -109,7 +108,7 @@ class StartCall(TypedNode):
extraction_variables: list[StartCall_Extraction_variablesRow] = field(default_factory=list)
"""
Each entry declares one variable to capture, with its name, data type,
and per-variable extraction hint.
and extraction hint.
"""
tool_uuids: list[str] = field(default_factory=list)

View file

@ -1,8 +1,8 @@
"""GENERATED — do not edit by hand.
Regenerate with `python -m dograh_sdk.codegen` against the target
Dograh backend. Source of truth: each node's NodeSpec in the backend's
`api/services/workflow/node_specs/` directory.
Dograh backend. Source of truth: the backend's model-backed node-spec
catalog served from `/api/v1/node-types`.
"""
from __future__ import annotations

View file

@ -0,0 +1,50 @@
"""GENERATED — do not edit by hand.
Regenerate with `python -m dograh_sdk.codegen` against the target
Dograh backend. Source of truth: the backend's model-backed node-spec
catalog served from `/api/v1/node-types`.
"""
from __future__ import annotations
from dataclasses import dataclass, field
from typing import Any, ClassVar, Literal, Optional
from dograh_sdk.typed._base import TypedNode
@dataclass(kw_only=True)
class Tuner(TypedNode):
"""
Export the completed call to Tuner for Agent Observability LLM hint:
Tuner is a post-call observability export. It does not participate in
the conversation graph and should not be connected to other nodes.
"""
type: ClassVar[str] = 'tuner'
tuner_agent_id: str
"""
The agent identifier registered in your Tuner workspace.
"""
tuner_workspace_id: float
"""
Your numeric Tuner workspace ID.
"""
tuner_api_key: str
"""
Bearer token used when posting completed calls to Tuner.
"""
name: str = 'Tuner'
"""
Short identifier for this Tuner export configuration.
"""
tuner_enabled: bool = True
"""
When false, Dograh skips exporting this call to Tuner.
"""

View file

@ -1,8 +1,8 @@
"""GENERATED — do not edit by hand.
Regenerate with `python -m dograh_sdk.codegen` against the target
Dograh backend. Source of truth: each node's NodeSpec in the backend's
`api/services/workflow/node_specs/` directory.
Dograh backend. Source of truth: the backend's model-backed node-spec
catalog served from `/api/v1/node-types`.
"""
from __future__ import annotations