ui rezig, onboarding, billing, hire us & on prem cues

This commit is contained in:
Pritesh 2026-06-11 10:37:43 +05:30
parent 0662a1770f
commit 0eddce6c83
55 changed files with 1108 additions and 629 deletions

View file

@ -85,6 +85,9 @@ class UserConfigurationRequestResponseSchema(BaseModel):
test_phone_number: str | None = None
timezone: str | None = None
organization_pricing: dict[str, Union[float, str, bool]] | None = None
# Post-signup onboarding gate (see UserConfiguration). Set once on submit/skip.
onboarding_completed_at: datetime | None = None
onboarding_skipped: bool | None = None
@router.get("/configurations/user")

View file

@ -21,6 +21,10 @@ class UserConfiguration(BaseModel):
test_phone_number: str | None = None
timezone: str | None = None
last_validated_at: datetime | None = None
# Post-signup onboarding gate: set once the user submits or skips the
# onboarding form, so it shows only once per user (server-side, cross-device).
onboarding_completed_at: datetime | None = None
onboarding_skipped: bool = False
@model_validator(mode="before")
@classmethod

View file

@ -141,6 +141,10 @@ def mask_user_config(config: UserConfiguration) -> Dict[str, Any]:
"is_realtime": config.is_realtime,
"test_phone_number": config.test_phone_number,
"timezone": config.timezone,
# Onboarding gate flags (not secrets) — surfaced so the UI can decide
# whether to show the post-signup onboarding form on boot.
"onboarding_completed_at": config.onboarding_completed_at,
"onboarding_skipped": config.onboarding_skipped,
}

View file

@ -113,6 +113,13 @@ def merge_user_configurations(
if "timezone" in incoming_partial:
merged["timezone"] = incoming_partial["timezone"]
# Onboarding gate flags — overwrite only when supplied (set once on submit/skip).
if "onboarding_completed_at" in incoming_partial:
merged["onboarding_completed_at"] = incoming_partial["onboarding_completed_at"]
if "onboarding_skipped" in incoming_partial:
merged["onboarding_skipped"] = incoming_partial["onboarding_skipped"]
return UserConfiguration.model_validate(merged)

View file

@ -257,12 +257,12 @@ SPEACHES_PROVIDER_MODEL_CONFIG = provider_model_config(
)
AZURE_SPEECH_PROVIDER_MODEL_CONFIG = provider_model_config(
"Azure Speech Services",
description="Azure Cognitive Services Speech TTS and STT via the Azure Speech SDK.",
description="Azure Cognitive Services Speech - TTS and STT via the Azure Speech SDK.",
provider_docs_url="https://learn.microsoft.com/en-us/azure/ai-services/speech-service/",
)
AZURE_REALTIME_PROVIDER_MODEL_CONFIG = provider_model_config(
"Azure OpenAI Realtime",
description="Azure OpenAI Realtime API low-latency speech-to-speech conversations.",
description="Azure OpenAI Realtime API - low-latency speech-to-speech conversations.",
provider_docs_url="https://learn.microsoft.com/en-us/azure/ai-services/openai/how-to/realtime-audio-quickstart",
)
@ -360,7 +360,7 @@ class GoogleVertexLLMConfiguration(BaseLLMConfiguration):
api_key: str | list[str] | None = Field(
default=None,
description=(
"Not used for Vertex AI authentication is via the service account "
"Not used for Vertex AI - authentication is via the service account "
"in `credentials` (or ADC). Leave blank."
),
)
@ -425,7 +425,7 @@ class AWSBedrockLLMConfiguration(BaseLLMConfiguration):
provider: Literal[ServiceProviders.AWS_BEDROCK] = ServiceProviders.AWS_BEDROCK
model: str = Field(
default="us.amazon.nova-pro-v1:0",
description="Bedrock model ID include the region inference-profile prefix (e.g. 'us.').",
description="Bedrock model ID - include the region inference-profile prefix (e.g. 'us.').",
json_schema_extra={"examples": AWS_BEDROCK_MODELS, "allow_custom_input": True},
)
aws_access_key: str = Field(
@ -442,7 +442,7 @@ class AWSBedrockLLMConfiguration(BaseLLMConfiguration):
)
api_key: str | list[str] | None = Field(
default=None,
description="Not used for Bedrock authentication is via the AWS credentials above. Leave blank.",
description="Not used for Bedrock - authentication is via the AWS credentials above. Leave blank.",
)
@ -682,7 +682,7 @@ class GoogleVertexRealtimeLLMConfiguration(BaseLLMConfiguration):
api_key: str | list[str] | None = Field(
default=None,
description=(
"Not used for Vertex AI authentication is via the service account "
"Not used for Vertex AI - authentication is via the service account "
"in `credentials` (or ADC). Leave blank."
),
)

View file

@ -176,7 +176,7 @@ class _ToolDocumentRefsMixin(BaseModel):
@node_spec(
name="startCall",
display_name="Start Call",
description="Entry point of the workflow plays a greeting and opens the conversation.",
description="Entry point of the workflow - plays a greeting and opens the conversation.",
llm_hint=(
"The entry point of every workflow (exactly one required). Plays an "
"optional greeting, can fetch context from an external API before the "
@ -344,7 +344,7 @@ class StartCallNodeData(
@node_spec(
name="agentNode",
display_name="Agent Node",
description="Conversational step the LLM runs one focused exchange.",
description="Conversational step - the LLM runs one focused exchange.",
llm_hint=(
"Mid-call step executed by the LLM. Most workflows are a chain of agent "
"nodes connected by edges that describe transition conditions. Each agent "
@ -613,9 +613,9 @@ class GlobalNodeData(BaseNodeData, _PromptedNodeDataMixin):
"description": (
"Path segment that uniquely identifies "
"this trigger. Used in both URLs:\n"
" • Production: `/api/v1/public/agent/<trigger_path>` executes "
" • Production: `/api/v1/public/agent/<trigger_path>` - executes "
"the published agent.\n"
" • Test: `/api/v1/public/agent/test/<trigger_path>` executes "
" • Test: `/api/v1/public/agent/test/<trigger_path>` - executes "
"the latest draft.\n"
"Can be customized to a descriptive value up to 36 characters "
"using letters, numbers, hyphens, or underscores."
@ -708,7 +708,7 @@ class TriggerNodeData(BaseNodeData):
"display_name": "Payload Template",
"description": (
"JSON body of the request. Values are Jinja-rendered against the "
"run context `{{workflow_run_id}}`, `{{gathered_context.foo}}`, "
"run context - `{{workflow_run_id}}`, `{{gathered_context.foo}}`, "
"`{{annotations.qa_xxx}}`, etc."
),
"ui_type": PropertyType.json,

View file

@ -229,7 +229,7 @@ class WorkflowGraph:
kind=ItemKind.workflow,
id=None,
field=None,
message="Workflow has no start node exactly one is required",
message="Workflow has no start node - exactly one is required",
)
)
elif len(start_nodes) > 1:
@ -239,7 +239,7 @@ class WorkflowGraph:
id=None,
field=None,
message=(
f"Workflow has {len(start_nodes)} start nodes "
f"Workflow has {len(start_nodes)} start nodes - "
f"exactly one is required"
),
)