@serviceai/api-spec 1.1.23 → 1.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/openapi.json +1325 -107
- package/openapi.yaml +806 -34
- package/package.json +1 -1
- package/types.d.ts +678 -13
package/openapi.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
openapi: 3.1.0
|
|
2
2
|
info:
|
|
3
3
|
title: ServiceAi API
|
|
4
|
-
version: 1.1
|
|
4
|
+
version: 1.2.1
|
|
5
5
|
description: >-
|
|
6
6
|
Source-of-truth API contract for ServiceAi. Generated from `shared/schema.ts` Zod schemas by
|
|
7
7
|
`scripts/build-api-spec.ts`. Versioning policy: see `docs/api-versioning.md`. The hand-written docs/ios-contract.md
|
|
@@ -78,7 +78,7 @@ components:
|
|
|
78
78
|
properties:
|
|
79
79
|
apiVersion:
|
|
80
80
|
type: string
|
|
81
|
-
example: 1.1
|
|
81
|
+
example: 1.2.1
|
|
82
82
|
minClientVersion:
|
|
83
83
|
type: string
|
|
84
84
|
example: 1.0.0
|
|
@@ -1234,9 +1234,49 @@ components:
|
|
|
1234
1234
|
type: string
|
|
1235
1235
|
category:
|
|
1236
1236
|
type: string
|
|
1237
|
+
roomLocalId:
|
|
1238
|
+
type: string
|
|
1239
|
+
maxLength: 128
|
|
1237
1240
|
walls:
|
|
1238
1241
|
type: array
|
|
1239
|
-
items:
|
|
1242
|
+
items:
|
|
1243
|
+
type: object
|
|
1244
|
+
properties:
|
|
1245
|
+
start:
|
|
1246
|
+
type: object
|
|
1247
|
+
properties:
|
|
1248
|
+
x:
|
|
1249
|
+
type: number
|
|
1250
|
+
'y':
|
|
1251
|
+
type: number
|
|
1252
|
+
required:
|
|
1253
|
+
- x
|
|
1254
|
+
- 'y'
|
|
1255
|
+
end:
|
|
1256
|
+
type: object
|
|
1257
|
+
properties:
|
|
1258
|
+
x:
|
|
1259
|
+
type: number
|
|
1260
|
+
'y':
|
|
1261
|
+
type: number
|
|
1262
|
+
required:
|
|
1263
|
+
- x
|
|
1264
|
+
- 'y'
|
|
1265
|
+
length:
|
|
1266
|
+
type: number
|
|
1267
|
+
height:
|
|
1268
|
+
type: number
|
|
1269
|
+
captureMetadata:
|
|
1270
|
+
type: object
|
|
1271
|
+
properties:
|
|
1272
|
+
identifier:
|
|
1273
|
+
type: string
|
|
1274
|
+
isDoor:
|
|
1275
|
+
type: boolean
|
|
1276
|
+
isOpening:
|
|
1277
|
+
type: boolean
|
|
1278
|
+
captureMethod:
|
|
1279
|
+
type: string
|
|
1240
1280
|
doors:
|
|
1241
1281
|
type: array
|
|
1242
1282
|
items:
|
|
@@ -1249,12 +1289,9 @@ components:
|
|
|
1249
1289
|
type: number
|
|
1250
1290
|
'y':
|
|
1251
1291
|
type: number
|
|
1252
|
-
z:
|
|
1253
|
-
type: number
|
|
1254
1292
|
required:
|
|
1255
1293
|
- x
|
|
1256
1294
|
- 'y'
|
|
1257
|
-
- z
|
|
1258
1295
|
width:
|
|
1259
1296
|
type: number
|
|
1260
1297
|
exclusiveMinimum: 0
|
|
@@ -1296,12 +1333,9 @@ components:
|
|
|
1296
1333
|
type: number
|
|
1297
1334
|
'y':
|
|
1298
1335
|
type: number
|
|
1299
|
-
z:
|
|
1300
|
-
type: number
|
|
1301
1336
|
required:
|
|
1302
1337
|
- x
|
|
1303
1338
|
- 'y'
|
|
1304
|
-
- z
|
|
1305
1339
|
width:
|
|
1306
1340
|
type: number
|
|
1307
1341
|
exclusiveMinimum: 0
|
|
@@ -1338,12 +1372,9 @@ components:
|
|
|
1338
1372
|
type: number
|
|
1339
1373
|
'y':
|
|
1340
1374
|
type: number
|
|
1341
|
-
z:
|
|
1342
|
-
type: number
|
|
1343
1375
|
required:
|
|
1344
1376
|
- x
|
|
1345
1377
|
- 'y'
|
|
1346
|
-
- z
|
|
1347
1378
|
width:
|
|
1348
1379
|
type: number
|
|
1349
1380
|
exclusiveMinimum: 0
|
|
@@ -1368,6 +1399,83 @@ components:
|
|
|
1368
1399
|
- position
|
|
1369
1400
|
- width
|
|
1370
1401
|
- height
|
|
1402
|
+
pins:
|
|
1403
|
+
type: array
|
|
1404
|
+
items:
|
|
1405
|
+
type: object
|
|
1406
|
+
properties:
|
|
1407
|
+
id:
|
|
1408
|
+
type: string
|
|
1409
|
+
minLength: 1
|
|
1410
|
+
maxLength: 128
|
|
1411
|
+
position:
|
|
1412
|
+
type: object
|
|
1413
|
+
properties:
|
|
1414
|
+
x:
|
|
1415
|
+
type: number
|
|
1416
|
+
'y':
|
|
1417
|
+
type: number
|
|
1418
|
+
required:
|
|
1419
|
+
- x
|
|
1420
|
+
- 'y'
|
|
1421
|
+
label:
|
|
1422
|
+
type: string
|
|
1423
|
+
maxLength: 256
|
|
1424
|
+
roomLocalId:
|
|
1425
|
+
type: string
|
|
1426
|
+
maxLength: 128
|
|
1427
|
+
kind:
|
|
1428
|
+
type: string
|
|
1429
|
+
maxLength: 64
|
|
1430
|
+
note:
|
|
1431
|
+
type: string
|
|
1432
|
+
maxLength: 1024
|
|
1433
|
+
required:
|
|
1434
|
+
- id
|
|
1435
|
+
- position
|
|
1436
|
+
objects:
|
|
1437
|
+
type: array
|
|
1438
|
+
items:
|
|
1439
|
+
type: object
|
|
1440
|
+
properties:
|
|
1441
|
+
category:
|
|
1442
|
+
type: string
|
|
1443
|
+
position:
|
|
1444
|
+
type: object
|
|
1445
|
+
properties:
|
|
1446
|
+
x:
|
|
1447
|
+
type: number
|
|
1448
|
+
'y':
|
|
1449
|
+
type: number
|
|
1450
|
+
required:
|
|
1451
|
+
- x
|
|
1452
|
+
- 'y'
|
|
1453
|
+
dimensions:
|
|
1454
|
+
type: object
|
|
1455
|
+
properties:
|
|
1456
|
+
width:
|
|
1457
|
+
type: number
|
|
1458
|
+
height:
|
|
1459
|
+
type: number
|
|
1460
|
+
depth:
|
|
1461
|
+
type: number
|
|
1462
|
+
boundaryPolygon:
|
|
1463
|
+
type: array
|
|
1464
|
+
items:
|
|
1465
|
+
type: object
|
|
1466
|
+
properties:
|
|
1467
|
+
x:
|
|
1468
|
+
type: number
|
|
1469
|
+
'y':
|
|
1470
|
+
type: number
|
|
1471
|
+
required:
|
|
1472
|
+
- x
|
|
1473
|
+
- 'y'
|
|
1474
|
+
roomNote:
|
|
1475
|
+
type: string
|
|
1476
|
+
maxLength: 4096
|
|
1477
|
+
entryDoorwayId:
|
|
1478
|
+
type: string
|
|
1371
1479
|
description: >-
|
|
1372
1480
|
Mobile-upload scan room. `doors`, `windows`, and `openings` are three distinct non-overlapping arrays
|
|
1373
1481
|
— array membership IS the discriminator (there is no `kind` / `type` field on the item itself).
|
|
@@ -1377,6 +1485,11 @@ components:
|
|
|
1377
1485
|
an `entryDoorwayId` target.
|
|
1378
1486
|
required:
|
|
1379
1487
|
- rooms
|
|
1488
|
+
description: >-
|
|
1489
|
+
RoomPlan JSON envelope. `rooms[]` carries the per-room geometry
|
|
1490
|
+
(walls/doors/windows/openings/pins/objects/boundaryPolygon). iOS continues to upload positions in the
|
|
1491
|
+
RoomPlan-native frame; the server applies the view-alignment intake transform once at `/scans/mobile-upload`
|
|
1492
|
+
(see docs/lidar-contract-v4.md).
|
|
1380
1493
|
name:
|
|
1381
1494
|
type: string
|
|
1382
1495
|
minLength: 1
|
|
@@ -1391,8 +1504,27 @@ components:
|
|
|
1391
1504
|
userOrientationHint:
|
|
1392
1505
|
type: string
|
|
1393
1506
|
wallConfidences:
|
|
1394
|
-
|
|
1395
|
-
|
|
1507
|
+
anyOf:
|
|
1508
|
+
- type: array
|
|
1509
|
+
items:
|
|
1510
|
+
type:
|
|
1511
|
+
- array
|
|
1512
|
+
- 'null'
|
|
1513
|
+
items:
|
|
1514
|
+
type: number
|
|
1515
|
+
- type: array
|
|
1516
|
+
items:
|
|
1517
|
+
type: number
|
|
1518
|
+
- type: object
|
|
1519
|
+
additionalProperties:
|
|
1520
|
+
type: array
|
|
1521
|
+
items:
|
|
1522
|
+
type: number
|
|
1523
|
+
description: >-
|
|
1524
|
+
Per-room per-wall capture confidences. Canonical shape: nested `(number[] | null)[]` parallel to
|
|
1525
|
+
`roomPlanJSON.rooms[]`. Two legacy shapes are still accepted for backwards compatibility but should not be
|
|
1526
|
+
emitted by new clients: a flat `number[]` (treated as room[0] confidences) and an object keyed by
|
|
1527
|
+
`roomLocalId` (or numeric index as string). See `normalizeWallConfidences` in `server/routes/lidar.ts`.
|
|
1396
1528
|
deviceTrack: {}
|
|
1397
1529
|
referencePhotos:
|
|
1398
1530
|
type: array
|
|
@@ -1473,12 +1605,42 @@ components:
|
|
|
1473
1605
|
type: string
|
|
1474
1606
|
clientMirrorApplied:
|
|
1475
1607
|
type: boolean
|
|
1608
|
+
parentScanId:
|
|
1609
|
+
type: integer
|
|
1610
|
+
exclusiveMinimum: 0
|
|
1611
|
+
entryDoorwayId:
|
|
1612
|
+
type: string
|
|
1613
|
+
description: >-
|
|
1614
|
+
Append-room doorway link to a target room on the parent composite. Format:
|
|
1615
|
+
`scan-<scanId>-room-<roomLocalId>-(door|opening)-<idx>`. The trailing segment selects kind-specifically —
|
|
1616
|
+
`door` indexes the target room's `doors[]`, `opening` indexes `openings[]`; the two are never folded.
|
|
1617
|
+
`<scanId>` and `<roomLocalId>` must reference a scan + room on the parent composite the iOS client is
|
|
1618
|
+
appending to.
|
|
1619
|
+
entryDoorwayWallIndex:
|
|
1620
|
+
type: integer
|
|
1621
|
+
minimum: 0
|
|
1622
|
+
entryDoorwayPosition:
|
|
1623
|
+
type: object
|
|
1624
|
+
properties:
|
|
1625
|
+
x:
|
|
1626
|
+
type: number
|
|
1627
|
+
'y':
|
|
1628
|
+
type: number
|
|
1629
|
+
required:
|
|
1630
|
+
- x
|
|
1631
|
+
- 'y'
|
|
1476
1632
|
required:
|
|
1477
1633
|
- roomPlanJSON
|
|
1478
1634
|
- name
|
|
1479
1635
|
description: >-
|
|
1480
|
-
POST /api/jobs/:jobId/scans/mobile-upload body.
|
|
1481
|
-
`
|
|
1636
|
+
POST /api/jobs/:jobId/scans/mobile-upload body. v5 of the LiDAR contract (Task #879) — additive over v3/v4.
|
|
1637
|
+
Required: `roomPlanJSON` (object with nested `rooms` array) + `name`. All v3 and v4 payloads remain accepted
|
|
1638
|
+
byte-for-byte. New first-class fields: per-room `roomLocalId`, `pins[]`, `objects[]`, `boundaryPolygon[]`,
|
|
1639
|
+
per-wall `captureMetadata`; append-room `parentScanId`, `entryDoorwayId`, `entryDoorwayWallIndex`,
|
|
1640
|
+
`entryDoorwayPosition`; opening `position` is 2D `{x, y}` (an additional `z` is tolerated for backwards
|
|
1641
|
+
compatibility but ignored by the server). `wallConfidences` advertises the canonical nested `(number[] |
|
|
1642
|
+
null)[]` shape; the two legacy shapes (flat `number[]` and `Record<roomLocalIdOrIndex, number[]>`) are still
|
|
1643
|
+
parsed by `normalizeWallConfidences` in `server/routes/lidar.ts`.
|
|
1482
1644
|
MobileUploadResponse:
|
|
1483
1645
|
type: object
|
|
1484
1646
|
properties:
|
|
@@ -1693,6 +1855,169 @@ components:
|
|
|
1693
1855
|
description: >-
|
|
1694
1856
|
Persisted floor-plan PNG render-frame. `mirrorX` is derived from `scans.client_mirror_applied` (negate when
|
|
1695
1857
|
false). Null sentinel: ANY required column NULL → `null` is emitted instead of a partial frame.
|
|
1858
|
+
ChattyToolDefinition:
|
|
1859
|
+
type: object
|
|
1860
|
+
properties:
|
|
1861
|
+
type:
|
|
1862
|
+
type: string
|
|
1863
|
+
enum:
|
|
1864
|
+
- function
|
|
1865
|
+
function:
|
|
1866
|
+
type: object
|
|
1867
|
+
properties:
|
|
1868
|
+
name:
|
|
1869
|
+
type: string
|
|
1870
|
+
minLength: 1
|
|
1871
|
+
description:
|
|
1872
|
+
type: string
|
|
1873
|
+
parameters:
|
|
1874
|
+
type: object
|
|
1875
|
+
properties:
|
|
1876
|
+
type:
|
|
1877
|
+
type: string
|
|
1878
|
+
enum:
|
|
1879
|
+
- object
|
|
1880
|
+
properties:
|
|
1881
|
+
type: object
|
|
1882
|
+
additionalProperties:
|
|
1883
|
+
allOf:
|
|
1884
|
+
- type: object
|
|
1885
|
+
additionalProperties: {}
|
|
1886
|
+
- type: object
|
|
1887
|
+
properties:
|
|
1888
|
+
type:
|
|
1889
|
+
anyOf:
|
|
1890
|
+
- type: string
|
|
1891
|
+
- type: array
|
|
1892
|
+
items:
|
|
1893
|
+
type: string
|
|
1894
|
+
description:
|
|
1895
|
+
type: string
|
|
1896
|
+
enum:
|
|
1897
|
+
type: array
|
|
1898
|
+
items:
|
|
1899
|
+
type: string
|
|
1900
|
+
required:
|
|
1901
|
+
type: array
|
|
1902
|
+
items:
|
|
1903
|
+
type: string
|
|
1904
|
+
additionalProperties:
|
|
1905
|
+
type: boolean
|
|
1906
|
+
required:
|
|
1907
|
+
- type
|
|
1908
|
+
required:
|
|
1909
|
+
type: array
|
|
1910
|
+
items:
|
|
1911
|
+
type: string
|
|
1912
|
+
additionalProperties:
|
|
1913
|
+
type: boolean
|
|
1914
|
+
required:
|
|
1915
|
+
- type
|
|
1916
|
+
- properties
|
|
1917
|
+
required:
|
|
1918
|
+
- name
|
|
1919
|
+
- description
|
|
1920
|
+
- parameters
|
|
1921
|
+
required:
|
|
1922
|
+
- type
|
|
1923
|
+
- function
|
|
1924
|
+
ChattyExecuteRequest:
|
|
1925
|
+
type: object
|
|
1926
|
+
properties:
|
|
1927
|
+
function:
|
|
1928
|
+
type: string
|
|
1929
|
+
minLength: 1
|
|
1930
|
+
name:
|
|
1931
|
+
type: string
|
|
1932
|
+
minLength: 1
|
|
1933
|
+
arguments:
|
|
1934
|
+
type: object
|
|
1935
|
+
additionalProperties: {}
|
|
1936
|
+
ChattyExecuteResponse:
|
|
1937
|
+
type: object
|
|
1938
|
+
properties:
|
|
1939
|
+
success:
|
|
1940
|
+
type: boolean
|
|
1941
|
+
message:
|
|
1942
|
+
type: string
|
|
1943
|
+
error:
|
|
1944
|
+
type: string
|
|
1945
|
+
code:
|
|
1946
|
+
type: string
|
|
1947
|
+
data: {}
|
|
1948
|
+
action: {}
|
|
1949
|
+
required:
|
|
1950
|
+
- success
|
|
1951
|
+
ChattyAiContextResponse:
|
|
1952
|
+
type: object
|
|
1953
|
+
properties:
|
|
1954
|
+
instructions:
|
|
1955
|
+
type: string
|
|
1956
|
+
knowledgeBaseLoaded:
|
|
1957
|
+
type: boolean
|
|
1958
|
+
workflowStagesLoaded:
|
|
1959
|
+
type: boolean
|
|
1960
|
+
timestamp:
|
|
1961
|
+
type: string
|
|
1962
|
+
required:
|
|
1963
|
+
- instructions
|
|
1964
|
+
- knowledgeBaseLoaded
|
|
1965
|
+
- workflowStagesLoaded
|
|
1966
|
+
- timestamp
|
|
1967
|
+
RealtimeTokenRequest:
|
|
1968
|
+
type: object
|
|
1969
|
+
properties:
|
|
1970
|
+
directWebRTC:
|
|
1971
|
+
type: boolean
|
|
1972
|
+
RealtimeTokenResponse:
|
|
1973
|
+
type: object
|
|
1974
|
+
properties:
|
|
1975
|
+
sessionId:
|
|
1976
|
+
type: string
|
|
1977
|
+
model:
|
|
1978
|
+
type: string
|
|
1979
|
+
voice:
|
|
1980
|
+
type: string
|
|
1981
|
+
clientSecret:
|
|
1982
|
+
type: string
|
|
1983
|
+
fallback:
|
|
1984
|
+
type: boolean
|
|
1985
|
+
directWebRTC:
|
|
1986
|
+
type: boolean
|
|
1987
|
+
useWebRTC:
|
|
1988
|
+
type: boolean
|
|
1989
|
+
expiresInSeconds:
|
|
1990
|
+
type: integer
|
|
1991
|
+
minimum: 0
|
|
1992
|
+
metadata:
|
|
1993
|
+
type: object
|
|
1994
|
+
properties:
|
|
1995
|
+
organizationId:
|
|
1996
|
+
anyOf:
|
|
1997
|
+
- type: string
|
|
1998
|
+
- type: number
|
|
1999
|
+
required:
|
|
2000
|
+
- organizationId
|
|
2001
|
+
message:
|
|
2002
|
+
type: string
|
|
2003
|
+
required:
|
|
2004
|
+
- fallback
|
|
2005
|
+
CsrfTokenResponse:
|
|
2006
|
+
type: object
|
|
2007
|
+
properties:
|
|
2008
|
+
token:
|
|
2009
|
+
type: string
|
|
2010
|
+
minLength: 1
|
|
2011
|
+
required:
|
|
2012
|
+
- token
|
|
2013
|
+
RealtimeWebrtcRequest:
|
|
2014
|
+
type: object
|
|
2015
|
+
properties:
|
|
2016
|
+
sdp:
|
|
2017
|
+
type: string
|
|
2018
|
+
minLength: 1
|
|
2019
|
+
required:
|
|
2020
|
+
- sdp
|
|
1696
2021
|
parameters: {}
|
|
1697
2022
|
paths:
|
|
1698
2023
|
/api/version:
|
|
@@ -2831,12 +3156,9 @@ paths:
|
|
|
2831
3156
|
type: number
|
|
2832
3157
|
'y':
|
|
2833
3158
|
type: number
|
|
2834
|
-
z:
|
|
2835
|
-
type: number
|
|
2836
3159
|
required:
|
|
2837
3160
|
- x
|
|
2838
3161
|
- 'y'
|
|
2839
|
-
- z
|
|
2840
3162
|
width:
|
|
2841
3163
|
type: number
|
|
2842
3164
|
exclusiveMinimum: 0
|
|
@@ -2876,12 +3198,9 @@ paths:
|
|
|
2876
3198
|
type: number
|
|
2877
3199
|
'y':
|
|
2878
3200
|
type: number
|
|
2879
|
-
z:
|
|
2880
|
-
type: number
|
|
2881
3201
|
required:
|
|
2882
3202
|
- x
|
|
2883
3203
|
- 'y'
|
|
2884
|
-
- z
|
|
2885
3204
|
width:
|
|
2886
3205
|
type: number
|
|
2887
3206
|
exclusiveMinimum: 0
|
|
@@ -2921,12 +3240,9 @@ paths:
|
|
|
2921
3240
|
type: number
|
|
2922
3241
|
'y':
|
|
2923
3242
|
type: number
|
|
2924
|
-
z:
|
|
2925
|
-
type: number
|
|
2926
3243
|
required:
|
|
2927
3244
|
- x
|
|
2928
3245
|
- 'y'
|
|
2929
|
-
- z
|
|
2930
3246
|
width:
|
|
2931
3247
|
type: number
|
|
2932
3248
|
exclusiveMinimum: 0
|
|
@@ -3081,12 +3397,9 @@ paths:
|
|
|
3081
3397
|
type: number
|
|
3082
3398
|
'y':
|
|
3083
3399
|
type: number
|
|
3084
|
-
z:
|
|
3085
|
-
type: number
|
|
3086
3400
|
required:
|
|
3087
3401
|
- x
|
|
3088
3402
|
- 'y'
|
|
3089
|
-
- z
|
|
3090
3403
|
width:
|
|
3091
3404
|
type: number
|
|
3092
3405
|
exclusiveMinimum: 0
|
|
@@ -3126,12 +3439,9 @@ paths:
|
|
|
3126
3439
|
type: number
|
|
3127
3440
|
'y':
|
|
3128
3441
|
type: number
|
|
3129
|
-
z:
|
|
3130
|
-
type: number
|
|
3131
3442
|
required:
|
|
3132
3443
|
- x
|
|
3133
3444
|
- 'y'
|
|
3134
|
-
- z
|
|
3135
3445
|
width:
|
|
3136
3446
|
type: number
|
|
3137
3447
|
exclusiveMinimum: 0
|
|
@@ -3171,12 +3481,9 @@ paths:
|
|
|
3171
3481
|
type: number
|
|
3172
3482
|
'y':
|
|
3173
3483
|
type: number
|
|
3174
|
-
z:
|
|
3175
|
-
type: number
|
|
3176
3484
|
required:
|
|
3177
3485
|
- x
|
|
3178
3486
|
- 'y'
|
|
3179
|
-
- z
|
|
3180
3487
|
width:
|
|
3181
3488
|
type: number
|
|
3182
3489
|
exclusiveMinimum: 0
|
|
@@ -3243,4 +3550,469 @@ paths:
|
|
|
3243
3550
|
application/json:
|
|
3244
3551
|
schema:
|
|
3245
3552
|
$ref: '#/components/schemas/ErrorEnvelope'
|
|
3553
|
+
/api/chatty-voice/tools:
|
|
3554
|
+
get:
|
|
3555
|
+
summary: List the OpenAI-Realtime-compatible function tools the executor can run.
|
|
3556
|
+
description: >-
|
|
3557
|
+
Returns the canonical Chatty Voice tool catalogue as a BARE ARRAY of `ChattyToolDefinition` envelopes (no
|
|
3558
|
+
wrapping object). Each entry is executable via POST /api/chatty-voice/tools/execute.
|
|
3559
|
+
tags:
|
|
3560
|
+
- chatty
|
|
3561
|
+
parameters:
|
|
3562
|
+
- *ref_2
|
|
3563
|
+
responses:
|
|
3564
|
+
'200':
|
|
3565
|
+
description: Bare array of tool definitions.
|
|
3566
|
+
content:
|
|
3567
|
+
application/json:
|
|
3568
|
+
schema:
|
|
3569
|
+
type: array
|
|
3570
|
+
items:
|
|
3571
|
+
type: object
|
|
3572
|
+
properties:
|
|
3573
|
+
type:
|
|
3574
|
+
type: string
|
|
3575
|
+
enum:
|
|
3576
|
+
- function
|
|
3577
|
+
function:
|
|
3578
|
+
type: object
|
|
3579
|
+
properties:
|
|
3580
|
+
name:
|
|
3581
|
+
type: string
|
|
3582
|
+
minLength: 1
|
|
3583
|
+
description:
|
|
3584
|
+
type: string
|
|
3585
|
+
parameters:
|
|
3586
|
+
type: object
|
|
3587
|
+
properties:
|
|
3588
|
+
type:
|
|
3589
|
+
type: string
|
|
3590
|
+
enum:
|
|
3591
|
+
- object
|
|
3592
|
+
properties:
|
|
3593
|
+
type: object
|
|
3594
|
+
additionalProperties:
|
|
3595
|
+
allOf:
|
|
3596
|
+
- type: object
|
|
3597
|
+
additionalProperties: {}
|
|
3598
|
+
- type: object
|
|
3599
|
+
properties:
|
|
3600
|
+
type:
|
|
3601
|
+
anyOf:
|
|
3602
|
+
- type: string
|
|
3603
|
+
- type: array
|
|
3604
|
+
items:
|
|
3605
|
+
type: string
|
|
3606
|
+
description:
|
|
3607
|
+
type: string
|
|
3608
|
+
enum:
|
|
3609
|
+
type: array
|
|
3610
|
+
items:
|
|
3611
|
+
type: string
|
|
3612
|
+
required:
|
|
3613
|
+
type: array
|
|
3614
|
+
items:
|
|
3615
|
+
type: string
|
|
3616
|
+
additionalProperties:
|
|
3617
|
+
type: boolean
|
|
3618
|
+
required:
|
|
3619
|
+
- type
|
|
3620
|
+
required:
|
|
3621
|
+
type: array
|
|
3622
|
+
items:
|
|
3623
|
+
type: string
|
|
3624
|
+
additionalProperties:
|
|
3625
|
+
type: boolean
|
|
3626
|
+
required:
|
|
3627
|
+
- type
|
|
3628
|
+
- properties
|
|
3629
|
+
required:
|
|
3630
|
+
- name
|
|
3631
|
+
- description
|
|
3632
|
+
- parameters
|
|
3633
|
+
required:
|
|
3634
|
+
- type
|
|
3635
|
+
- function
|
|
3636
|
+
'401':
|
|
3637
|
+
description: Unauthenticated.
|
|
3638
|
+
content:
|
|
3639
|
+
application/json:
|
|
3640
|
+
schema:
|
|
3641
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
3642
|
+
'403':
|
|
3643
|
+
description: Caller lacks the chatty-voice entitlement.
|
|
3644
|
+
content:
|
|
3645
|
+
application/json:
|
|
3646
|
+
schema:
|
|
3647
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
3648
|
+
'426':
|
|
3649
|
+
description: Client major below minClientVersion.
|
|
3650
|
+
content:
|
|
3651
|
+
application/json:
|
|
3652
|
+
schema:
|
|
3653
|
+
$ref: '#/components/schemas/UpgradeRequiredEnvelope'
|
|
3654
|
+
/api/chatty-voice/tools/execute:
|
|
3655
|
+
post:
|
|
3656
|
+
summary: Execute a Chatty Voice tool by canonical `function` (or legacy `name`).
|
|
3657
|
+
description: >-
|
|
3658
|
+
Body accepts either the canonical `function` field or the legacy `name` alias — at least one is required. The
|
|
3659
|
+
executor treats them as equivalent and dispatches to the same switch case in `tools.ts`. Tool arguments are
|
|
3660
|
+
passed through verbatim as an opaque JSON object.
|
|
3661
|
+
tags:
|
|
3662
|
+
- chatty
|
|
3663
|
+
parameters:
|
|
3664
|
+
- *ref_2
|
|
3665
|
+
requestBody:
|
|
3666
|
+
content:
|
|
3667
|
+
application/json:
|
|
3668
|
+
schema:
|
|
3669
|
+
type: object
|
|
3670
|
+
properties:
|
|
3671
|
+
function:
|
|
3672
|
+
type: string
|
|
3673
|
+
minLength: 1
|
|
3674
|
+
name:
|
|
3675
|
+
type: string
|
|
3676
|
+
minLength: 1
|
|
3677
|
+
arguments:
|
|
3678
|
+
type: object
|
|
3679
|
+
additionalProperties: {}
|
|
3680
|
+
responses:
|
|
3681
|
+
'200':
|
|
3682
|
+
description: >-
|
|
3683
|
+
Always returned when execution reaches the executor. `success: false` envelopes carry an `error` and (for
|
|
3684
|
+
permission denials) a `code` — including the missing/unknown function case.
|
|
3685
|
+
content:
|
|
3686
|
+
application/json:
|
|
3687
|
+
schema:
|
|
3688
|
+
type: object
|
|
3689
|
+
properties:
|
|
3690
|
+
success:
|
|
3691
|
+
type: boolean
|
|
3692
|
+
message:
|
|
3693
|
+
type: string
|
|
3694
|
+
error:
|
|
3695
|
+
type: string
|
|
3696
|
+
code:
|
|
3697
|
+
type: string
|
|
3698
|
+
data: {}
|
|
3699
|
+
action: {}
|
|
3700
|
+
required:
|
|
3701
|
+
- success
|
|
3702
|
+
'401':
|
|
3703
|
+
description: Unauthenticated.
|
|
3704
|
+
content:
|
|
3705
|
+
application/json:
|
|
3706
|
+
schema:
|
|
3707
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
3708
|
+
'403':
|
|
3709
|
+
description: Caller lacks the chatty-voice entitlement or a per-tool permission.
|
|
3710
|
+
content:
|
|
3711
|
+
application/json:
|
|
3712
|
+
schema:
|
|
3713
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
3714
|
+
'500':
|
|
3715
|
+
description: 'Unhandled executor error. Body is `{ success: false, error }` (same envelope as 200).'
|
|
3716
|
+
content:
|
|
3717
|
+
application/json:
|
|
3718
|
+
schema:
|
|
3719
|
+
type: object
|
|
3720
|
+
properties:
|
|
3721
|
+
success:
|
|
3722
|
+
type: boolean
|
|
3723
|
+
message:
|
|
3724
|
+
type: string
|
|
3725
|
+
error:
|
|
3726
|
+
type: string
|
|
3727
|
+
code:
|
|
3728
|
+
type: string
|
|
3729
|
+
data: {}
|
|
3730
|
+
action: {}
|
|
3731
|
+
required:
|
|
3732
|
+
- success
|
|
3733
|
+
/api/chatty-voice/ai-context:
|
|
3734
|
+
get:
|
|
3735
|
+
summary: Fetch the Chatty Voice system prompt + load-status flags.
|
|
3736
|
+
tags:
|
|
3737
|
+
- chatty
|
|
3738
|
+
parameters:
|
|
3739
|
+
- *ref_2
|
|
3740
|
+
responses:
|
|
3741
|
+
'200':
|
|
3742
|
+
description: System instructions + knowledge-base / workflow-stage load flags.
|
|
3743
|
+
content:
|
|
3744
|
+
application/json:
|
|
3745
|
+
schema:
|
|
3746
|
+
type: object
|
|
3747
|
+
properties:
|
|
3748
|
+
instructions:
|
|
3749
|
+
type: string
|
|
3750
|
+
knowledgeBaseLoaded:
|
|
3751
|
+
type: boolean
|
|
3752
|
+
workflowStagesLoaded:
|
|
3753
|
+
type: boolean
|
|
3754
|
+
timestamp:
|
|
3755
|
+
type: string
|
|
3756
|
+
required:
|
|
3757
|
+
- instructions
|
|
3758
|
+
- knowledgeBaseLoaded
|
|
3759
|
+
- workflowStagesLoaded
|
|
3760
|
+
- timestamp
|
|
3761
|
+
'401':
|
|
3762
|
+
description: Unauthenticated.
|
|
3763
|
+
content:
|
|
3764
|
+
application/json:
|
|
3765
|
+
schema:
|
|
3766
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
3767
|
+
'403':
|
|
3768
|
+
description: Caller lacks the chatty-voice entitlement.
|
|
3769
|
+
content:
|
|
3770
|
+
application/json:
|
|
3771
|
+
schema:
|
|
3772
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
3773
|
+
/api/realtime-token:
|
|
3774
|
+
post:
|
|
3775
|
+
summary: Mint an OpenAI Realtime ephemeral session token (single union object).
|
|
3776
|
+
description: >-
|
|
3777
|
+
Body: `{ directWebRTC?: boolean }`. Response is a SINGLE union object — the directWebRTC, desktop
|
|
3778
|
+
server-proxied, and HTTP-fallback branches all share the same envelope. Only `fallback` is always present; every
|
|
3779
|
+
other field is optional and presence depends on the branch.
|
|
3780
|
+
tags:
|
|
3781
|
+
- chatty
|
|
3782
|
+
parameters:
|
|
3783
|
+
- *ref_2
|
|
3784
|
+
requestBody:
|
|
3785
|
+
content:
|
|
3786
|
+
application/json:
|
|
3787
|
+
schema:
|
|
3788
|
+
type: object
|
|
3789
|
+
properties:
|
|
3790
|
+
directWebRTC:
|
|
3791
|
+
type: boolean
|
|
3792
|
+
responses:
|
|
3793
|
+
'200':
|
|
3794
|
+
description: Session minted (or fallback signalled). See union shape.
|
|
3795
|
+
content:
|
|
3796
|
+
application/json:
|
|
3797
|
+
schema:
|
|
3798
|
+
type: object
|
|
3799
|
+
properties:
|
|
3800
|
+
sessionId:
|
|
3801
|
+
type: string
|
|
3802
|
+
model:
|
|
3803
|
+
type: string
|
|
3804
|
+
voice:
|
|
3805
|
+
type: string
|
|
3806
|
+
clientSecret:
|
|
3807
|
+
type: string
|
|
3808
|
+
fallback:
|
|
3809
|
+
type: boolean
|
|
3810
|
+
directWebRTC:
|
|
3811
|
+
type: boolean
|
|
3812
|
+
useWebRTC:
|
|
3813
|
+
type: boolean
|
|
3814
|
+
expiresInSeconds:
|
|
3815
|
+
type: integer
|
|
3816
|
+
minimum: 0
|
|
3817
|
+
metadata:
|
|
3818
|
+
type: object
|
|
3819
|
+
properties:
|
|
3820
|
+
organizationId:
|
|
3821
|
+
anyOf:
|
|
3822
|
+
- type: string
|
|
3823
|
+
- type: number
|
|
3824
|
+
required:
|
|
3825
|
+
- organizationId
|
|
3826
|
+
message:
|
|
3827
|
+
type: string
|
|
3828
|
+
required:
|
|
3829
|
+
- fallback
|
|
3830
|
+
'401':
|
|
3831
|
+
description: Unauthenticated.
|
|
3832
|
+
content:
|
|
3833
|
+
application/json:
|
|
3834
|
+
schema:
|
|
3835
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
3836
|
+
'403':
|
|
3837
|
+
description: Caller lacks the chatty-voice entitlement.
|
|
3838
|
+
content:
|
|
3839
|
+
application/json:
|
|
3840
|
+
schema:
|
|
3841
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
3842
|
+
'405':
|
|
3843
|
+
description: Method Not Allowed (POST only).
|
|
3844
|
+
content:
|
|
3845
|
+
application/json:
|
|
3846
|
+
schema:
|
|
3847
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
3848
|
+
'429':
|
|
3849
|
+
description: Per-user rate limit on token mint.
|
|
3850
|
+
content:
|
|
3851
|
+
application/json:
|
|
3852
|
+
schema:
|
|
3853
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
3854
|
+
'500':
|
|
3855
|
+
description: 'Mint failure — body still carries `fallback: true`.'
|
|
3856
|
+
content:
|
|
3857
|
+
application/json:
|
|
3858
|
+
schema:
|
|
3859
|
+
type: object
|
|
3860
|
+
properties:
|
|
3861
|
+
sessionId:
|
|
3862
|
+
type: string
|
|
3863
|
+
model:
|
|
3864
|
+
type: string
|
|
3865
|
+
voice:
|
|
3866
|
+
type: string
|
|
3867
|
+
clientSecret:
|
|
3868
|
+
type: string
|
|
3869
|
+
fallback:
|
|
3870
|
+
type: boolean
|
|
3871
|
+
directWebRTC:
|
|
3872
|
+
type: boolean
|
|
3873
|
+
useWebRTC:
|
|
3874
|
+
type: boolean
|
|
3875
|
+
expiresInSeconds:
|
|
3876
|
+
type: integer
|
|
3877
|
+
minimum: 0
|
|
3878
|
+
metadata:
|
|
3879
|
+
type: object
|
|
3880
|
+
properties:
|
|
3881
|
+
organizationId:
|
|
3882
|
+
anyOf:
|
|
3883
|
+
- type: string
|
|
3884
|
+
- type: number
|
|
3885
|
+
required:
|
|
3886
|
+
- organizationId
|
|
3887
|
+
message:
|
|
3888
|
+
type: string
|
|
3889
|
+
required:
|
|
3890
|
+
- fallback
|
|
3891
|
+
/api/csrf-token:
|
|
3892
|
+
get:
|
|
3893
|
+
summary: Mint a short-lived CSRF token for the WebRTC SDP exchange.
|
|
3894
|
+
description: >-
|
|
3895
|
+
Returned token is required as `X-CSRF-Token` on POST /api/realtime/webrtc and is bound to the calling user for 5
|
|
3896
|
+
minutes.
|
|
3897
|
+
tags:
|
|
3898
|
+
- chatty
|
|
3899
|
+
parameters:
|
|
3900
|
+
- *ref_2
|
|
3901
|
+
responses:
|
|
3902
|
+
'200':
|
|
3903
|
+
description: Fresh CSRF token.
|
|
3904
|
+
content:
|
|
3905
|
+
application/json:
|
|
3906
|
+
schema:
|
|
3907
|
+
type: object
|
|
3908
|
+
properties:
|
|
3909
|
+
token:
|
|
3910
|
+
type: string
|
|
3911
|
+
minLength: 1
|
|
3912
|
+
required:
|
|
3913
|
+
- token
|
|
3914
|
+
'401':
|
|
3915
|
+
description: Unauthenticated.
|
|
3916
|
+
content:
|
|
3917
|
+
application/json:
|
|
3918
|
+
schema:
|
|
3919
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
3920
|
+
'403':
|
|
3921
|
+
description: Caller lacks the chatty-voice entitlement.
|
|
3922
|
+
content:
|
|
3923
|
+
application/json:
|
|
3924
|
+
schema:
|
|
3925
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
3926
|
+
/api/realtime/webrtc:
|
|
3927
|
+
post:
|
|
3928
|
+
summary: Server-proxied OpenAI Realtime SDP exchange (desktop branch).
|
|
3929
|
+
description: >-
|
|
3930
|
+
Request body is JSON `{ sdp }`; the server mints a fresh OpenAI ephemeral client_secret, forwards the raw SDP to
|
|
3931
|
+
OpenAI's WebRTC endpoint, and returns the raw SDP answer as `application/sdp` text. CSRF-protected via
|
|
3932
|
+
`X-CSRF-Token` (see GET /api/csrf-token) and rate-limited to 3 req/min/IP.
|
|
3933
|
+
tags:
|
|
3934
|
+
- chatty
|
|
3935
|
+
parameters:
|
|
3936
|
+
- *ref_2
|
|
3937
|
+
- name: X-CSRF-Token
|
|
3938
|
+
in: header
|
|
3939
|
+
required: true
|
|
3940
|
+
schema:
|
|
3941
|
+
type: string
|
|
3942
|
+
description: CSRF token previously minted by GET /api/csrf-token.
|
|
3943
|
+
requestBody:
|
|
3944
|
+
content:
|
|
3945
|
+
application/json:
|
|
3946
|
+
schema:
|
|
3947
|
+
type: object
|
|
3948
|
+
properties:
|
|
3949
|
+
sdp:
|
|
3950
|
+
type: string
|
|
3951
|
+
minLength: 1
|
|
3952
|
+
required:
|
|
3953
|
+
- sdp
|
|
3954
|
+
responses:
|
|
3955
|
+
'200':
|
|
3956
|
+
description: Raw OpenAI SDP answer (text body, not JSON).
|
|
3957
|
+
content:
|
|
3958
|
+
application/sdp:
|
|
3959
|
+
schema:
|
|
3960
|
+
type: string
|
|
3961
|
+
'400':
|
|
3962
|
+
description: Invalid SDP format.
|
|
3963
|
+
content:
|
|
3964
|
+
application/json:
|
|
3965
|
+
schema:
|
|
3966
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
3967
|
+
'401':
|
|
3968
|
+
description: Unauthenticated.
|
|
3969
|
+
content:
|
|
3970
|
+
application/json:
|
|
3971
|
+
schema:
|
|
3972
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
3973
|
+
'403':
|
|
3974
|
+
description: Caller lacks the chatty-voice entitlement, or CSRF token invalid.
|
|
3975
|
+
content:
|
|
3976
|
+
application/json:
|
|
3977
|
+
schema:
|
|
3978
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
3979
|
+
'429':
|
|
3980
|
+
description: Rate limit (3 req/min/IP).
|
|
3981
|
+
content:
|
|
3982
|
+
application/json:
|
|
3983
|
+
schema:
|
|
3984
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
3985
|
+
'500':
|
|
3986
|
+
description: SDP exchange failed locally.
|
|
3987
|
+
content:
|
|
3988
|
+
application/json:
|
|
3989
|
+
schema:
|
|
3990
|
+
$ref: '#/components/schemas/ErrorEnvelope'
|
|
3991
|
+
'502':
|
|
3992
|
+
description: >-
|
|
3993
|
+
Local failure minting the OpenAI ephemeral client_secret required to authenticate the SDP exchange. Returned
|
|
3994
|
+
as a JSON envelope generated by this server: `{ error, status? }`.
|
|
3995
|
+
content:
|
|
3996
|
+
application/json:
|
|
3997
|
+
schema:
|
|
3998
|
+
type: object
|
|
3999
|
+
properties:
|
|
4000
|
+
error:
|
|
4001
|
+
type: string
|
|
4002
|
+
status:
|
|
4003
|
+
type: integer
|
|
4004
|
+
required:
|
|
4005
|
+
- error
|
|
4006
|
+
default:
|
|
4007
|
+
description: >-
|
|
4008
|
+
Upstream OpenAI SDP exchange error. Pass-through: this endpoint forwards OpenAI's HTTP status verbatim
|
|
4009
|
+
(typically 4xx/5xx) and the body is OpenAI's raw error payload — NOT a JSON envelope generated by this
|
|
4010
|
+
server. Content-Type and exact shape are determined by OpenAI; clients MUST treat any non-200 response on
|
|
4011
|
+
this endpoint as opaque error text unless they explicitly detect the 502 JSON envelope above.
|
|
4012
|
+
content:
|
|
4013
|
+
application/json:
|
|
4014
|
+
schema: {}
|
|
4015
|
+
text/plain:
|
|
4016
|
+
schema:
|
|
4017
|
+
type: string
|
|
3246
4018
|
webhooks: {}
|