2026-04-21 07:56:16 +05:30
|
|
|
# generated by datamodel-codegen:
|
feat: UI refresh and user onboarding (#430)
* 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>
2026-06-17 19:49:33 +05:30
|
|
|
# filename: dograh-openapi-XXXXXX.json.lMzKvoOMbD
|
|
|
|
|
# timestamp: 2026-06-17T13:44:53+00:00
|
2026-04-21 07:56:16 +05:30
|
|
|
|
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
|
|
from enum import Enum
|
2026-05-31 16:50:44 +05:30
|
|
|
from typing import Annotated, Any, Literal
|
2026-04-21 07:56:16 +05:30
|
|
|
|
2026-05-31 16:50:44 +05:30
|
|
|
from pydantic import AwareDatetime, BaseModel, ConfigDict, Field, RootModel
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class CalculatorToolDefinition(BaseModel):
|
|
|
|
|
"""
|
|
|
|
|
Tool definition for Calculator tools.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
schema_version: Annotated[int | None, Field(title='Schema Version')] = 1
|
|
|
|
|
"""
|
|
|
|
|
Schema version.
|
|
|
|
|
"""
|
|
|
|
|
type: Annotated[Literal['calculator'], Field(title='Type')]
|
|
|
|
|
"""
|
|
|
|
|
Tool type.
|
|
|
|
|
"""
|
2026-04-21 07:56:16 +05:30
|
|
|
|
|
|
|
|
|
|
|
|
|
class CallDispositionCodes(BaseModel):
|
|
|
|
|
disposition_codes: Annotated[list[str] | None, Field(title='Disposition Codes')] = (
|
|
|
|
|
[]
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
|
2026-05-31 16:50:44 +05:30
|
|
|
class Category(Enum):
|
|
|
|
|
"""
|
|
|
|
|
Tool category. Must match definition.type.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
http_api = 'http_api'
|
|
|
|
|
end_call = 'end_call'
|
|
|
|
|
transfer_call = 'transfer_call'
|
|
|
|
|
calculator = 'calculator'
|
|
|
|
|
native = 'native'
|
|
|
|
|
integration = 'integration'
|
|
|
|
|
mcp = 'mcp'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class Icon(RootModel[str]):
|
|
|
|
|
root: Annotated[str, Field(max_length=50, title='Icon')] = 'globe'
|
|
|
|
|
"""
|
|
|
|
|
Lucide icon identifier.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class IconColor(RootModel[str]):
|
|
|
|
|
root: Annotated[str, Field(max_length=7, title='Icon Color')] = '#3B82F6'
|
|
|
|
|
"""
|
|
|
|
|
Hex color for the tool icon.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
2026-04-24 14:09:24 +05:30
|
|
|
class CreateWorkflowRequest(BaseModel):
|
|
|
|
|
name: Annotated[str, Field(title='Name')]
|
|
|
|
|
workflow_definition: Annotated[dict[str, Any], Field(title='Workflow Definition')]
|
|
|
|
|
|
|
|
|
|
|
2026-04-21 07:56:16 +05:30
|
|
|
class CreatedByResponse(BaseModel):
|
|
|
|
|
"""
|
|
|
|
|
Response schema for the user who created a tool.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
id: Annotated[int, Field(title='Id')]
|
|
|
|
|
provider_id: Annotated[str, Field(title='Provider Id')]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class CredentialResponse(BaseModel):
|
|
|
|
|
"""
|
|
|
|
|
Response schema for a webhook credential (never includes sensitive data).
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
uuid: Annotated[str, Field(title='Uuid')]
|
|
|
|
|
name: Annotated[str, Field(title='Name')]
|
|
|
|
|
description: Annotated[str | None, Field(title='Description')]
|
|
|
|
|
credential_type: Annotated[str, Field(title='Credential Type')]
|
|
|
|
|
created_at: Annotated[AwareDatetime, Field(title='Created At')]
|
|
|
|
|
updated_at: Annotated[AwareDatetime | None, Field(title='Updated At')]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class DisplayOptions(BaseModel):
|
|
|
|
|
"""
|
|
|
|
|
Conditional visibility rules.
|
|
|
|
|
|
|
|
|
|
`show` keys are AND-combined: this property is visible only when EVERY
|
|
|
|
|
referenced field's value matches one of the listed values.
|
|
|
|
|
|
|
|
|
|
`hide` keys are OR-combined: this property is hidden when ANY referenced
|
|
|
|
|
field's value matches one of the listed values.
|
|
|
|
|
|
|
|
|
|
Example:
|
|
|
|
|
DisplayOptions(show={"extraction_enabled": [True]})
|
|
|
|
|
DisplayOptions(show={"greeting_type": ["audio"]})
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
model_config = ConfigDict(
|
|
|
|
|
extra='forbid',
|
|
|
|
|
)
|
|
|
|
|
show: Annotated[dict[str, list[Any]] | None, Field(title='Show')] = None
|
|
|
|
|
hide: Annotated[dict[str, list[Any]] | None, Field(title='Hide')] = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class DocumentResponseSchema(BaseModel):
|
|
|
|
|
"""
|
|
|
|
|
Response schema for document metadata.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
id: Annotated[int, Field(title='Id')]
|
|
|
|
|
document_uuid: Annotated[str, Field(title='Document Uuid')]
|
|
|
|
|
filename: Annotated[str, Field(title='Filename')]
|
|
|
|
|
file_size_bytes: Annotated[int, Field(title='File Size Bytes')]
|
|
|
|
|
file_hash: Annotated[str, Field(title='File Hash')]
|
|
|
|
|
mime_type: Annotated[str, Field(title='Mime Type')]
|
|
|
|
|
processing_status: Annotated[str, Field(title='Processing Status')]
|
|
|
|
|
processing_error: Annotated[str | None, Field(title='Processing Error')] = None
|
|
|
|
|
total_chunks: Annotated[int, Field(title='Total Chunks')]
|
|
|
|
|
retrieval_mode: Annotated[str | None, Field(title='Retrieval Mode')] = 'chunked'
|
|
|
|
|
custom_metadata: Annotated[dict[str, Any], Field(title='Custom Metadata')]
|
|
|
|
|
docling_metadata: Annotated[dict[str, Any], Field(title='Docling Metadata')]
|
|
|
|
|
source_url: Annotated[str | None, Field(title='Source Url')] = None
|
|
|
|
|
created_at: Annotated[AwareDatetime, Field(title='Created At')]
|
|
|
|
|
updated_at: Annotated[AwareDatetime, Field(title='Updated At')]
|
|
|
|
|
organization_id: Annotated[int, Field(title='Organization Id')]
|
|
|
|
|
created_by: Annotated[int, Field(title='Created By')]
|
|
|
|
|
is_active: Annotated[bool, Field(title='Is Active')]
|
|
|
|
|
|
|
|
|
|
|
2026-05-31 16:50:44 +05:30
|
|
|
class MessageType(Enum):
|
|
|
|
|
"""
|
|
|
|
|
Type of goodbye message.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
none = 'none'
|
|
|
|
|
custom = 'custom'
|
|
|
|
|
audio = 'audio'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class EndCallConfig(BaseModel):
|
|
|
|
|
"""
|
|
|
|
|
Configuration for End Call tools.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
messageType: Annotated[MessageType | None, Field(title='Messagetype')] = 'none'
|
|
|
|
|
"""
|
|
|
|
|
Type of goodbye message.
|
|
|
|
|
"""
|
|
|
|
|
customMessage: Annotated[str | None, Field(title='Custommessage')] = None
|
|
|
|
|
"""
|
|
|
|
|
Custom message to play before ending the call.
|
|
|
|
|
"""
|
|
|
|
|
audioRecordingId: Annotated[str | None, Field(title='Audiorecordingid')] = None
|
|
|
|
|
"""
|
|
|
|
|
Recording ID for audio goodbye message.
|
|
|
|
|
"""
|
|
|
|
|
endCallReason: Annotated[bool | None, Field(title='Endcallreason')] = False
|
|
|
|
|
"""
|
|
|
|
|
When enabled, the model must provide a reason for ending the call. The reason is set as call disposition and added to call tags.
|
|
|
|
|
"""
|
|
|
|
|
endCallReasonDescription: Annotated[
|
|
|
|
|
str | None, Field(title='Endcallreasondescription')
|
|
|
|
|
] = None
|
|
|
|
|
"""
|
|
|
|
|
Description shown to the model for the reason parameter. Used only when endCallReason is enabled.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class EndCallToolDefinition(BaseModel):
|
|
|
|
|
"""
|
|
|
|
|
Tool definition for End Call tools.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
schema_version: Annotated[int | None, Field(title='Schema Version')] = 1
|
|
|
|
|
"""
|
|
|
|
|
Schema version.
|
|
|
|
|
"""
|
|
|
|
|
type: Annotated[Literal['end_call'], Field(title='Type')]
|
|
|
|
|
"""
|
|
|
|
|
Tool type.
|
|
|
|
|
"""
|
|
|
|
|
config: EndCallConfig
|
|
|
|
|
"""
|
|
|
|
|
End Call configuration.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
2026-04-21 07:56:16 +05:30
|
|
|
class GraphConstraints(BaseModel):
|
|
|
|
|
"""
|
|
|
|
|
Per-node-type graph rules. WorkflowGraph enforces these at validation.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
model_config = ConfigDict(
|
|
|
|
|
extra='forbid',
|
|
|
|
|
)
|
|
|
|
|
min_incoming: Annotated[int | None, Field(title='Min Incoming')] = None
|
|
|
|
|
max_incoming: Annotated[int | None, Field(title='Max Incoming')] = None
|
|
|
|
|
min_outgoing: Annotated[int | None, Field(title='Min Outgoing')] = None
|
|
|
|
|
max_outgoing: Annotated[int | None, Field(title='Max Outgoing')] = None
|
|
|
|
|
|
|
|
|
|
|
2026-05-31 16:50:44 +05:30
|
|
|
class Method(Enum):
|
|
|
|
|
"""
|
|
|
|
|
HTTP method to use for the request.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
GET = 'GET'
|
|
|
|
|
POST = 'POST'
|
|
|
|
|
PUT = 'PUT'
|
|
|
|
|
PATCH = 'PATCH'
|
|
|
|
|
DELETE = 'DELETE'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TimeoutMs(RootModel[int]):
|
|
|
|
|
root: Annotated[int, Field(ge=1, title='Timeout Ms')] = 5000
|
|
|
|
|
"""
|
|
|
|
|
Request timeout in milliseconds.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class CustomMessageType(Enum):
|
|
|
|
|
"""
|
|
|
|
|
Type of custom message.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
text = 'text'
|
|
|
|
|
audio = 'audio'
|
|
|
|
|
|
|
|
|
|
|
2026-04-21 07:56:16 +05:30
|
|
|
class InitiateCallRequest(BaseModel):
|
|
|
|
|
workflow_id: Annotated[int, Field(title='Workflow Id')]
|
|
|
|
|
workflow_run_id: Annotated[int | None, Field(title='Workflow Run Id')] = None
|
|
|
|
|
phone_number: Annotated[str | None, Field(title='Phone Number')] = None
|
2026-05-02 16:59:17 +05:30
|
|
|
telephony_configuration_id: Annotated[
|
|
|
|
|
int | None, Field(title='Telephony Configuration Id')
|
|
|
|
|
] = None
|
2026-05-08 14:48:53 +05:30
|
|
|
from_phone_number_id: Annotated[int | None, Field(title='From Phone Number Id')] = (
|
|
|
|
|
None
|
|
|
|
|
)
|
2026-04-21 07:56:16 +05:30
|
|
|
|
|
|
|
|
|
2026-05-31 16:50:44 +05:30
|
|
|
class McpToolConfig(BaseModel):
|
|
|
|
|
"""
|
|
|
|
|
Configuration for a customer MCP server tool definition.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
transport: Annotated[Literal['streamable_http'], Field(title='Transport')] = (
|
|
|
|
|
'streamable_http'
|
|
|
|
|
)
|
|
|
|
|
"""
|
|
|
|
|
MCP transport protocol.
|
|
|
|
|
"""
|
|
|
|
|
url: Annotated[str, Field(title='Url')]
|
|
|
|
|
"""
|
|
|
|
|
MCP server URL. Must use http:// or https://.
|
|
|
|
|
"""
|
|
|
|
|
credential_uuid: Annotated[str | None, Field(title='Credential Uuid')] = None
|
|
|
|
|
"""
|
|
|
|
|
Reference to an external credential for MCP server auth.
|
|
|
|
|
"""
|
|
|
|
|
tools_filter: Annotated[list[str] | None, Field(title='Tools Filter')] = None
|
|
|
|
|
"""
|
|
|
|
|
Allowlist of MCP tool names to expose. Empty exposes all tools.
|
|
|
|
|
"""
|
|
|
|
|
timeout_secs: Annotated[int | None, Field(ge=0, title='Timeout Secs')] = 30
|
|
|
|
|
"""
|
|
|
|
|
Connection timeout in seconds.
|
|
|
|
|
"""
|
|
|
|
|
sse_read_timeout_secs: Annotated[
|
|
|
|
|
int | None, Field(ge=0, title='Sse Read Timeout Secs')
|
|
|
|
|
] = 300
|
|
|
|
|
"""
|
|
|
|
|
SSE read timeout in seconds.
|
|
|
|
|
"""
|
|
|
|
|
discovered_tools: Annotated[
|
|
|
|
|
list[dict[str, Any]] | None, Field(title='Discovered Tools')
|
|
|
|
|
] = None
|
|
|
|
|
"""
|
|
|
|
|
Server-managed cache of the MCP server's tool catalog [{name, description}]. Populated best-effort by the backend.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class McpToolDefinition(BaseModel):
|
|
|
|
|
"""
|
|
|
|
|
Persisted MCP tool definition.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
schema_version: Annotated[int | None, Field(title='Schema Version')] = 1
|
|
|
|
|
"""
|
|
|
|
|
Schema version.
|
|
|
|
|
"""
|
|
|
|
|
type: Annotated[Literal['mcp'], Field(title='Type')]
|
|
|
|
|
"""
|
|
|
|
|
Tool type.
|
|
|
|
|
"""
|
|
|
|
|
config: McpToolConfig
|
|
|
|
|
"""
|
|
|
|
|
MCP server configuration.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
2026-04-21 07:56:16 +05:30
|
|
|
class NodeCategory(Enum):
|
|
|
|
|
"""
|
|
|
|
|
Drives grouping in the AddNodePanel UI.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
call_node = 'call_node'
|
|
|
|
|
global_node = 'global_node'
|
|
|
|
|
trigger = 'trigger'
|
|
|
|
|
integration = 'integration'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class NodeExample(BaseModel):
|
|
|
|
|
"""
|
|
|
|
|
A worked example LLMs can pattern-match. Keep small and realistic.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
model_config = ConfigDict(
|
|
|
|
|
extra='forbid',
|
|
|
|
|
)
|
|
|
|
|
name: Annotated[str, Field(title='Name')]
|
|
|
|
|
description: Annotated[str | None, Field(title='Description')] = None
|
|
|
|
|
data: Annotated[dict[str, Any], Field(title='Data')]
|
|
|
|
|
|
|
|
|
|
|
2026-05-31 16:50:44 +05:30
|
|
|
class Type(Enum):
|
|
|
|
|
"""
|
|
|
|
|
JSON type for the resolved value.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
string = 'string'
|
|
|
|
|
number = 'number'
|
|
|
|
|
boolean = 'boolean'
|
2026-06-01 23:05:38 -07:00
|
|
|
object = 'object'
|
|
|
|
|
array = 'array'
|
2026-05-31 16:50:44 +05:30
|
|
|
|
|
|
|
|
|
|
|
|
|
class PresetToolParameter(BaseModel):
|
|
|
|
|
"""
|
|
|
|
|
A parameter injected by Dograh at runtime.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
name: Annotated[str, Field(title='Name')]
|
|
|
|
|
"""
|
|
|
|
|
Parameter name used as a key in the request body.
|
|
|
|
|
"""
|
|
|
|
|
type: Annotated[Type, Field(title='Type')]
|
|
|
|
|
"""
|
|
|
|
|
JSON type for the resolved value.
|
|
|
|
|
"""
|
|
|
|
|
value_template: Annotated[str, Field(title='Value Template')]
|
|
|
|
|
"""
|
|
|
|
|
Fixed value or template, e.g. {{initial_context.phone_number}}.
|
|
|
|
|
"""
|
|
|
|
|
required: Annotated[bool | None, Field(title='Required')] = True
|
|
|
|
|
"""
|
|
|
|
|
Whether the parameter must resolve to a non-empty value.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
2026-04-21 07:56:16 +05:30
|
|
|
class PropertyOption(BaseModel):
|
|
|
|
|
"""
|
|
|
|
|
An option in an `options` or `multi_options` dropdown.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
model_config = ConfigDict(
|
|
|
|
|
extra='forbid',
|
|
|
|
|
)
|
|
|
|
|
value: Annotated[str | int | bool | float, Field(title='Value')]
|
|
|
|
|
label: Annotated[str, Field(title='Label')]
|
|
|
|
|
description: Annotated[str | None, Field(title='Description')] = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class PropertyType(Enum):
|
|
|
|
|
"""
|
|
|
|
|
Bounded vocabulary of property types the renderer dispatches on.
|
|
|
|
|
|
|
|
|
|
Adding a value here requires a matching arm in the frontend
|
|
|
|
|
`<PropertyInput>` switch and (where relevant) the SDK codegen template.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
string = 'string'
|
|
|
|
|
number = 'number'
|
|
|
|
|
boolean = 'boolean'
|
|
|
|
|
options = 'options'
|
|
|
|
|
multi_options = 'multi_options'
|
|
|
|
|
fixed_collection = 'fixed_collection'
|
|
|
|
|
json = 'json'
|
|
|
|
|
tool_refs = 'tool_refs'
|
|
|
|
|
document_refs = 'document_refs'
|
|
|
|
|
recording_ref = 'recording_ref'
|
|
|
|
|
credential_ref = 'credential_ref'
|
|
|
|
|
mention_textarea = 'mention_textarea'
|
|
|
|
|
url = 'url'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class RecordingResponseSchema(BaseModel):
|
|
|
|
|
"""
|
|
|
|
|
Response schema for a single recording.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
id: Annotated[int, Field(title='Id')]
|
|
|
|
|
recording_id: Annotated[str, Field(title='Recording Id')]
|
|
|
|
|
workflow_id: Annotated[int | None, Field(title='Workflow Id')] = None
|
|
|
|
|
organization_id: Annotated[int, Field(title='Organization Id')]
|
|
|
|
|
tts_provider: Annotated[str | None, Field(title='Tts Provider')] = None
|
|
|
|
|
tts_model: Annotated[str | None, Field(title='Tts Model')] = None
|
|
|
|
|
tts_voice_id: Annotated[str | None, Field(title='Tts Voice Id')] = None
|
|
|
|
|
transcript: Annotated[str, Field(title='Transcript')]
|
|
|
|
|
storage_key: Annotated[str, Field(title='Storage Key')]
|
|
|
|
|
storage_backend: Annotated[str, Field(title='Storage Backend')]
|
|
|
|
|
metadata: Annotated[dict[str, Any], Field(title='Metadata')]
|
|
|
|
|
created_by: Annotated[int, Field(title='Created By')]
|
|
|
|
|
created_at: Annotated[AwareDatetime, Field(title='Created At')]
|
|
|
|
|
is_active: Annotated[bool, Field(title='Is Active')]
|
|
|
|
|
|
|
|
|
|
|
2026-05-31 16:50:44 +05:30
|
|
|
class Type1(Enum):
|
|
|
|
|
"""
|
|
|
|
|
JSON type for the parameter value.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
string = 'string'
|
|
|
|
|
number = 'number'
|
|
|
|
|
boolean = 'boolean'
|
2026-06-01 23:05:38 -07:00
|
|
|
object = 'object'
|
|
|
|
|
array = 'array'
|
2026-05-31 16:50:44 +05:30
|
|
|
|
|
|
|
|
|
|
|
|
|
class ToolParameter(BaseModel):
|
|
|
|
|
"""
|
|
|
|
|
A parameter that the tool accepts from the model at call time.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
name: Annotated[str, Field(title='Name')]
|
|
|
|
|
"""
|
|
|
|
|
Parameter name used as a key in the tool request body.
|
|
|
|
|
"""
|
|
|
|
|
type: Annotated[Type1, Field(title='Type')]
|
|
|
|
|
"""
|
|
|
|
|
JSON type for the parameter value.
|
|
|
|
|
"""
|
|
|
|
|
description: Annotated[str, Field(title='Description')]
|
|
|
|
|
"""
|
|
|
|
|
Description shown to the model for this parameter.
|
|
|
|
|
"""
|
|
|
|
|
required: Annotated[bool | None, Field(title='Required')] = True
|
|
|
|
|
"""
|
|
|
|
|
Whether this parameter is required when the tool is called.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
2026-04-21 07:56:16 +05:30
|
|
|
class ToolResponse(BaseModel):
|
|
|
|
|
"""
|
2026-05-31 16:50:44 +05:30
|
|
|
Response schema for a reusable tool.
|
2026-04-21 07:56:16 +05:30
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
id: Annotated[int, Field(title='Id')]
|
|
|
|
|
tool_uuid: Annotated[str, Field(title='Tool Uuid')]
|
|
|
|
|
name: Annotated[str, Field(title='Name')]
|
|
|
|
|
description: Annotated[str | None, Field(title='Description')]
|
|
|
|
|
category: Annotated[str, Field(title='Category')]
|
|
|
|
|
icon: Annotated[str | None, Field(title='Icon')]
|
|
|
|
|
icon_color: Annotated[str | None, Field(title='Icon Color')]
|
|
|
|
|
status: Annotated[str, Field(title='Status')]
|
|
|
|
|
definition: Annotated[dict[str, Any], Field(title='Definition')]
|
|
|
|
|
created_at: Annotated[AwareDatetime, Field(title='Created At')]
|
|
|
|
|
updated_at: Annotated[AwareDatetime | None, Field(title='Updated At')]
|
|
|
|
|
created_by: CreatedByResponse | None = None
|
|
|
|
|
|
|
|
|
|
|
2026-05-31 16:50:44 +05:30
|
|
|
class MessageType1(Enum):
|
|
|
|
|
"""
|
|
|
|
|
Type of message to play before transfer.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
none = 'none'
|
|
|
|
|
custom = 'custom'
|
|
|
|
|
audio = 'audio'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TransferCallConfig(BaseModel):
|
|
|
|
|
"""
|
|
|
|
|
Configuration for Transfer Call tools.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
destination: Annotated[str, Field(title='Destination')]
|
|
|
|
|
"""
|
|
|
|
|
Phone number or SIP endpoint to transfer the call to, e.g. +1234567890 or PJSIP/1234.
|
|
|
|
|
"""
|
|
|
|
|
messageType: Annotated[MessageType1 | None, Field(title='Messagetype')] = 'none'
|
|
|
|
|
"""
|
|
|
|
|
Type of message to play before transfer.
|
|
|
|
|
"""
|
|
|
|
|
customMessage: Annotated[str | None, Field(title='Custommessage')] = None
|
|
|
|
|
"""
|
|
|
|
|
Custom message to play before transferring.
|
|
|
|
|
"""
|
|
|
|
|
audioRecordingId: Annotated[str | None, Field(title='Audiorecordingid')] = None
|
|
|
|
|
"""
|
|
|
|
|
Recording ID for audio message before transfer.
|
|
|
|
|
"""
|
|
|
|
|
timeout: Annotated[int | None, Field(ge=5, le=120, title='Timeout')] = 30
|
|
|
|
|
"""
|
|
|
|
|
Maximum seconds to wait for the destination to answer.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class TransferCallToolDefinition(BaseModel):
|
|
|
|
|
"""
|
|
|
|
|
Tool definition for Transfer Call tools.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
schema_version: Annotated[int | None, Field(title='Schema Version')] = 1
|
|
|
|
|
"""
|
|
|
|
|
Schema version.
|
|
|
|
|
"""
|
|
|
|
|
type: Annotated[Literal['transfer_call'], Field(title='Type')]
|
|
|
|
|
"""
|
|
|
|
|
Tool type.
|
|
|
|
|
"""
|
|
|
|
|
config: TransferCallConfig
|
|
|
|
|
"""
|
|
|
|
|
Transfer Call configuration.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
2026-04-21 07:56:16 +05:30
|
|
|
class UpdateWorkflowRequest(BaseModel):
|
|
|
|
|
name: Annotated[str | None, Field(title='Name')] = None
|
|
|
|
|
workflow_definition: Annotated[
|
|
|
|
|
dict[str, Any] | None, Field(title='Workflow Definition')
|
|
|
|
|
] = None
|
|
|
|
|
template_context_variables: Annotated[
|
|
|
|
|
dict[str, Any] | None, Field(title='Template Context Variables')
|
|
|
|
|
] = None
|
|
|
|
|
workflow_configurations: Annotated[
|
|
|
|
|
dict[str, Any] | None, Field(title='Workflow Configurations')
|
|
|
|
|
] = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class ValidationError(BaseModel):
|
|
|
|
|
loc: Annotated[list[str | int], Field(title='Location')]
|
|
|
|
|
msg: Annotated[str, Field(title='Message')]
|
|
|
|
|
type: Annotated[str, Field(title='Error Type')]
|
|
|
|
|
input: Annotated[Any | None, Field(title='Input')] = None
|
|
|
|
|
ctx: Annotated[dict[str, Any] | None, Field(title='Context')] = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class WorkflowListResponse(BaseModel):
|
|
|
|
|
"""
|
|
|
|
|
Lightweight response for workflow listings (excludes large fields).
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
id: Annotated[int, Field(title='Id')]
|
|
|
|
|
name: Annotated[str, Field(title='Name')]
|
|
|
|
|
status: Annotated[str, Field(title='Status')]
|
|
|
|
|
created_at: Annotated[AwareDatetime, Field(title='Created At')]
|
|
|
|
|
total_runs: Annotated[int, Field(title='Total Runs')]
|
2026-05-22 14:36:50 +05:30
|
|
|
folder_id: Annotated[int | None, Field(title='Folder Id')] = None
|
|
|
|
|
workflow_uuid: Annotated[str | None, Field(title='Workflow Uuid')] = None
|
2026-04-21 07:56:16 +05:30
|
|
|
|
|
|
|
|
|
|
|
|
|
class WorkflowResponse(BaseModel):
|
|
|
|
|
id: Annotated[int, Field(title='Id')]
|
|
|
|
|
name: Annotated[str, Field(title='Name')]
|
|
|
|
|
status: Annotated[str, Field(title='Status')]
|
|
|
|
|
created_at: Annotated[AwareDatetime, Field(title='Created At')]
|
|
|
|
|
workflow_definition: Annotated[dict[str, Any], Field(title='Workflow Definition')]
|
|
|
|
|
current_definition_id: Annotated[int | None, Field(title='Current Definition Id')]
|
|
|
|
|
template_context_variables: Annotated[
|
|
|
|
|
dict[str, Any] | None, Field(title='Template Context Variables')
|
|
|
|
|
] = None
|
|
|
|
|
call_disposition_codes: CallDispositionCodes | None = None
|
|
|
|
|
total_runs: Annotated[int | None, Field(title='Total Runs')] = None
|
|
|
|
|
workflow_configurations: Annotated[
|
|
|
|
|
dict[str, Any] | None, Field(title='Workflow Configurations')
|
|
|
|
|
] = None
|
|
|
|
|
version_number: Annotated[int | None, Field(title='Version Number')] = None
|
|
|
|
|
version_status: Annotated[str | None, Field(title='Version Status')] = None
|
2026-05-02 16:59:17 +05:30
|
|
|
workflow_uuid: Annotated[str | None, Field(title='Workflow Uuid')] = None
|
2026-04-21 07:56:16 +05:30
|
|
|
|
|
|
|
|
|
|
|
|
|
class DocumentListResponseSchema(BaseModel):
|
|
|
|
|
"""
|
|
|
|
|
Response schema for list of documents.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
documents: Annotated[list[DocumentResponseSchema], Field(title='Documents')]
|
|
|
|
|
total: Annotated[int, Field(title='Total')]
|
|
|
|
|
limit: Annotated[int, Field(title='Limit')]
|
|
|
|
|
offset: Annotated[int, Field(title='Offset')]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class HTTPValidationError(BaseModel):
|
|
|
|
|
detail: Annotated[list[ValidationError] | None, Field(title='Detail')] = None
|
|
|
|
|
|
|
|
|
|
|
2026-05-31 16:50:44 +05:30
|
|
|
class HttpApiConfig(BaseModel):
|
|
|
|
|
"""
|
|
|
|
|
Configuration for HTTP API tools.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
method: Annotated[Method, Field(title='Method')]
|
|
|
|
|
"""
|
|
|
|
|
HTTP method to use for the request.
|
|
|
|
|
"""
|
|
|
|
|
url: Annotated[str, Field(title='Url')]
|
|
|
|
|
"""
|
|
|
|
|
Target HTTP or HTTPS URL.
|
|
|
|
|
"""
|
|
|
|
|
headers: Annotated[dict[str, str] | None, Field(title='Headers')] = None
|
|
|
|
|
"""
|
|
|
|
|
Static headers to include with every request.
|
|
|
|
|
"""
|
|
|
|
|
credential_uuid: Annotated[str | None, Field(title='Credential Uuid')] = None
|
|
|
|
|
"""
|
|
|
|
|
Reference to an external credential for request authentication.
|
|
|
|
|
"""
|
|
|
|
|
parameters: Annotated[list[ToolParameter] | None, Field(title='Parameters')] = None
|
|
|
|
|
"""
|
|
|
|
|
Parameters the model must provide when calling this tool.
|
|
|
|
|
"""
|
|
|
|
|
preset_parameters: Annotated[
|
|
|
|
|
list[PresetToolParameter] | None, Field(title='Preset Parameters')
|
|
|
|
|
] = None
|
|
|
|
|
"""
|
|
|
|
|
Parameters injected by Dograh from fixed values or workflow context templates.
|
|
|
|
|
"""
|
|
|
|
|
timeout_ms: Annotated[
|
|
|
|
|
TimeoutMs | None, Field(title='Timeout Ms', validate_default=True)
|
|
|
|
|
] = 5000
|
|
|
|
|
"""
|
|
|
|
|
Request timeout in milliseconds.
|
|
|
|
|
"""
|
|
|
|
|
customMessage: Annotated[str | None, Field(title='Custommessage')] = None
|
|
|
|
|
"""
|
|
|
|
|
Custom message to play after tool execution.
|
|
|
|
|
"""
|
|
|
|
|
customMessageType: Annotated[
|
|
|
|
|
CustomMessageType | None, Field(title='Custommessagetype')
|
|
|
|
|
] = None
|
|
|
|
|
"""
|
|
|
|
|
Type of custom message.
|
|
|
|
|
"""
|
|
|
|
|
customMessageRecordingId: Annotated[
|
|
|
|
|
str | None, Field(title='Custommessagerecordingid')
|
|
|
|
|
] = None
|
|
|
|
|
"""
|
|
|
|
|
Recording ID for an audio custom message.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class HttpApiToolDefinition(BaseModel):
|
|
|
|
|
"""
|
|
|
|
|
Tool definition for HTTP API tools.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
schema_version: Annotated[int | None, Field(title='Schema Version')] = 1
|
|
|
|
|
"""
|
|
|
|
|
Schema version.
|
|
|
|
|
"""
|
|
|
|
|
type: Annotated[Literal['http_api'], Field(title='Type')]
|
|
|
|
|
"""
|
|
|
|
|
Tool type.
|
|
|
|
|
"""
|
|
|
|
|
config: HttpApiConfig
|
|
|
|
|
"""
|
|
|
|
|
HTTP API configuration.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
2026-04-21 07:56:16 +05:30
|
|
|
class PropertySpec(BaseModel):
|
|
|
|
|
"""
|
|
|
|
|
Single field on a node.
|
|
|
|
|
|
|
|
|
|
`description` is HUMAN-FACING — shown under the field in the edit
|
|
|
|
|
dialog. Keep it concise and explain what the field does.
|
|
|
|
|
|
|
|
|
|
`llm_hint` is LLM-FACING — appears only in the `get_node_type` MCP
|
|
|
|
|
response and in SDK schema output. Use it for catalog tool references
|
|
|
|
|
(e.g., "Use `list_recordings`"), array shape, expected value idioms,
|
|
|
|
|
or anything that would be noise in the UI. Optional; omit when the
|
|
|
|
|
`description` already suffices for both audiences.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
model_config = ConfigDict(
|
|
|
|
|
extra='forbid',
|
|
|
|
|
)
|
|
|
|
|
name: Annotated[str, Field(title='Name')]
|
|
|
|
|
type: PropertyType
|
|
|
|
|
display_name: Annotated[str, Field(title='Display Name')]
|
|
|
|
|
description: Annotated[str, Field(min_length=1, title='Description')]
|
|
|
|
|
"""
|
|
|
|
|
Human-facing explanation shown in the UI.
|
|
|
|
|
"""
|
|
|
|
|
llm_hint: Annotated[str | None, Field(title='Llm Hint')] = None
|
|
|
|
|
"""
|
|
|
|
|
LLM-only guidance; omitted from the UI.
|
|
|
|
|
"""
|
|
|
|
|
default: Annotated[Any | None, Field(title='Default')] = None
|
|
|
|
|
required: Annotated[bool | None, Field(title='Required')] = False
|
|
|
|
|
placeholder: Annotated[str | None, Field(title='Placeholder')] = None
|
|
|
|
|
display_options: DisplayOptions | None = None
|
|
|
|
|
options: Annotated[list[PropertyOption] | None, Field(title='Options')] = None
|
|
|
|
|
properties: Annotated[list[PropertySpec] | None, Field(title='Properties')] = None
|
|
|
|
|
min_value: Annotated[float | None, Field(title='Min Value')] = None
|
|
|
|
|
max_value: Annotated[float | None, Field(title='Max Value')] = None
|
|
|
|
|
min_length: Annotated[int | None, Field(title='Min Length')] = None
|
|
|
|
|
max_length: Annotated[int | None, Field(title='Max Length')] = None
|
|
|
|
|
pattern: Annotated[str | None, Field(title='Pattern')] = None
|
|
|
|
|
editor: Annotated[str | None, Field(title='Editor')] = None
|
|
|
|
|
extra: Annotated[dict[str, Any] | None, Field(title='Extra')] = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class RecordingListResponseSchema(BaseModel):
|
|
|
|
|
"""
|
|
|
|
|
Response schema for list of recordings.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
recordings: Annotated[list[RecordingResponseSchema], Field(title='Recordings')]
|
|
|
|
|
total: Annotated[int, Field(title='Total')]
|
|
|
|
|
|
|
|
|
|
|
2026-05-31 16:50:44 +05:30
|
|
|
class CreateToolRequest(BaseModel):
|
|
|
|
|
"""
|
|
|
|
|
Request schema for creating a reusable tool.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
name: Annotated[str, Field(max_length=255, title='Name')]
|
|
|
|
|
"""
|
|
|
|
|
Display name for the tool.
|
|
|
|
|
"""
|
|
|
|
|
description: Annotated[str | None, Field(title='Description')] = None
|
|
|
|
|
"""
|
|
|
|
|
Description shown to the agent when deciding whether to call it.
|
|
|
|
|
"""
|
|
|
|
|
category: Annotated[Category | None, Field(title='Category')] = 'http_api'
|
|
|
|
|
"""
|
|
|
|
|
Tool category. Must match definition.type.
|
|
|
|
|
"""
|
|
|
|
|
icon: Annotated[Icon | None, Field(title='Icon', validate_default=True)] = 'globe'
|
|
|
|
|
"""
|
|
|
|
|
Lucide icon identifier.
|
|
|
|
|
"""
|
|
|
|
|
icon_color: Annotated[
|
|
|
|
|
IconColor | None, Field(title='Icon Color', validate_default=True)
|
|
|
|
|
] = '#3B82F6'
|
|
|
|
|
"""
|
|
|
|
|
Hex color for the tool icon.
|
|
|
|
|
"""
|
|
|
|
|
definition: Annotated[
|
|
|
|
|
HttpApiToolDefinition
|
|
|
|
|
| EndCallToolDefinition
|
|
|
|
|
| TransferCallToolDefinition
|
|
|
|
|
| CalculatorToolDefinition
|
|
|
|
|
| McpToolDefinition,
|
|
|
|
|
Field(discriminator='type', title='Definition'),
|
|
|
|
|
]
|
|
|
|
|
"""
|
|
|
|
|
Typed tool definition.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
|
2026-04-21 07:56:16 +05:30
|
|
|
class NodeSpec(BaseModel):
|
|
|
|
|
"""
|
|
|
|
|
Single source of truth for a node type.
|
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
|
model_config = ConfigDict(
|
|
|
|
|
extra='forbid',
|
|
|
|
|
)
|
|
|
|
|
name: Annotated[str, Field(title='Name')]
|
|
|
|
|
display_name: Annotated[str, Field(title='Display Name')]
|
|
|
|
|
description: Annotated[str, Field(min_length=1, title='Description')]
|
|
|
|
|
"""
|
|
|
|
|
Human-facing explanation shown in AddNodePanel.
|
|
|
|
|
"""
|
|
|
|
|
llm_hint: Annotated[str | None, Field(title='Llm Hint')] = None
|
|
|
|
|
"""
|
|
|
|
|
LLM-only guidance; omitted from the UI.
|
|
|
|
|
"""
|
|
|
|
|
category: NodeCategory
|
|
|
|
|
icon: Annotated[str, Field(title='Icon')]
|
|
|
|
|
version: Annotated[str | None, Field(title='Version')] = '1.0.0'
|
|
|
|
|
properties: Annotated[list[PropertySpec], Field(title='Properties')]
|
|
|
|
|
examples: Annotated[list[NodeExample] | None, Field(title='Examples')] = None
|
|
|
|
|
graph_constraints: GraphConstraints | None = None
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
class NodeTypesResponse(BaseModel):
|
|
|
|
|
spec_version: Annotated[str, Field(title='Spec Version')]
|
|
|
|
|
node_types: Annotated[list[NodeSpec], Field(title='Node Types')]
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
PropertySpec.model_rebuild()
|