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

@ -127,8 +127,8 @@ function renderSpecFile(spec: NodeSpec): string {
const header = `// GENERATED — do not edit by hand.
//
// Regenerate with \`npm run codegen\` against the target Dograh backend.
// Source of truth: each node's NodeSpec in the backend's
// \`api/services/workflow/node_specs/\` directory.
// Source of truth: the backend's model-backed node-spec catalog served
// from \`/api/v1/node-types\`.
`;
const nested: string[] = [];

View file

@ -1,11 +1,11 @@
// GENERATED — do not edit by hand.
//
// Regenerate with `npm run codegen` against the target Dograh backend.
// Source of truth: each node's NodeSpec in the backend's
// `api/services/workflow/node_specs/` directory.
// Source of truth: the backend's model-backed node-spec catalog served
// from `/api/v1/node-types`.
/**
* 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.
*/
export interface AgentNodeExtraction_variablesRow {
/**
@ -46,7 +46,7 @@ export interface AgentNode {
*/
add_global_prompt?: boolean;
/**
* 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_enabled?: boolean;
/**
@ -54,7 +54,7 @@ export interface AgentNode {
*/
extraction_prompt?: string;
/**
* 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.
*/
extraction_variables?: Array<AgentNodeExtraction_variablesRow>;
/**

View file

@ -1,8 +1,8 @@
// GENERATED — do not edit by hand.
//
// Regenerate with `npm run codegen` against the target Dograh backend.
// Source of truth: each node's NodeSpec in the backend's
// `api/services/workflow/node_specs/` directory.
// Source of truth: the backend's model-backed node-spec catalog served
// from `/api/v1/node-types`.
/**
* Each entry declares one variable to capture from the conversation, with its name, data type, and a per-variable extraction hint.
@ -13,11 +13,11 @@ export interface EndCallExtraction_variablesRow {
*/
name: string;
/**
* The data type of the extracted value.
* Data type of the extracted value.
*/
type: "string" | "number" | "boolean";
/**
* Per-variable hint describing what to look for in the conversation.
* Per-variable hint describing what to look for.
*/
prompt?: string;
}

View file

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

View file

@ -9,6 +9,7 @@ export { type GlobalNode, globalNode } from "./global-node.js";
export { type Qa, qa } from "./qa.js";
export { type StartCall, startCall } from "./start-call.js";
export { type Trigger, trigger } from "./trigger.js";
export { type Tuner, tuner } from "./tuner.js";
export { type Webhook, webhook } from "./webhook.js";
import type {
@ -18,8 +19,9 @@ import type {
Qa,
StartCall,
Trigger,
Tuner,
Webhook,
} from "./index.js";
/** Discriminated union of every generated typed node. */
export type TypedNode = AgentNode | EndCall | GlobalNode | Qa | StartCall | Trigger | Webhook;
export type TypedNode = AgentNode | EndCall | GlobalNode | Qa | StartCall | Trigger | Tuner | Webhook;

View file

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

View file

@ -1,11 +1,11 @@
// GENERATED — do not edit by hand.
//
// Regenerate with `npm run codegen` against the target Dograh backend.
// Source of truth: each node's NodeSpec in the backend's
// `api/services/workflow/node_specs/` directory.
// Source of truth: the backend's model-backed node-spec catalog served
// from `/api/v1/node-types`.
/**
* Each entry declares one variable to capture, with its name, data type, and per-variable extraction hint.
* Each entry declares one variable to capture, with its name, data type, and extraction hint.
*/
export interface StartCallExtraction_variablesRow {
/**
@ -68,7 +68,7 @@ export interface StartCall {
*/
delayed_start_duration?: number;
/**
* 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_enabled?: boolean;
/**
@ -76,7 +76,7 @@ export interface StartCall {
*/
extraction_prompt?: string;
/**
* Each entry declares one variable to capture, with its name, data type, and per-variable extraction hint.
* Each entry declares one variable to capture, with its name, data type, and extraction hint.
*/
extraction_variables?: Array<StartCallExtraction_variablesRow>;
/**

View file

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

View file

@ -0,0 +1,40 @@
// GENERATED — do not edit by hand.
//
// Regenerate with `npm run codegen` against the target Dograh backend.
// Source of truth: the backend's model-backed node-spec catalog served
// from `/api/v1/node-types`.
/**
* 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.
*/
export interface Tuner {
type: "tuner";
/**
* Short identifier for this Tuner export configuration.
*/
name?: string;
/**
* When false, Dograh skips exporting this call to Tuner.
*/
tuner_enabled?: boolean;
/**
* The agent identifier registered in your Tuner workspace.
*/
tuner_agent_id: string;
/**
* Your numeric Tuner workspace ID.
*/
tuner_workspace_id: number;
/**
* Bearer token used when posting completed calls to Tuner.
*/
tuner_api_key: string;
}
/** Factory — sets `type` for you so you don't repeat the discriminator. */
export function tuner(input: Omit<Tuner, "type">): Tuner {
return { type: "tuner", ...input };
}

View file

@ -1,8 +1,8 @@
// GENERATED — do not edit by hand.
//
// Regenerate with `npm run codegen` against the target Dograh backend.
// Source of truth: each node's NodeSpec in the backend's
// `api/services/workflow/node_specs/` directory.
// Source of truth: the backend's model-backed node-spec catalog served
// from `/api/v1/node-types`.
/**
* Additional HTTP headers to include with the request.