mirror of
https://github.com/dograh-hq/dograh.git
synced 2026-07-16 11:31:04 +02:00
chore: add docs url for integration nodes
This commit is contained in:
parent
c650ccc5dd
commit
a422241517
13 changed files with 95 additions and 13 deletions
|
|
@ -25,6 +25,7 @@ from api.services.workflow.node_specs.model_spec import (
|
|||
"Paygent is a post-call usage-tracking and billing integration. "
|
||||
"It does not participate in the conversation graph and should not be connected to other nodes."
|
||||
),
|
||||
docs_url="https://docs.dograh.com/integrations/paygent",
|
||||
category=NodeCategory.integration,
|
||||
icon="CreditCard",
|
||||
examples=[
|
||||
|
|
|
|||
|
|
@ -36,6 +36,7 @@ _COST_RATE_RENDERER_OPTIONS = PropertyRendererOptions(
|
|||
"Tuner is a post-call observability export. It does not participate in the "
|
||||
"conversation graph and should not be connected to other nodes."
|
||||
),
|
||||
docs_url="https://docs.dograh.com/integrations/tuner",
|
||||
category=NodeCategory.integration,
|
||||
icon="Activity",
|
||||
examples=[
|
||||
|
|
|
|||
|
|
@ -241,9 +241,7 @@ class DograhUltravoxRealtimeLLMService(UltravoxRealtimeLLMService):
|
|||
"call(s) after bot turn ended"
|
||||
)
|
||||
for tool_name, invocation_id, parameters in invocations:
|
||||
await super()._handle_tool_invocation(
|
||||
tool_name, invocation_id, parameters
|
||||
)
|
||||
await super()._handle_tool_invocation(tool_name, invocation_id, parameters)
|
||||
|
||||
async def _send_tool_result(self, tool_call_id: str, result: str):
|
||||
is_node_transition = tool_call_id in self._pending_node_transition_tool_call_ids
|
||||
|
|
|
|||
|
|
@ -300,6 +300,10 @@ class NodeSpec(BaseModel):
|
|||
default=None,
|
||||
description="LLM-only guidance; omitted from the UI.",
|
||||
)
|
||||
docs_url: Optional[str] = Field(
|
||||
default=None,
|
||||
description="Documentation URL shown in the node editor.",
|
||||
)
|
||||
category: NodeCategory
|
||||
icon: str # lucide-react icon name (e.g., "Play")
|
||||
version: str = "1.0.0"
|
||||
|
|
@ -312,8 +316,8 @@ class NodeSpec(BaseModel):
|
|||
def to_mcp_dict(self) -> dict[str, Any]:
|
||||
"""Lean projection of this spec for the `get_node_type` MCP tool.
|
||||
|
||||
Drops node-level UI metadata (`display_name`, `category`, `icon`,
|
||||
`version`) and the per-property rendering concerns trimmed by
|
||||
Drops node-level UI metadata (`display_name`, `docs_url`, `category`,
|
||||
`icon`, `version`) and the per-property rendering concerns trimmed by
|
||||
`PropertySpec.to_mcp_dict`, leaving just the authoring-relevant
|
||||
schema the LLM consumes when composing a workflow. The full spec is
|
||||
still served verbatim to the frontend renderer (REST `node-types`
|
||||
|
|
|
|||
|
|
@ -33,6 +33,7 @@ class NodeSpecMetadata:
|
|||
category: NodeCategory
|
||||
icon: str
|
||||
llm_hint: str | None = None
|
||||
docs_url: str | None = None
|
||||
version: str = "1.0.0"
|
||||
examples: tuple[NodeExample, ...] = ()
|
||||
graph_constraints: GraphConstraints | None = None
|
||||
|
|
@ -91,6 +92,7 @@ def node_spec(
|
|||
category: NodeCategory,
|
||||
icon: str,
|
||||
llm_hint: str | None = None,
|
||||
docs_url: str | None = None,
|
||||
version: str = "1.0.0",
|
||||
examples: list[NodeExample] | tuple[NodeExample, ...] = (),
|
||||
graph_constraints: GraphConstraints | None = None,
|
||||
|
|
@ -104,6 +106,7 @@ def node_spec(
|
|||
category=category,
|
||||
icon=icon,
|
||||
llm_hint=llm_hint,
|
||||
docs_url=docs_url,
|
||||
version=version,
|
||||
examples=tuple(examples),
|
||||
graph_constraints=graph_constraints,
|
||||
|
|
@ -137,6 +140,7 @@ def build_spec(model_cls: type[BaseModel]) -> NodeSpec:
|
|||
display_name=metadata.display_name,
|
||||
description=metadata.description,
|
||||
llm_hint=metadata.llm_hint,
|
||||
docs_url=metadata.docs_url,
|
||||
category=metadata.category,
|
||||
icon=metadata.icon,
|
||||
version=metadata.version,
|
||||
|
|
|
|||
|
|
@ -336,6 +336,18 @@ def test_tuner_cost_rate_fields_use_typed_renderer_options():
|
|||
)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("spec_name", "expected_docs_url"),
|
||||
[
|
||||
("paygent", "https://docs.dograh.com/integrations/paygent"),
|
||||
("tuner", "https://docs.dograh.com/integrations/tuner"),
|
||||
],
|
||||
)
|
||||
def test_integration_node_docs_url(spec_name: str, expected_docs_url: str):
|
||||
spec = next(spec for spec in all_specs() if spec.name == spec_name)
|
||||
assert spec.docs_url == expected_docs_url
|
||||
|
||||
|
||||
def test_property_renderer_options_reject_unknown_hints():
|
||||
with pytest.raises(ValidationError):
|
||||
PropertyRendererOptions.model_validate({"layout": {"width": "half"}})
|
||||
|
|
@ -352,6 +364,7 @@ def test_property_renderer_options_reject_unknown_hints():
|
|||
_UI_ONLY_KEYS = frozenset(
|
||||
{
|
||||
"display_name",
|
||||
"docs_url",
|
||||
"icon",
|
||||
"category",
|
||||
"version",
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
|
|
@ -1,6 +1,6 @@
|
|||
# generated by datamodel-codegen:
|
||||
# filename: dograh-openapi-XXXXXX.json.uTKtHKJw6v
|
||||
# timestamp: 2026-07-15T11:25:06+00:00
|
||||
# filename: dograh-openapi-XXXXXX.json.di0tn7Gw6b
|
||||
# timestamp: 2026-07-15T13:20:43+00:00
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
|
|
@ -947,6 +947,10 @@ class NodeSpec(BaseModel):
|
|||
"""
|
||||
LLM-only guidance; omitted from the UI.
|
||||
"""
|
||||
docs_url: Annotated[str | None, Field(title='Docs Url')] = None
|
||||
"""
|
||||
Documentation URL shown in the node editor.
|
||||
"""
|
||||
category: NodeCategory
|
||||
icon: Annotated[str, Field(title='Icon')]
|
||||
version: Annotated[str | None, Field(title='Version')] = '1.0.0'
|
||||
|
|
|
|||
|
|
@ -809,6 +809,11 @@ export interface components {
|
|||
* @description LLM-only guidance; omitted from the UI.
|
||||
*/
|
||||
llm_hint?: string | null;
|
||||
/**
|
||||
* Docs Url
|
||||
* @description Documentation URL shown in the node editor.
|
||||
*/
|
||||
docs_url?: string | null;
|
||||
category: components["schemas"]["NodeCategory"];
|
||||
/** Icon */
|
||||
icon: string;
|
||||
|
|
|
|||
File diff suppressed because one or more lines are too long
File diff suppressed because one or more lines are too long
|
|
@ -401,7 +401,7 @@ export type AzureRealtimeLlmConfiguration = {
|
|||
/**
|
||||
* Api Version
|
||||
*
|
||||
* Azure OpenAI API version.
|
||||
* Azure OpenAI Realtime protocol version. Use 'v1' for the GA API; date-based versions select the deprecated preview endpoint.
|
||||
*/
|
||||
api_version?: string;
|
||||
};
|
||||
|
|
@ -3814,6 +3814,12 @@ export type NodeSpec = {
|
|||
* LLM-only guidance; omitted from the UI.
|
||||
*/
|
||||
llm_hint?: string | null;
|
||||
/**
|
||||
* Docs Url
|
||||
*
|
||||
* Documentation URL shown in the node editor.
|
||||
*/
|
||||
docs_url?: string | null;
|
||||
category: NodeCategory;
|
||||
/**
|
||||
* Icon
|
||||
|
|
@ -7479,6 +7485,38 @@ export type CompleteTransferFunctionCallApiV1TelephonyTransferResultTransferIdPo
|
|||
200: unknown;
|
||||
};
|
||||
|
||||
export type HandleCloudonixTransferResultApiV1TelephonyCloudonixTransferResultTransferIdPostData = {
|
||||
body?: never;
|
||||
path: {
|
||||
/**
|
||||
* Transfer Id
|
||||
*/
|
||||
transfer_id: string;
|
||||
};
|
||||
query?: never;
|
||||
url: '/api/v1/telephony/cloudonix/transfer-result/{transfer_id}';
|
||||
};
|
||||
|
||||
export type HandleCloudonixTransferResultApiV1TelephonyCloudonixTransferResultTransferIdPostErrors = {
|
||||
/**
|
||||
* Not found
|
||||
*/
|
||||
404: unknown;
|
||||
/**
|
||||
* Validation Error
|
||||
*/
|
||||
422: HttpValidationError;
|
||||
};
|
||||
|
||||
export type HandleCloudonixTransferResultApiV1TelephonyCloudonixTransferResultTransferIdPostError = HandleCloudonixTransferResultApiV1TelephonyCloudonixTransferResultTransferIdPostErrors[keyof HandleCloudonixTransferResultApiV1TelephonyCloudonixTransferResultTransferIdPostErrors];
|
||||
|
||||
export type HandleCloudonixTransferResultApiV1TelephonyCloudonixTransferResultTransferIdPostResponses = {
|
||||
/**
|
||||
* Successful Response
|
||||
*/
|
||||
200: unknown;
|
||||
};
|
||||
|
||||
export type HandleCloudonixStatusCallbackApiV1TelephonyCloudonixStatusCallbackWorkflowRunIdPostData = {
|
||||
body?: never;
|
||||
path: {
|
||||
|
|
|
|||
|
|
@ -597,7 +597,7 @@ export const GenericNode = memo(({ data, selected, id, type }: GenericNodeProps)
|
|||
: { source: true, target: true });
|
||||
const badge = getBadgeForSpec(spec, styleVariant);
|
||||
const Icon = spec ? resolveIcon(spec.icon) : Circle;
|
||||
const docUrl = DOC_URL_BY_SPEC[type];
|
||||
const docUrl = spec?.docs_url ?? DOC_URL_BY_SPEC[type];
|
||||
const contentLabel = spec?.properties.some((p) => p.name === "prompt")
|
||||
? "Prompt"
|
||||
: "Details";
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue