191 lines
10 KiB
JSON
191 lines
10 KiB
JSON
{
|
|
"$schema": "https://json-schema.org/draft/2020-12/schema",
|
|
"$id": "https://go-sip.local/contracts/current/config-read.schema.json",
|
|
"title": "Project-local read-only Dispatcher configuration; external SaaS compatibility unverified",
|
|
"oneOf": [
|
|
{"$ref": "#/$defs/sip"},
|
|
{"$ref": "#/$defs/providers"},
|
|
{"$ref": "#/$defs/task"},
|
|
{"$ref": "#/$defs/quota"},
|
|
{"$ref": "#/$defs/error"}
|
|
],
|
|
"$defs": {
|
|
"dispatcher_id": {"type": "string", "format": "uuid"},
|
|
"tenant_id": {"type": "integer", "minimum": 1},
|
|
"task_id": {"type": "string", "pattern": "^[A-Za-z0-9_-]{1,128}$"},
|
|
"sip": {
|
|
"type": "object", "additionalProperties": false,
|
|
"required": ["resource", "dispatcher_id", "revision", "trunks"],
|
|
"properties": {
|
|
"resource": {"const": "sip_config"},
|
|
"dispatcher_id": {"$ref": "#/$defs/dispatcher_id"},
|
|
"revision": {"type": "integer", "minimum": 1},
|
|
"trunks": {"type": "array", "items": {"$ref": "#/$defs/trunk"}}
|
|
}
|
|
},
|
|
"trunk": {
|
|
"type": "object", "additionalProperties": false,
|
|
"required": ["trunk_id", "provider_id", "codec", "dial_prefix", "enabled", "server_host", "server_port", "transport", "auth_mode", "registration_required", "max_concurrent_calls", "caller_profiles", "schedule"],
|
|
"properties": {
|
|
"trunk_id": {"type": "string", "minLength": 1},
|
|
"provider_id": {"type": "string", "minLength": 1},
|
|
"codec": {"const": "PCMA"},
|
|
"dial_prefix": {"type": "string"},
|
|
"enabled": {"type": "boolean"},
|
|
"server_host": {"type": "string", "minLength": 1},
|
|
"server_port": {"type": "integer", "minimum": 1, "maximum": 65535},
|
|
"transport": {"enum": ["udp", "tcp", "tls", null]},
|
|
"auth_mode": {"enum": ["ip", "digest", "none", null]},
|
|
"registration_required": {"type": ["boolean", "null"]},
|
|
"max_concurrent_calls": {"type": ["integer", "null"], "minimum": 1},
|
|
"caller_profiles": {"type": "array", "items": {"type": "object", "additionalProperties": false, "required": ["caller_profile_id", "caller_id"], "properties": {"caller_profile_id": {"type": "string", "minLength": 1}, "caller_id": {"type": "string", "minLength": 1}}}},
|
|
"schedule": {"$ref": "#/$defs/weekly_schedule"}
|
|
}
|
|
},
|
|
"providers": {
|
|
"type": "object", "additionalProperties": false,
|
|
"required": ["resource", "dispatcher_id", "providers"],
|
|
"properties": {
|
|
"resource": {"const": "ai_providers"},
|
|
"dispatcher_id": {"$ref": "#/$defs/dispatcher_id"},
|
|
"providers": {"type": "array", "items": {"$ref": "#/$defs/provider"}}
|
|
}
|
|
},
|
|
"provider": {
|
|
"type": "object", "additionalProperties": false,
|
|
"required": ["provider_ref", "role", "enabled", "adapter", "endpoint", "credential"],
|
|
"properties": {
|
|
"provider_ref": {"type": "string", "minLength": 1},
|
|
"role": {"enum": ["asr", "llm", "tts"]},
|
|
"enabled": {"type": "boolean"},
|
|
"adapter": {"type": "string", "minLength": 1},
|
|
"endpoint": {"type": "string", "minLength": 1},
|
|
"credential": {"type": "string", "minLength": 1, "$comment": "Value is supplied verbatim to the provider SDK. Never log its content."}
|
|
}
|
|
},
|
|
"task": {
|
|
"type": "object", "additionalProperties": false,
|
|
"required": ["resource", "dispatcher_id", "tenant_id", "task_id", "task_revision", "status", "max_concurrent_calls", "ring_timeout_ms", "max_call_duration_ms", "route_policy_id", "caller_profile_id", "allowed_trunk_ids", "schedule", "agent"],
|
|
"properties": {
|
|
"resource": {"const": "task_config"},
|
|
"dispatcher_id": {"$ref": "#/$defs/dispatcher_id"},
|
|
"tenant_id": {"$ref": "#/$defs/tenant_id"},
|
|
"task_id": {"$ref": "#/$defs/task_id"},
|
|
"task_revision": {"type": "integer", "minimum": 1},
|
|
"status": {"enum": ["running", "paused", "stopped"]},
|
|
"name": {"type": "string", "minLength": 1},
|
|
"max_concurrent_calls": {"type": "integer", "minimum": 1},
|
|
"ring_timeout_ms": {"type": "integer", "minimum": 1},
|
|
"max_call_duration_ms": {"type": "integer", "minimum": 1},
|
|
"route_policy_id": {"type": "string", "minLength": 1},
|
|
"caller_profile_id": {"type": "string", "minLength": 1},
|
|
"allowed_trunk_ids": {"type": "array", "minItems": 1, "uniqueItems": true, "items": {"type": "string", "minLength": 1}},
|
|
"schedule": {"$ref": "#/$defs/task_schedule"},
|
|
"agent": {"$ref": "#/$defs/agent"}
|
|
}
|
|
},
|
|
"quota": {
|
|
"type": "object", "additionalProperties": false,
|
|
"required": ["resource", "dispatcher_id", "tenant_id", "quota_revision", "max_concurrent_calls"],
|
|
"properties": {
|
|
"resource": {"const": "tenant_quota"},
|
|
"dispatcher_id": {"$ref": "#/$defs/dispatcher_id"},
|
|
"tenant_id": {"$ref": "#/$defs/tenant_id"},
|
|
"quota_revision": {"type": "integer", "minimum": 1},
|
|
"max_concurrent_calls": {"type": "integer", "minimum": 0}
|
|
}
|
|
},
|
|
"error": {
|
|
"type": "object", "additionalProperties": false,
|
|
"required": ["resource", "error"],
|
|
"properties": {
|
|
"resource": {"const": "error"},
|
|
"error": {"type": "object", "additionalProperties": false, "required": ["code", "message"], "properties": {"code": {"type": "string", "minLength": 1}, "message": {"type": "string", "minLength": 1}}}
|
|
}
|
|
},
|
|
"task_schedule": {
|
|
"type": "object", "additionalProperties": false,
|
|
"required": ["time_zone", "starts_at", "ends_at", "weekly_windows", "excluded_dates"],
|
|
"properties": {
|
|
"time_zone": {"const": "Asia/Shanghai"},
|
|
"starts_at": {"type": ["string", "null"], "format": "date-time"},
|
|
"ends_at": {"type": ["string", "null"], "format": "date-time"},
|
|
"weekly_windows": {"$ref": "#/$defs/weekly_windows"},
|
|
"excluded_dates": {"type": "array", "uniqueItems": true, "items": {"type": "string", "format": "date"}}
|
|
}
|
|
},
|
|
"weekly_schedule": {
|
|
"type": "object", "additionalProperties": false,
|
|
"required": ["time_zone", "weekly_windows"],
|
|
"properties": {"time_zone": {"const": "Asia/Shanghai"}, "weekly_windows": {"$ref": "#/$defs/weekly_windows"}}
|
|
},
|
|
"weekly_windows": {
|
|
"type": "object", "additionalProperties": false,
|
|
"required": ["monday", "tuesday", "wednesday", "thursday", "friday", "saturday", "sunday"],
|
|
"properties": {
|
|
"monday": {"$ref": "#/$defs/windows"}, "tuesday": {"$ref": "#/$defs/windows"}, "wednesday": {"$ref": "#/$defs/windows"}, "thursday": {"$ref": "#/$defs/windows"}, "friday": {"$ref": "#/$defs/windows"}, "saturday": {"$ref": "#/$defs/windows"}, "sunday": {"$ref": "#/$defs/windows"}
|
|
}
|
|
},
|
|
"windows": {"type": "array", "items": {"type": "object", "additionalProperties": false, "required": ["start", "end"], "properties": {"start": {"type": "string", "pattern": "^(?:[01][0-9]|2[0-3]):[0-5][0-9]$"}, "end": {"type": "string", "pattern": "^(?:(?:[01][0-9]|2[0-3]):[0-5][0-9]|24:00)$"}}}},
|
|
"agent": {
|
|
"type": "object", "additionalProperties": false,
|
|
"required": ["immutable", "mode", "asr"],
|
|
"properties": {
|
|
"immutable": {"const": true},
|
|
"mode": {"enum": ["asr_only", "full_ai"]},
|
|
"asr": {"$ref": "#/$defs/asr"},
|
|
"llm": {"$ref": "#/$defs/llm"},
|
|
"tts": {"$ref": "#/$defs/tts"},
|
|
"prompt": {"$ref": "#/$defs/prompt"},
|
|
"conversation": {"$ref": "#/$defs/conversation"}
|
|
},
|
|
"allOf": [
|
|
{"if": {"properties": {"mode": {"const": "full_ai"}}}, "then": {"required": ["llm", "tts", "prompt", "conversation"]}},
|
|
{"if": {"properties": {"mode": {"const": "asr_only"}}}, "then": {"not": {"anyOf": [{"required": ["llm"]}, {"required": ["tts"]}, {"required": ["prompt"]}]}}}
|
|
]
|
|
},
|
|
"asr": {
|
|
"type": "object", "additionalProperties": false,
|
|
"required": ["provider_ref", "language", "input"],
|
|
"properties": {
|
|
"provider_ref": {"type": "string", "minLength": 1},
|
|
"model": {"type": "string", "minLength": 1},
|
|
"language": {"type": "string", "minLength": 1},
|
|
"interim": {"type": "boolean"},
|
|
"timeout_ms": {"type": "integer", "minimum": 1},
|
|
"input": {"$ref": "#/$defs/audio_input"}
|
|
}
|
|
},
|
|
"audio_input": {
|
|
"type": "object", "additionalProperties": false,
|
|
"required": ["encoding", "sample_rate_hz", "channels", "sample_width_bytes"],
|
|
"properties": {
|
|
"encoding": {"const": "pcm_s16le"}, "sample_rate_hz": {"type": "integer", "minimum": 8000}, "channels": {"const": 1}, "sample_width_bytes": {"const": 2}
|
|
}
|
|
},
|
|
"llm": {
|
|
"type": "object", "additionalProperties": false,
|
|
"required": ["provider_ref", "model"],
|
|
"properties": {
|
|
"provider_ref": {"type": "string", "minLength": 1}, "model": {"type": "string", "minLength": 1}, "temperature": {"type": "number", "minimum": 0, "maximum": 2}, "max_tokens": {"type": "integer", "minimum": 1}, "timeout_ms": {"type": "integer", "minimum": 1}
|
|
}
|
|
},
|
|
"tts": {
|
|
"type": "object", "additionalProperties": false,
|
|
"required": ["provider_ref", "model", "voice", "format"],
|
|
"properties": {
|
|
"provider_ref": {"type": "string", "minLength": 1}, "model": {"type": "string", "minLength": 1}, "voice": {"type": "string", "minLength": 1}, "speed": {"type": "number", "minimum": 0.25, "maximum": 3}, "timeout_ms": {"type": "integer", "minimum": 1}, "format": {"type": "object", "additionalProperties": false, "required": ["encoding", "sample_rate_hz", "channels"], "properties": {"encoding": {"enum": ["pcm_s16le", "pcma"]}, "sample_rate_hz": {"type": "integer", "minimum": 8000}, "channels": {"const": 1}}}
|
|
}
|
|
},
|
|
"prompt": {
|
|
"type": "object", "additionalProperties": false,
|
|
"required": ["text", "allowed_variables"],
|
|
"properties": {"text": {"type": "string", "minLength": 1}, "allowed_variables": {"type": "array", "uniqueItems": true, "items": {"type": "string", "minLength": 1}}, "max_bytes": {"type": "integer", "minimum": 1}}
|
|
},
|
|
"conversation": {
|
|
"type": "object", "additionalProperties": false,
|
|
"properties": {"opening": {"type": "string"}, "hangup_keywords": {"type": "array", "items": {"type": "string", "minLength": 1}}, "allow_interrupt": {"type": "boolean"}, "silence_timeout_ms": {"type": "integer", "minimum": 1}, "max_duration_ms": {"type": "integer", "minimum": 1}, "max_turns": {"type": "integer", "minimum": 1}, "sentence_max_chars": {"type": "integer", "minimum": 1}, "max_pending_audio_chunks": {"type": "integer", "minimum": 1}}
|
|
}
|
|
}
|
|
}
|