Merge remote-tracking branch 'origin/main' into fix/call-concurrency-limit

# Conflicts:
#	api/services/auth/depends.py
#	docs/api-reference/openapi.json
#	sdk/python/src/dograh_sdk/_generated_models.py
This commit is contained in:
Abhishek Kumar 2026-07-09 18:26:20 +05:30
commit d3326d8fad
57 changed files with 1163 additions and 1354 deletions

170
ui/package-lock.json generated
View file

@ -1,12 +1,12 @@
{
"name": "ui",
"version": "1.39.0",
"version": "1.40.0",
"lockfileVersion": 3,
"requires": true,
"packages": {
"": {
"name": "ui",
"version": "1.39.0",
"version": "1.40.0",
"dependencies": {
"@calcom/embed-react": "^1.5.3",
"@dagrejs/dagre": "^1.1.4",
@ -482,7 +482,6 @@
"resolved": "https://registry.npmjs.org/@babel/core/-/core-7.29.7.tgz",
"integrity": "sha512-RgHBCvtjbOK2gXSNBNIkNoEc9qoVEtau3hj8gEqKQuL3HZAibKarWFEI3Lfm6EYKkLalOh8eSrj9b+ch9H/VBA==",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/code-frame": "^7.29.7",
"@babel/generator": "^7.29.7",
@ -669,6 +668,7 @@
"resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.27.0.tgz",
"integrity": "sha512-VtPOkrdPHZsKc/clNqyi9WUA8TINkZ4cGk63UUE3u4pmB2k+ZMQRDuIOagv8UVd6j7k0T3+RRIb7beKTebNbcw==",
"license": "MIT",
"peer": true,
"dependencies": {
"regenerator-runtime": "^0.14.0"
},
@ -812,6 +812,7 @@
"resolved": "https://registry.npmjs.org/@emotion/babel-plugin/-/babel-plugin-11.13.5.tgz",
"integrity": "sha512-pxHCpT2ex+0q+HH91/zsdHkw/lXd468DIN2zvfvLtPKLLMo6gQj7oLObq8PhkrxOZb/gGCq03S3Z7PDhS8pduQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/helper-module-imports": "^7.16.7",
"@babel/runtime": "^7.18.3",
@ -830,13 +831,15 @@
"version": "1.9.0",
"resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.9.0.tgz",
"integrity": "sha512-ASFBup0Mz1uyiIjANan1jzLQami9z1PoYSZCiiYW2FczPbenXc45FZdBZLzOT+r6+iciuEModtmCti+hjaAk0A==",
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/@emotion/babel-plugin/node_modules/source-map": {
"version": "0.5.7",
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz",
"integrity": "sha512-LbrmJOMUSdEVxIKvdcJzQC+nQhe8FUZQTXQy6+I75skNgn3OoQ0DZA8YnFa7gp8tqtL3KPf1kmo0R5DoApeSGQ==",
"license": "BSD-3-Clause",
"peer": true,
"engines": {
"node": ">=0.10.0"
}
@ -846,6 +849,7 @@
"resolved": "https://registry.npmjs.org/@emotion/cache/-/cache-11.14.0.tgz",
"integrity": "sha512-L/B1lc/TViYk4DcpGxtAVbx0ZyiKM5ktoIyafGkH6zg/tj+mA+NE//aPYKG0k8kCHSHVJrpLpcAlOBEXQ3SavA==",
"license": "MIT",
"peer": true,
"dependencies": {
"@emotion/memoize": "^0.9.0",
"@emotion/sheet": "^1.4.0",
@ -858,19 +862,22 @@
"version": "0.9.2",
"resolved": "https://registry.npmjs.org/@emotion/hash/-/hash-0.9.2.tgz",
"integrity": "sha512-MyqliTZGuOm3+5ZRSaaBGP3USLw6+EGykkwZns2EPC5g8jJ4z9OrdZY9apkl3+UP9+sdz76YYkwCKP5gh8iY3g==",
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/@emotion/memoize": {
"version": "0.9.0",
"resolved": "https://registry.npmjs.org/@emotion/memoize/-/memoize-0.9.0.tgz",
"integrity": "sha512-30FAj7/EoJ5mwVPOWhAyCX+FPfMDrVecJAM+Iw9NRoSl4BBAQeqj4cApHHUXOVvIPgLVDsCFoz/hGD+5QQD1GQ==",
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/@emotion/react": {
"version": "11.14.0",
"resolved": "https://registry.npmjs.org/@emotion/react/-/react-11.14.0.tgz",
"integrity": "sha512-O000MLDBDdk/EohJPFUqvnp4qnHeYkVP5B0xEG0D/L7cOKP9kefu2DXn8dj74cQfsEzUqh+sr1RzFqiL1o+PpA==",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/runtime": "^7.18.3",
"@emotion/babel-plugin": "^11.13.5",
@ -895,6 +902,7 @@
"resolved": "https://registry.npmjs.org/@emotion/serialize/-/serialize-1.3.3.tgz",
"integrity": "sha512-EISGqt7sSNWHGI76hC7x1CksiXPahbxEOrC5RjmFRJTqLyEK9/9hZvBbiYn70dw4wuwMKiEMCUlR6ZXTSWQqxA==",
"license": "MIT",
"peer": true,
"dependencies": {
"@emotion/hash": "^0.9.2",
"@emotion/memoize": "^0.9.0",
@ -907,19 +915,22 @@
"version": "1.4.0",
"resolved": "https://registry.npmjs.org/@emotion/sheet/-/sheet-1.4.0.tgz",
"integrity": "sha512-fTBW9/8r2w3dXWYM4HCB1Rdp8NLibOw2+XELH5m5+AkWiL/KqYX6dc0kKYlaYyKjrQ6ds33MCdMPEwgs2z1rqg==",
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/@emotion/unitless": {
"version": "0.10.0",
"resolved": "https://registry.npmjs.org/@emotion/unitless/-/unitless-0.10.0.tgz",
"integrity": "sha512-dFoMUuQA20zvtVTuxZww6OHoJYgrzfKM1t52mVySDJnMSEa08ruEvdYQbhvyu6soU+NeLVd3yKfTfT0NeV6qGg==",
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/@emotion/use-insertion-effect-with-fallbacks": {
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@emotion/use-insertion-effect-with-fallbacks/-/use-insertion-effect-with-fallbacks-1.2.0.tgz",
"integrity": "sha512-yJMtVdH59sxi/aVJBpk9FQq+OR8ll5GT8oWd57UpeaKEVGab41JWaCFA7FRLoMLloOZF/c/wsPoe+bfGmRKgDg==",
"license": "MIT",
"peer": true,
"peerDependencies": {
"react": ">=16.8.0"
}
@ -928,13 +939,15 @@
"version": "1.4.2",
"resolved": "https://registry.npmjs.org/@emotion/utils/-/utils-1.4.2.tgz",
"integrity": "sha512-3vLclRofFziIa3J2wDh9jjbkUz9qk5Vi3IZ/FSTKViB0k+ef0fPV7dYrUIugbgupYDx7v9ud/SjrtEP8Y4xLoA==",
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/@emotion/weak-memoize": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/@emotion/weak-memoize/-/weak-memoize-0.4.0.tgz",
"integrity": "sha512-snKqtPW01tN0ui7yu9rGv69aJXr/a/Ywvl11sUjNtEcRc+ng/mQriFL0wLXMef74iHa/EkftbDzU9F8iFbH+zg==",
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/@esbuild/aix-ppc64": {
"version": "0.27.7",
@ -2223,6 +2236,7 @@
"resolved": "https://registry.npmjs.org/@jridgewell/source-map/-/source-map-0.3.11.tgz",
"integrity": "sha512-ZMp1V8ZFcPG5dIWnQLr3NSI1MiCU7UETdS/A0G8V/XWHvJv3ZsFqutJn1Y5RPmAPX6F3BiE397OqveU/9NCuIA==",
"license": "MIT",
"peer": true,
"dependencies": {
"@jridgewell/gen-mapping": "^0.3.5",
"@jridgewell/trace-mapping": "^0.3.25"
@ -2471,7 +2485,6 @@
"resolved": "https://registry.npmjs.org/@opentelemetry/api/-/api-1.9.1.tgz",
"integrity": "sha512-gLyJlPHPZYdAk1JENA9LeHejZe1Ti77/pTeFm/nMXmQH/HFZlcS/O2XJB+L8fkbrNSqhdtlvjBVjxwUYanNH5Q==",
"license": "Apache-2.0",
"peer": true,
"engines": {
"node": ">=8.0.0"
}
@ -2493,7 +2506,6 @@
"resolved": "https://registry.npmjs.org/@opentelemetry/core/-/core-2.9.0.tgz",
"integrity": "sha512-m2nckMT80NnmjTYSPjJQObBJ+8dgkoajEOUbznL8AHZ3T3yHRk2P7gI1PhEBc1+lOnrYE9UWrWHqJDsmqjmNbw==",
"license": "Apache-2.0",
"peer": true,
"dependencies": {
"@opentelemetry/semantic-conventions": "^1.29.0"
},
@ -2509,7 +2521,6 @@
"resolved": "https://registry.npmjs.org/@opentelemetry/instrumentation/-/instrumentation-0.214.0.tgz",
"integrity": "sha512-MHqEX5Dk59cqVah5LiARMACku7jXSVk9iVDWOea4x3cr7VfdByeDCURK6o1lntT1JS/Tsovw01UJrBhN3/uC5w==",
"license": "Apache-2.0",
"peer": true,
"dependencies": {
"@opentelemetry/api-logs": "0.214.0",
"import-in-the-middle": "^3.0.0",
@ -2560,7 +2571,6 @@
"resolved": "https://registry.npmjs.org/@opentelemetry/sdk-trace-base/-/sdk-trace-base-2.9.0.tgz",
"integrity": "sha512-cp9zmTl62R8PJrpvFcmc8N2JQU/xfa0S+61q511Nji+QxCfZ8Ifvg7H27G8cANe4crg4RTrWsVvanHiXjSp6ag==",
"license": "Apache-2.0",
"peer": true,
"dependencies": {
"@opentelemetry/core": "2.9.0",
"@opentelemetry/resources": "2.9.0",
@ -8545,7 +8555,6 @@
"resolved": "https://registry.npmjs.org/picomatch/-/picomatch-4.0.4.tgz",
"integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=12"
},
@ -9740,7 +9749,6 @@
"resolved": "https://registry.npmjs.org/@stripe/stripe-js/-/stripe-js-7.9.0.tgz",
"integrity": "sha512-ggs5k+/0FUJcIgNY08aZTqpBTtbExkJMYMLSMwyucrhtWexVOEY1KJmhBsxf+E/Q15f5rbwBpj+t0t2AW2oCsQ==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=12.16"
}
@ -10176,14 +10184,14 @@
"version": "4.0.2",
"resolved": "https://registry.npmjs.org/@types/parse-json/-/parse-json-4.0.2.tgz",
"integrity": "sha512-dISoDXWWQwUquiKsyZ4Ng+HX2KsPL7LyHKHQwgGFEA3IaKac4Obd+h2a/a6waisAoepJlBcx9paWqjA8/HVjCw==",
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/@types/react": {
"version": "19.1.0",
"resolved": "https://registry.npmjs.org/@types/react/-/react-19.1.0.tgz",
"integrity": "sha512-UaicktuQI+9UKyA4njtDOGBD/67t8YEBt2xdfqu8+gP9hqPUPsiXlNPcpS2gVdjmis5GKPG3fCxbQLVgxsQZ8w==",
"license": "MIT",
"peer": true,
"dependencies": {
"csstype": "^3.0.2"
}
@ -10194,7 +10202,6 @@
"integrity": "sha512-jFf/woGTVTjUJsl2O7hcopJ1r0upqoq/vIOoCj0yLh3RIXxWcljlpuZ+vEBRXsymD1jhfeJrlyTy/S1UW+4y1w==",
"devOptional": true,
"license": "MIT",
"peer": true,
"peerDependencies": {
"@types/react": "^19.0.0"
}
@ -10204,6 +10211,7 @@
"resolved": "https://registry.npmjs.org/@types/react-transition-group/-/react-transition-group-4.4.12.tgz",
"integrity": "sha512-8TV6R3h2j7a91c+1DXdJi3Syo69zzIZbz7Lg5tORM5LEJG7X/E6a1V3drRyBRZq7/utz7A+c4OgYLiLcYGHG6w==",
"license": "MIT",
"peer": true,
"peerDependencies": {
"@types/react": "*"
}
@ -10718,6 +10726,7 @@
"resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.14.1.tgz",
"integrity": "sha512-nuBEDgQfm1ccRp/8bCQrx1frohyufl4JlbMMZ4P1wpeOfDhF6FQkxZJ1b/e+PLwr6X1Nhw6OLme5usuBWYBvuQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"@webassemblyjs/helper-numbers": "1.13.2",
"@webassemblyjs/helper-wasm-bytecode": "1.13.2"
@ -10727,25 +10736,29 @@
"version": "1.13.2",
"resolved": "https://registry.npmjs.org/@webassemblyjs/floating-point-hex-parser/-/floating-point-hex-parser-1.13.2.tgz",
"integrity": "sha512-6oXyTOzbKxGH4steLbLNOu71Oj+C8Lg34n6CqRvqfS2O71BxY6ByfMDRhBytzknj9yGUPVJ1qIKhRlAwO1AovA==",
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/@webassemblyjs/helper-api-error": {
"version": "1.13.2",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-api-error/-/helper-api-error-1.13.2.tgz",
"integrity": "sha512-U56GMYxy4ZQCbDZd6JuvvNV/WFildOjsaWD3Tzzvmw/mas3cXzRJPMjP83JqEsgSbyrmaGjBfDtV7KDXV9UzFQ==",
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/@webassemblyjs/helper-buffer": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-buffer/-/helper-buffer-1.14.1.tgz",
"integrity": "sha512-jyH7wtcHiKssDtFPRB+iQdxlDf96m0E39yb0k5uJVhFGleZFoNw1c4aeIcVUPPbXUVJ94wwnMOAqUHyzoEPVMA==",
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/@webassemblyjs/helper-numbers": {
"version": "1.13.2",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-numbers/-/helper-numbers-1.13.2.tgz",
"integrity": "sha512-FE8aCmS5Q6eQYcV3gI35O4J789wlQA+7JrqTTpJqn5emA4U2hvwJmvFRC0HODS+3Ye6WioDklgd6scJ3+PLnEA==",
"license": "MIT",
"peer": true,
"dependencies": {
"@webassemblyjs/floating-point-hex-parser": "1.13.2",
"@webassemblyjs/helper-api-error": "1.13.2",
@ -10756,13 +10769,15 @@
"version": "1.13.2",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-bytecode/-/helper-wasm-bytecode-1.13.2.tgz",
"integrity": "sha512-3QbLKy93F0EAIXLh0ogEVR6rOubA9AoZ+WRYhNbFyuB70j3dRdwH9g+qXhLAO0kiYGlg3TxDV+I4rQTr/YNXkA==",
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/@webassemblyjs/helper-wasm-section": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/helper-wasm-section/-/helper-wasm-section-1.14.1.tgz",
"integrity": "sha512-ds5mXEqTJ6oxRoqjhWDU83OgzAYjwsCV8Lo/N+oRsNDmx/ZDpqalmrtgOMkHwxsG0iI//3BwWAErYRHtgn0dZw==",
"license": "MIT",
"peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.14.1",
"@webassemblyjs/helper-buffer": "1.14.1",
@ -10775,6 +10790,7 @@
"resolved": "https://registry.npmjs.org/@webassemblyjs/ieee754/-/ieee754-1.13.2.tgz",
"integrity": "sha512-4LtOzh58S/5lX4ITKxnAK2USuNEvpdVV9AlgGQb8rJDHaLeHciwG4zlGr0j/SNWlr7x3vO1lDEsuePvtcDNCkw==",
"license": "MIT",
"peer": true,
"dependencies": {
"@xtuc/ieee754": "^1.2.0"
}
@ -10784,6 +10800,7 @@
"resolved": "https://registry.npmjs.org/@webassemblyjs/leb128/-/leb128-1.13.2.tgz",
"integrity": "sha512-Lde1oNoIdzVzdkNEAWZ1dZ5orIbff80YPdHx20mrHwHrVNNTjNr8E3xz9BdpcGqRQbAEa+fkrCb+fRFTl/6sQw==",
"license": "Apache-2.0",
"peer": true,
"dependencies": {
"@xtuc/long": "4.2.2"
}
@ -10792,13 +10809,15 @@
"version": "1.13.2",
"resolved": "https://registry.npmjs.org/@webassemblyjs/utf8/-/utf8-1.13.2.tgz",
"integrity": "sha512-3NQWGjKTASY1xV5m7Hr0iPeXD9+RDobLll3T9d2AO+g3my8xy5peVyjSag4I50mR1bBSN/Ct12lo+R9tJk0NZQ==",
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/@webassemblyjs/wasm-edit": {
"version": "1.14.1",
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-edit/-/wasm-edit-1.14.1.tgz",
"integrity": "sha512-RNJUIQH/J8iA/1NzlE4N7KtyZNHi3w7at7hDjvRNm5rcUXa00z1vRz3glZoULfJ5mpvYhLybmVcwcjGrC1pRrQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.14.1",
"@webassemblyjs/helper-buffer": "1.14.1",
@ -10815,6 +10834,7 @@
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-gen/-/wasm-gen-1.14.1.tgz",
"integrity": "sha512-AmomSIjP8ZbfGQhumkNvgC33AY7qtMCXnN6bL2u2Js4gVCg8fp735aEiMSBbDR7UQIj90n4wKAFUSEd0QN2Ukg==",
"license": "MIT",
"peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.14.1",
"@webassemblyjs/helper-wasm-bytecode": "1.13.2",
@ -10828,6 +10848,7 @@
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-opt/-/wasm-opt-1.14.1.tgz",
"integrity": "sha512-PTcKLUNvBqnY2U6E5bdOQcSM+oVP/PmrDY9NzowJjislEjwP/C4an2303MCVS2Mg9d3AJpIGdUFIQQWbPds0Sw==",
"license": "MIT",
"peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.14.1",
"@webassemblyjs/helper-buffer": "1.14.1",
@ -10840,6 +10861,7 @@
"resolved": "https://registry.npmjs.org/@webassemblyjs/wasm-parser/-/wasm-parser-1.14.1.tgz",
"integrity": "sha512-JLBl+KZ0R5qB7mCnud/yyX08jWFw5MsoalJ1pQ4EdFlgj9VdXKGuENGsiCIjegI1W7p91rUlcB/LB5yRJKNTcQ==",
"license": "MIT",
"peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.14.1",
"@webassemblyjs/helper-api-error": "1.13.2",
@ -10854,6 +10876,7 @@
"resolved": "https://registry.npmjs.org/@webassemblyjs/wast-printer/-/wast-printer-1.14.1.tgz",
"integrity": "sha512-kPSSXE6De1XOR820C90RIo2ogvZG+c3KiHzqUoO/F34Y2shGzesfqv7o57xrxovZJH/MetF5UjroJ/R/3isoiw==",
"license": "MIT",
"peer": true,
"dependencies": {
"@webassemblyjs/ast": "1.14.1",
"@xtuc/long": "4.2.2"
@ -10869,13 +10892,15 @@
"version": "1.2.0",
"resolved": "https://registry.npmjs.org/@xtuc/ieee754/-/ieee754-1.2.0.tgz",
"integrity": "sha512-DX8nKgqcGwsc0eJSqYt5lwP4DH5FlHnmuWWBRy7X0NcaGR0ZtuyeESgMwTYVEtxmsNGY+qit4QYT/MIYTOTPeA==",
"license": "BSD-3-Clause"
"license": "BSD-3-Clause",
"peer": true
},
"node_modules/@xtuc/long": {
"version": "4.2.2",
"resolved": "https://registry.npmjs.org/@xtuc/long/-/long-4.2.2.tgz",
"integrity": "sha512-NuHqBY1PB/D8xU6s/thBgOAiAP7HOYDQ32+BFZILJ8ivkUkAHQnWfn6WhL79Owj1qmUnoN/YPhktdIoucipkAQ==",
"license": "Apache-2.0"
"license": "Apache-2.0",
"peer": true
},
"node_modules/@xyflow/react": {
"version": "12.10.2",
@ -10942,7 +10967,6 @@
"resolved": "https://registry.npmjs.org/acorn/-/acorn-8.16.0.tgz",
"integrity": "sha512-UVJyE9MttOsBQIDKw1skb9nAwQuR5wuGD3+82K6JgJlm/Y+KI92oNsMNGZCYdDsVtRHSak0pcV5Dno5+4jh9sw==",
"license": "MIT",
"peer": true,
"bin": {
"acorn": "bin/acorn"
},
@ -10964,6 +10988,7 @@
"resolved": "https://registry.npmjs.org/acorn-import-phases/-/acorn-import-phases-1.0.4.tgz",
"integrity": "sha512-wKmbr/DDiIXzEOiWrTTUcDm24kQ2vGfZQvM2fwg2vXqR5uW6aapr7ObPtj1th32b9u90/Pf4AItvdTh42fBmVQ==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=10.13.0"
},
@ -11033,6 +11058,7 @@
"resolved": "https://registry.npmjs.org/ajv-formats/-/ajv-formats-2.1.1.tgz",
"integrity": "sha512-Wx0Kx52hxE7C18hkMEggYlEifqWZtYaRgouJor+WMdPnQyEK13vgEWyVNup7SoeeoLMsr4kf5h6dOW11I15MUA==",
"license": "MIT",
"peer": true,
"dependencies": {
"ajv": "^8.0.0"
},
@ -11050,6 +11076,7 @@
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.20.0.tgz",
"integrity": "sha512-Thbli+OlOj+iMPYFBVBfJ3OmCAnaSyNn4M1vz9T6Gka5Jt9ba/HIR56joy65tY6kx/FCF5VXNB819Y7/GUrBGA==",
"license": "MIT",
"peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.3",
"fast-uri": "^3.0.1",
@ -11065,7 +11092,8 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/ansi-colors": {
"version": "4.1.3",
@ -11373,6 +11401,7 @@
"resolved": "https://registry.npmjs.org/babel-plugin-macros/-/babel-plugin-macros-3.1.0.tgz",
"integrity": "sha512-Cg7TFGpIr01vOQNODXOOaGz2NpCU5gl8x1qJFbb6hbZxR7XrcE2vtbAsTAbJ7/xwJtUuJEw8K8Zr/AE0LHlesg==",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/runtime": "^7.12.5",
"cosmiconfig": "^7.0.0",
@ -11490,7 +11519,6 @@
}
],
"license": "MIT",
"peer": true,
"dependencies": {
"baseline-browser-mapping": "^2.10.12",
"caniuse-lite": "^1.0.30001782",
@ -11695,6 +11723,7 @@
"resolved": "https://registry.npmjs.org/chrome-trace-event/-/chrome-trace-event-1.0.4.tgz",
"integrity": "sha512-rNjApaLzuwaOTjCiT8lSDdGN1APCiqkChLMJxJPWLunPAt5fy8xgU9/jNOchV84wfIxrA0lRQB7oCT8jrn/wrQ==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=6.0"
}
@ -11933,6 +11962,7 @@
"resolved": "https://registry.npmjs.org/cosmiconfig/-/cosmiconfig-7.1.0.tgz",
"integrity": "sha512-AdmX6xUzdNASswsFtmwSt7Vj8po9IuqXm0UXz7QKPuEUmPB4XyjGfaAr2PSuELMwkRMVH1EpIkX5bTZGRB3eCA==",
"license": "MIT",
"peer": true,
"dependencies": {
"@types/parse-json": "^4.0.0",
"import-fresh": "^3.2.1",
@ -12104,7 +12134,6 @@
"resolved": "https://registry.npmjs.org/d3-selection/-/d3-selection-3.0.0.tgz",
"integrity": "sha512-fmTRWbNMmsmWq6xJV8D19U/gw/bwrHfNXxrIN+HfZgnzqTHp9jOmKMhsTUjXOJnZOdZY9Q28y4yebKzqDKlxlQ==",
"license": "ISC",
"peer": true,
"engines": {
"node": ">=12"
}
@ -12456,6 +12485,7 @@
"resolved": "https://registry.npmjs.org/dom-helpers/-/dom-helpers-5.2.1.tgz",
"integrity": "sha512-nRCa7CK3VTrM2NmGkIy4cbK7IZlgBE/PYMn55rrXefr5xXDP0LdtfPnblFDoVdcAfslJ7or6iqAUnx0CCGIWQA==",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/runtime": "^7.8.7",
"csstype": "^3.0.2"
@ -12552,6 +12582,7 @@
"resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz",
"integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==",
"license": "MIT",
"peer": true,
"dependencies": {
"is-arrayish": "^0.2.1"
}
@ -12560,7 +12591,8 @@
"version": "0.2.1",
"resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz",
"integrity": "sha512-zz06S8t0ozoDXMG+ube26zeCTNXcKIPJZJi8hBrF4idCLms4CG9QtK7qBl1boi5ODzFpjswb5JPmHCbMpjaYzg==",
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/es-abstract": {
"version": "1.23.9",
@ -12832,7 +12864,6 @@
"integrity": "sha512-LEyamqS7W5HB3ujJyvi0HQK/dtVINZvd5mAAp9eT5S/ujByGjiZLCzPcHVzuXbpJDJF/cxwHlfceVUDZ2lnSTw==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@eslint-community/eslint-utils": "^4.8.0",
"@eslint-community/regexpp": "^4.12.1",
@ -13006,7 +13037,6 @@
"integrity": "sha512-ixmkI62Rbc2/w8Vfxyh1jQRTdRTF52VxwRVHl/ykPAmqG+Nb7/kNn+byLP0LxPgI7zWA16Jt82SybJInmMia3A==",
"dev": true,
"license": "MIT",
"peer": true,
"dependencies": {
"@rtsao/scc": "^1.1.0",
"array-includes": "^3.1.8",
@ -13293,6 +13323,7 @@
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
"integrity": "sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=0.8.x"
}
@ -13407,7 +13438,8 @@
"url": "https://opencollective.com/fastify"
}
],
"license": "BSD-3-Clause"
"license": "BSD-3-Clause",
"peer": true
},
"node_modules/fastq": {
"version": "1.19.1",
@ -13455,7 +13487,8 @@
"version": "1.1.0",
"resolved": "https://registry.npmjs.org/find-root/-/find-root-1.1.0.tgz",
"integrity": "sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng==",
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/find-up": {
"version": "5.0.0",
@ -13916,6 +13949,7 @@
"resolved": "https://registry.npmjs.org/hoist-non-react-statics/-/hoist-non-react-statics-3.3.2.tgz",
"integrity": "sha512-/gGivxi8JPKWNm/W0jSmzcMPpfpPLc3dY/6GxhX2hQ9iGj3aDfklV4ET7NjKpSinLpJ5vafa9iiGIEZg10SfBw==",
"license": "BSD-3-Clause",
"peer": true,
"dependencies": {
"react-is": "^16.7.0"
}
@ -13948,7 +13982,6 @@
"resolved": "https://registry.npmjs.org/immer/-/immer-10.1.1.tgz",
"integrity": "sha512-s2MPrmjovJcoMaHtx6K11Ra7oD05NT97w1IC5zpMkT6Atjr7H8LjaDd81iIxUYpMKSRRNMJE703M1Fhr/TctHw==",
"license": "MIT",
"peer": true,
"funding": {
"type": "opencollective",
"url": "https://opencollective.com/immer"
@ -14552,6 +14585,7 @@
"resolved": "https://registry.npmjs.org/jest-worker/-/jest-worker-27.5.1.tgz",
"integrity": "sha512-7vuh85V5cdDofPyxn58nrPjBktZo0u9x1g8WtjQol+jZDaE+fhN+cIvTj11GndBnMnyfrUOG1sZQxCdjKh+DKg==",
"license": "MIT",
"peer": true,
"dependencies": {
"@types/node": "*",
"merge-stream": "^2.0.0",
@ -14566,6 +14600,7 @@
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-8.1.1.tgz",
"integrity": "sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==",
"license": "MIT",
"peer": true,
"dependencies": {
"has-flag": "^4.0.0"
},
@ -14662,7 +14697,8 @@
"version": "2.3.1",
"resolved": "https://registry.npmjs.org/json-parse-even-better-errors/-/json-parse-even-better-errors-2.3.1.tgz",
"integrity": "sha512-xyFwyhro/JEof6Ghe2iz2NcXoj2sloNsWr/XsERDK/oiPCfaNhl5ONfp+jQdAZRQQ0IJWNzH9zIZF7li91kh2w==",
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/json-schema": {
"version": "0.4.0",
@ -15000,13 +15036,15 @@
"version": "1.2.4",
"resolved": "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.2.4.tgz",
"integrity": "sha512-7ylylesZQ/PV29jhEDl3Ufjo6ZX7gCqJr5F7PKrqc93v7fzSymt1BpwEU8nAUXs8qzzvqhbjhK5QZg6Mt/HkBg==",
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/loader-runner": {
"version": "4.3.2",
"resolved": "https://registry.npmjs.org/loader-runner/-/loader-runner-4.3.2.tgz",
"integrity": "sha512-DFEqQ3ihfS9blba08cLfYf1NRAIEm+dDjic073DRDc3/JspI/8wYmtDsHwd3+4hwvdxSK7PGaElfTmm0awWJ4w==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=6.11.5"
},
@ -15090,13 +15128,15 @@
"version": "6.0.0",
"resolved": "https://registry.npmjs.org/memoize-one/-/memoize-one-6.0.0.tgz",
"integrity": "sha512-rkpe71W0N0c0Xz6QD0eJETuWAJGnJ9afsl1srmwPrI+yBCkge5EycXXbYRyvL29zZVUWQCY7InPRCv3GDXuZNw==",
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/merge-stream": {
"version": "2.0.0",
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/merge2": {
"version": "1.4.1",
@ -15136,6 +15176,7 @@
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.54.0.tgz",
"integrity": "sha512-aU5EJuIN2WDemCcAp2vFBfp/m4EAhWJnUNSSw0ixs7/kXbd6Pg64EmwJkNdFhB8aWt1sH2CTXrLxo/iAGV3oPQ==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">= 0.6"
}
@ -15179,6 +15220,7 @@
"resolved": "https://registry.npmjs.org/minimizer-webpack-plugin/-/minimizer-webpack-plugin-5.6.1.tgz",
"integrity": "sha512-DoeAZz8Q1C1znwsUzej1fdoi4jCf7/+Em27ouLqfK/+3m8G+D7yDhUwrc3CNhjSzGUN1kn7Iv4sWmjflQHenpw==",
"license": "MIT",
"peer": true,
"dependencies": {
"@jridgewell/trace-mapping": "^0.3.25",
"jest-worker": "^27.4.5",
@ -15290,14 +15332,14 @@
"version": "2.6.2",
"resolved": "https://registry.npmjs.org/neo-async/-/neo-async-2.6.2.tgz",
"integrity": "sha512-Yd3UES5mWCSqR+qNT93S3UoYUkqAZ9lLg8a7g9rimsWmYGK8cVToA4/sF3RrshdyV3sAGMXVUmpMYOw+dLpOuw==",
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/next": {
"version": "15.5.20",
"resolved": "https://registry.npmjs.org/next/-/next-15.5.20.tgz",
"integrity": "sha512-cvyS3/geydan1xLtE3FA8VCgdoQ/Gg/dlOldFkFCbB5VcVYJV7090hQLBnvTW2PwT76Z/dHdzDZCsVhZpoOlUA==",
"license": "MIT",
"peer": true,
"dependencies": {
"@next/env": "15.5.20",
"@swc/helpers": "0.5.15",
@ -15684,6 +15726,7 @@
"resolved": "https://registry.npmjs.org/parse-json/-/parse-json-5.2.0.tgz",
"integrity": "sha512-ayCKvm/phCGxOkYRSCM82iDwct8/EonSEgCSxWxD7ve6jHggsFl4fZVQBPRNgQoKiuV/odhFrGzQXZwbifC8Rg==",
"license": "MIT",
"peer": true,
"dependencies": {
"@babel/code-frame": "^7.0.0",
"error-ex": "^1.3.1",
@ -15752,6 +15795,7 @@
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=8"
}
@ -16125,7 +16169,6 @@
"resolved": "https://registry.npmjs.org/react/-/react-19.1.0.tgz",
"integrity": "sha512-FS+XFBNvn3GTAWq26joslQgWNoFu08F4kl0J4CgdNKADkdSGXQyTCnKteIAJy96Br6YbpEU1LSzV5dYtjMkMDg==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=0.10.0"
}
@ -16156,7 +16199,6 @@
"resolved": "https://registry.npmjs.org/react-dom/-/react-dom-19.1.0.tgz",
"integrity": "sha512-Xs1hdnE+DyKgeHJeJznQmYMIBG3TKIHJJT95Q58nHLSrElKlGQqDTR2HQ9fx5CN/Gk6Vh/kupBTDLU11/nDk/g==",
"license": "MIT",
"peer": true,
"dependencies": {
"scheduler": "^0.26.0"
},
@ -16183,7 +16225,6 @@
"resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.72.1.tgz",
"integrity": "sha512-RhwBoy2ygeVZje+C+bwJ8g0NjTdBmDlJvAUHTxRjTmSUKPYsKfMphkS2sgEMotsY03bP358yEYlnUeZy//D9Ig==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=18.0.0"
},
@ -16208,15 +16249,13 @@
"version": "16.13.1",
"resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz",
"integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==",
"license": "MIT",
"peer": true
"license": "MIT"
},
"node_modules/react-redux": {
"version": "9.2.0",
"resolved": "https://registry.npmjs.org/react-redux/-/react-redux-9.2.0.tgz",
"integrity": "sha512-ROY9fvHhwOD9ySfrF0wmvu//bKCQ6AeZZq1nJNtbDC+kk5DuSuNX/n6YWYF/SYy7bSba4D4FSz8DJeKY/S/r+g==",
"license": "MIT",
"peer": true,
"dependencies": {
"@types/use-sync-external-store": "^0.0.6",
"use-sync-external-store": "^1.4.0"
@ -16356,6 +16395,7 @@
"resolved": "https://registry.npmjs.org/react-transition-group/-/react-transition-group-4.4.5.tgz",
"integrity": "sha512-pZcd1MCJoiKiBR2NRxeCRg13uCXbydPnmB4EOeRrY7480qNWO8IIgQG6zlDkm6uRMsURXPuKq0GWtiM59a5Q6g==",
"license": "BSD-3-Clause",
"peer": true,
"dependencies": {
"@babel/runtime": "^7.5.5",
"dom-helpers": "^5.0.1",
@ -16421,8 +16461,7 @@
"version": "5.0.1",
"resolved": "https://registry.npmjs.org/redux/-/redux-5.0.1.tgz",
"integrity": "sha512-M9/ELqF6fy8FwmkpnF0S3YKOqMyoWJ4+CS5Efg2ct3oY9daQvd/Pc71FpGZsVsbl3Cpb+IIcjBDUnnyBdQbq4w==",
"license": "MIT",
"peer": true
"license": "MIT"
},
"node_modules/redux-thunk": {
"version": "3.1.0",
@ -16460,7 +16499,8 @@
"version": "0.14.1",
"resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
"integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw==",
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/regexp.prototype.flags": {
"version": "1.5.4",
@ -16497,6 +16537,7 @@
"resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz",
"integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=0.10.0"
}
@ -16580,7 +16621,6 @@
"resolved": "https://registry.npmjs.org/rollup/-/rollup-4.62.2.tgz",
"integrity": "sha512-RFnrW4lhXA3s3eqHDZvN654g8OTjzRfqpIRJYczCGB6HzphckVAi/Qh4tbPUbRuDi7s1Llv8g/NspLkttY3gTA==",
"license": "MIT",
"peer": true,
"dependencies": {
"@types/estree": "1.0.9"
},
@ -16752,6 +16792,7 @@
"resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-4.3.3.tgz",
"integrity": "sha512-eflK8wEtyOE6+hsaRVPxvUKYCpRgzLqDTb8krvAsRIwOGlHoSgYLgBXoubGgLd2fT41/OUYdb48v4k4WWHQurA==",
"license": "MIT",
"peer": true,
"dependencies": {
"@types/json-schema": "^7.0.9",
"ajv": "^8.9.0",
@ -16788,6 +16829,7 @@
"resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz",
"integrity": "sha512-YCS/JNFAUyr5vAuhk1DWm1CBxRHW9LbJ2ozWeemrIqpbsqKjHVxYPyi5GC0rjZIT5JxJ3virVTS8wk4i/Z+krw==",
"license": "MIT",
"peer": true,
"dependencies": {
"fast-deep-equal": "^3.1.3"
},
@ -16799,7 +16841,8 @@
"version": "1.0.0",
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz",
"integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==",
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/secure-json-parse": {
"version": "4.0.0",
@ -17343,7 +17386,8 @@
"version": "4.2.0",
"resolved": "https://registry.npmjs.org/stylis/-/stylis-4.2.0.tgz",
"integrity": "sha512-Orov6g6BB1sDfYgzWfTHDOxamtX1bE/zo104Dh9e6fqJ3PooipYyfJ0pUmrZO2wAvO8YbEyeFrkV91XTsGMSrw==",
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/supports-color": {
"version": "7.2.0",
@ -17397,8 +17441,7 @@
"version": "4.1.1",
"resolved": "https://registry.npmjs.org/tailwindcss/-/tailwindcss-4.1.1.tgz",
"integrity": "sha512-QNbdmeS979Efzim2g/bEvfuh+fTcIdp1y7gA+sb6OYSW74rt7Cr7M78AKdf6HqWT3d5AiTb7SwTT3sLQxr4/qw==",
"license": "MIT",
"peer": true
"license": "MIT"
},
"node_modules/tailwindcss-animate": {
"version": "1.0.7",
@ -17427,6 +17470,7 @@
"resolved": "https://registry.npmjs.org/terser/-/terser-5.48.0.tgz",
"integrity": "sha512-J/9An6vs9Us6wKRriSFXBWdRZapREHqFzdNUKk0pmu804EMR6dr6winwo7e5JDxN4xahxQsuysyYFwlwj4XN/Q==",
"license": "BSD-2-Clause",
"peer": true,
"dependencies": {
"@jridgewell/source-map": "^0.3.3",
"acorn": "^8.15.0",
@ -17444,7 +17488,8 @@
"version": "2.20.3",
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz",
"integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==",
"license": "MIT"
"license": "MIT",
"peer": true
},
"node_modules/thread-stream": {
"version": "3.1.0",
@ -17523,7 +17568,6 @@
"integrity": "sha512-QP88BAKvMam/3NxH6vj2o21R6MjxZUAd6nlwAS/pnGvN9IVLocLHxGYIzFhg6fUQ+5th6P4dv4eW9jX3DSIj7A==",
"dev": true,
"license": "MIT",
"peer": true,
"engines": {
"node": ">=12"
},
@ -17725,7 +17769,6 @@
"integrity": "sha512-aJn6wq13/afZp/jT9QZmwEjDqqvSGp1VT5GVg+f/t6/oVyrgXM6BY1h9BRh/O5p3PlUPAe+WuiEZOmb/49RqoQ==",
"dev": true,
"license": "Apache-2.0",
"peer": true,
"bin": {
"tsc": "bin/tsc",
"tsserver": "bin/tsserver"
@ -17852,6 +17895,7 @@
"resolved": "https://registry.npmjs.org/use-isomorphic-layout-effect/-/use-isomorphic-layout-effect-1.2.1.tgz",
"integrity": "sha512-tpZZ+EX0gaghDAiFR37hj5MgY6ZN55kLiPkJsKxBMZ6GZdOSPJXiOzPM984oPYZ5AnehYx5WQp1+ME8I/P/pRA==",
"license": "MIT",
"peer": true,
"peerDependencies": {
"react": "^16.8.0 || ^17.0.0 || ^18.0.0 || ^19.0.0"
},
@ -17938,6 +17982,7 @@
"resolved": "https://registry.npmjs.org/watchpack/-/watchpack-2.5.2.tgz",
"integrity": "sha512-6i/00NBjP4yGPs+caKSyRfpTF/8Torsu0MOW3mMzIbhgISFder8i7xbqgHlLMwJrdiN8ndBV3UA1/AfzPSr+jg==",
"license": "MIT",
"peer": true,
"dependencies": {
"graceful-fs": "^4.1.2"
},
@ -17962,6 +18007,7 @@
"resolved": "https://registry.npmjs.org/webpack/-/webpack-5.108.3.tgz",
"integrity": "sha512-hOpaCHmQVVY66IVTjofnH14IgSdmod2aquSGHGuYig/OIdWge01Hk2Wt988DZcwXumFUT4+FvJY5N+ikl8o/ww==",
"license": "MIT",
"peer": true,
"dependencies": {
"@types/estree": "^1.0.8",
"@types/json-schema": "^7.0.15",
@ -18007,6 +18053,7 @@
"resolved": "https://registry.npmjs.org/webpack-sources/-/webpack-sources-3.5.0.tgz",
"integrity": "sha512-HPuy+uuoTCaaoEoI1LQ3JN9+vrPBvEesnnX1jADHy728cHSMlq4wUc4afYqahq2B1mhQVZxCXOkNTnXltr+2vQ==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=10.13.0"
}
@ -18016,6 +18063,7 @@
"resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz",
"integrity": "sha512-2NxwbF/hZ0KpepYN0cNbo+FN6XoK7GaHlQhgx/hIZl6Va0bF45RQOOwhLIy8lQDbuCiadSLCBnH2CFYquit5bw==",
"license": "BSD-2-Clause",
"peer": true,
"dependencies": {
"esrecurse": "^4.3.0",
"estraverse": "^4.1.1"
@ -18029,6 +18077,7 @@
"resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.3.0.tgz",
"integrity": "sha512-39nnKffWz8xN1BU/2c79n9nB9HDzo0niYUqx6xyqUnyoAnQyyWpOTdZEeiCch8BBu515t4wp9ZmgVfVhn9EBpw==",
"license": "BSD-2-Clause",
"peer": true,
"engines": {
"node": ">=4.0"
}
@ -18203,6 +18252,7 @@
"resolved": "https://registry.npmjs.org/yaml/-/yaml-1.10.3.tgz",
"integrity": "sha512-vIYeF1u3CjlhAFekPPAk2h/Kv4T3mAkMox5OymRiJQB0spDP10LHvt+K7G9Ny6NuuMAb25/6n1qyUjAcGNf/AA==",
"license": "ISC",
"peer": true,
"engines": {
"node": ">= 6"
}
@ -18311,7 +18361,6 @@
"resolved": "https://registry.npmjs.org/yup/-/yup-1.7.1.tgz",
"integrity": "sha512-GKHFX2nXul2/4Dtfxhozv701jLQHdf6J34YDh2cEkpqoo8le5Mg6/LrdseVLrFarmFygZTlfIhHx/QKfb/QWXw==",
"license": "MIT",
"peer": true,
"dependencies": {
"property-expr": "^2.0.5",
"tiny-case": "^1.0.3",
@ -18352,7 +18401,6 @@
"resolved": "https://registry.npmjs.org/zustand/-/zustand-5.0.8.tgz",
"integrity": "sha512-gyPKpIaxY9XcO2vSMrLbiER7QMAMGOQZVRdJ6Zi782jkbzZygq5GI9nG8g+sMgitRtndwaBSl7uiqC49o1SSiw==",
"license": "MIT",
"peer": true,
"engines": {
"node": ">=12.20.0"
},

View file

@ -116,7 +116,7 @@ export default function BillingPage() {
const router = useRouter();
const searchParams = useSearchParams();
const auth = useAuth();
const { config } = useAppConfig();
const { config, loading: configLoading } = useAppConfig();
const [credits, setCredits] = useState<MpsBillingCreditsResponse | null>(null);
const [loading, setLoading] = useState(true);
const [refreshing, setRefreshing] = useState(false);
@ -125,9 +125,9 @@ export default function BillingPage() {
() => getPageFromSearchParams(searchParams),
);
const isBillingV2 = credits?.billing_version === "v2";
const isOssMode = config?.deploymentMode === "oss";
const canPurchaseCredits = isBillingV2 && !isOssMode;
const hasAppConfig = !configLoading && config !== null;
const isOssMode = hasAppConfig && config.deploymentMode === "oss";
const canPurchaseCredits = hasAppConfig && config.deploymentMode !== "oss";
const totalQuota = credits?.total_quota ?? 0;
const remainingCredits = credits?.remaining_credits ?? 0;
const usedCredits = credits?.total_credits_used ?? 0;
@ -229,7 +229,7 @@ export default function BillingPage() {
}
};
if (loading) {
if (loading || configLoading) {
return (
<div className="container mx-auto p-6 space-y-6">
<div className="space-y-2">
@ -301,7 +301,7 @@ export default function BillingPage() {
<div className="grid gap-4 md:grid-cols-2">
<Card>
<CardHeader className="pb-2">
<CardDescription>{isBillingV2 ? "Credit balance" : "Credits remaining"}</CardDescription>
<CardDescription>{isOssMode ? "Credits remaining" : "Credit balance"}</CardDescription>
<CardTitle className="flex items-center gap-2 text-3xl">
<CircleDollarSign className="h-6 w-6 text-muted-foreground" />
{formatCredits(remainingCredits)}
@ -319,13 +319,13 @@ export default function BillingPage() {
</CardHeader>
<CardContent>
<p className="text-sm text-muted-foreground">
{isBillingV2 ? "Total ledger debits" : "Current allocation usage"}
{isOssMode ? "Current allocation usage" : "Total ledger debits"}
</p>
</CardContent>
</Card>
</div>
{isBillingV2 ? (
{!isOssMode ? (
<Card>
<CardHeader>
<CardTitle>Credit Ledger</CardTitle>

View file

@ -2,24 +2,12 @@
import ModelConfigurationV2 from "@/components/ModelConfigurationV2";
import { SETTINGS_DOCUMENTATION_URLS } from "@/constants/documentation";
interface ServiceConfigurationPageProps {
searchParams?: Promise<{
action?: string | string[];
}>;
}
export default async function ServiceConfigurationPage({ searchParams }: ServiceConfigurationPageProps) {
const params = searchParams ? await searchParams : {};
const action = Array.isArray(params.action) ? params.action[0] : params.action;
export default function ServiceConfigurationPage() {
return (
<div className="min-h-screen">
<div className="container mx-auto px-4 py-8">
<div className="max-w-4xl mx-auto">
<ModelConfigurationV2
docsUrl={SETTINGS_DOCUMENTATION_URLS.modelOverrides}
initialAction={action}
/>
<ModelConfigurationV2 docsUrl={SETTINGS_DOCUMENTATION_URLS.modelOverrides} />
</div>
</div>
</div>

View file

@ -78,6 +78,7 @@ export const ConfigurationsDialog = ({
turn_start_min_words: turnStartMinWords,
provisional_vad_pause_secs: provisionalVadPauseSecs,
turn_stop_strategy: turnStopStrategy,
transcript_configuration: resolvedWorkflowConfigurations.transcript_configuration,
context_compaction_enabled: contextCompactionEnabled,
}, name);
onOpenChange(false);

View file

@ -1,54 +0,0 @@
import { ServiceConfigurationForm } from "@/components/ServiceConfigurationForm";
import {
Dialog,
DialogContent,
DialogDescription,
DialogHeader,
DialogTitle,
} from "@/components/ui/dialog";
import type { WorkflowConfigurations } from "@/types/workflow-configurations";
interface ModelConfigurationDialogProps {
open: boolean;
onOpenChange: (open: boolean) => void;
workflowConfigurations: WorkflowConfigurations | null;
workflowName: string;
onSave: (configurations: WorkflowConfigurations, workflowName: string) => Promise<void>;
}
export const ModelConfigurationDialog = ({
open,
onOpenChange,
workflowConfigurations,
workflowName,
onSave,
}: ModelConfigurationDialogProps) => {
return (
<Dialog open={open} onOpenChange={onOpenChange}>
<DialogContent className="max-w-2xl max-h-[85vh] overflow-y-auto">
<DialogHeader>
<DialogTitle>Model Configuration</DialogTitle>
<DialogDescription>
Override global model settings for this workflow. Toggle individual services to customize.
</DialogDescription>
</DialogHeader>
<ServiceConfigurationForm
mode="override"
currentOverrides={workflowConfigurations?.model_overrides}
submitLabel="Save"
onSave={async (config) => {
await onSave(
{
...workflowConfigurations,
model_overrides: config.model_overrides as WorkflowConfigurations["model_overrides"],
} as WorkflowConfigurations,
workflowName,
);
onOpenChange(false);
}}
/>
</DialogContent>
</Dialog>
);
};

View file

@ -25,7 +25,6 @@ import {
} from "@/components/AIModelConfigurationV2Editor";
import { FlowEdge, FlowNode } from "@/components/flow/types";
import { LLMConfigSelector } from "@/components/LLMConfigSelector";
import { ServiceConfigurationForm } from "@/components/ServiceConfigurationForm";
import SpinLoader from "@/components/SpinLoader";
import { Button } from "@/components/ui/button";
import { Calendar } from "@/components/ui/calendar";
@ -48,6 +47,7 @@ import {
DEFAULT_PROVISIONAL_VAD_PAUSE_SECS,
DEFAULT_TURN_START_MIN_WORDS,
DEFAULT_VOICEMAIL_DETECTION_CONFIGURATION,
resolveWorkflowConfigurations,
TURN_START_STRATEGY_OPTIONS,
type TurnStartStrategy,
type TurnStopStrategy,
@ -293,6 +293,9 @@ function GeneralSection({
const [contextCompactionEnabled, setContextCompactionEnabled] = useState(
workflowConfigurations.context_compaction_enabled,
);
const [includeTranscriptEndTimestamps, setIncludeTranscriptEndTimestamps] = useState(
workflowConfigurations.transcript_configuration?.include_end_timestamps ?? false,
);
const [isSaving, setIsSaving] = useState(false);
const [isUploadingAudio, setIsUploadingAudio] = useState(false);
const [audioUploadError, setAudioUploadError] = useState<string | null>(null);
@ -314,9 +317,11 @@ function GeneralSection({
turnStartMinWords !== workflowConfigurations.turn_start_min_words ||
provisionalVadPauseSecs !== workflowConfigurations.provisional_vad_pause_secs ||
turnStopStrategy !== workflowConfigurations.turn_stop_strategy ||
contextCompactionEnabled !== workflowConfigurations.context_compaction_enabled
contextCompactionEnabled !== workflowConfigurations.context_compaction_enabled ||
includeTranscriptEndTimestamps !==
(workflowConfigurations.transcript_configuration?.include_end_timestamps ?? false)
);
}, [name, workflowName, ambientNoiseConfig, maxCallDuration, maxUserIdleTimeout, smartTurnStopSecs, turnStartStrategy, turnStartMinWords, provisionalVadPauseSecs, turnStopStrategy, contextCompactionEnabled, workflowConfigurations]);
}, [name, workflowName, ambientNoiseConfig, maxCallDuration, maxUserIdleTimeout, smartTurnStopSecs, turnStartStrategy, turnStartMinWords, provisionalVadPauseSecs, turnStopStrategy, contextCompactionEnabled, includeTranscriptEndTimestamps, workflowConfigurations]);
useUnsavedChanges("general", isDirty);
@ -393,6 +398,10 @@ function GeneralSection({
provisional_vad_pause_secs: provisionalVadPauseSecs,
turn_stop_strategy: turnStopStrategy,
context_compaction_enabled: contextCompactionEnabled,
transcript_configuration: {
...(workflowConfigurations.transcript_configuration ?? {}),
include_end_timestamps: includeTranscriptEndTimestamps,
},
},
name,
);
@ -686,6 +695,34 @@ function GeneralSection({
<Separator />
{/* Transcript */}
<div className="space-y-4">
<div>
<h3 className="text-sm font-medium">Transcript</h3>
<p className="text-xs text-muted-foreground mt-0.5">
Include start and stop timestamps for each speaker in the uploaded transcript.
</p>
</div>
<div className="flex items-center justify-between">
<Label htmlFor="transcript-end-timestamps-enabled" className="text-sm">
Enhanced Timestamped Transcript
</Label>
<Switch
id="transcript-end-timestamps-enabled"
checked={includeTranscriptEndTimestamps}
onCheckedChange={setIncludeTranscriptEndTimestamps}
/>
</div>
<div className="rounded-md border bg-muted/20 p-3">
<pre className="whitespace-pre-wrap text-xs leading-relaxed text-muted-foreground">
{`[2026-07-06T10:00:00.000Z -> 2026-07-06T10:00:04.800Z] assistant: Can you confirm your date of birth?
[2026-07-06T10:00:06.200Z -> 2026-07-06T10:00:08.700Z] user: January fifth, nineteen ninety.`}
</pre>
</div>
</div>
<Separator />
{/* Context Compaction */}
<div className="space-y-4">
<div>
@ -1185,17 +1222,7 @@ function WorkflowModelOverridesSection({
setOverrideEnabled(Boolean(workflowConfigurations.model_configuration_v2_override));
}, [workflowConfigurations.model_configuration_v2_override]);
const source = organizationModelConfiguration?.source || "empty";
const isV2 = source === "organization_v2";
const saveLegacyOverrides = async (config: Record<string, unknown>) => {
const nextConfigurations = withoutModelConfigurationOverrides(workflowConfigurations);
const modelOverrides = config.model_overrides as WorkflowConfigurations["model_overrides"] | undefined;
if (modelOverrides) {
nextConfigurations.model_overrides = modelOverrides;
}
await onSave(nextConfigurations, workflowName);
};
const hasOrgConfiguration = organizationModelConfiguration?.source === "organization_v2";
const saveV2Override = async (configuration: OrganizationAiModelConfigurationV2) => {
const nextConfigurations = withoutModelConfigurationOverrides(workflowConfigurations);
@ -1223,9 +1250,7 @@ function WorkflowModelOverridesSection({
Model Overrides
</CardTitle>
<CardDescription>
{isV2
? "Override the full organization model configuration for this workflow."
: "Override global model settings for this workflow. Toggle individual services to customize."}{" "}
Override the full organization model configuration for this workflow.{" "}
<a href={SETTINGS_DOCUMENTATION_URLS.modelOverrides} target="_blank" rel="noopener noreferrer" className="inline-flex items-center gap-0.5 underline">Learn more <ExternalLink className="h-3 w-3" /></a>
</CardDescription>
</CardHeader>
@ -1243,28 +1268,18 @@ function WorkflowModelOverridesSection({
</div>
)}
{!modelConfigurationLoading && !modelConfigurationError && !isV2 && (
<>
{source === "legacy_user_v1" && (
<div className="flex flex-col gap-3 rounded-md border bg-muted/30 p-4 sm:flex-row sm:items-center sm:justify-between">
<p className="text-sm text-muted-foreground">
This workflow is using legacy model overrides. Migrate organization model configuration to use v2 overrides.
</p>
<Button type="button" variant="outline" size="sm" asChild>
<Link href="/model-configurations?action=migrate_to_v2">Migrate to v2</Link>
</Button>
</div>
)}
<ServiceConfigurationForm
mode="override"
currentOverrides={workflowConfigurations.model_overrides}
submitLabel="Save Model Overrides"
onSave={saveLegacyOverrides}
/>
</>
{!modelConfigurationLoading && !modelConfigurationError && !hasOrgConfiguration && (
<div className="flex flex-col gap-3 rounded-md border bg-muted/30 p-4 sm:flex-row sm:items-center sm:justify-between">
<p className="text-sm text-muted-foreground">
Set up your organization model configuration before overriding it per workflow.
</p>
<Button type="button" variant="outline" size="sm" asChild>
<Link href="/model-configurations">Configure Models</Link>
</Button>
</div>
)}
{!modelConfigurationLoading && !modelConfigurationError && isV2 && modelConfigurationDefaults && organizationModelConfiguration && (
{!modelConfigurationLoading && !modelConfigurationError && hasOrgConfiguration && modelConfigurationDefaults && organizationModelConfiguration && (
<>
<div className="flex items-center justify-between rounded-md border p-4">
<div className="space-y-0.5">
@ -1458,6 +1473,9 @@ function WorkflowSettingsInner({
initialWorkflowConfigurations,
user,
});
const resolvedWorkflowConfigurationsForRender = workflowConfigurations
? resolveWorkflowConfigurations(workflowConfigurations)
: null;
useEffect(() => {
if (hasFetchedModelConfiguration.current) return;
@ -1532,18 +1550,18 @@ function WorkflowSettingsInner({
<div className="mx-auto flex max-w-5xl gap-8 px-6 py-8">
{/* Sections */}
<div className="min-w-0 flex-1 space-y-8">
{workflowConfigurations && (
{resolvedWorkflowConfigurationsForRender && (
<>
{/* General */}
<GeneralSection
workflowConfigurations={workflowConfigurations}
workflowConfigurations={resolvedWorkflowConfigurationsForRender}
workflowName={workflowName || workflow.name}
workflowId={workflowId}
onSave={saveWorkflowConfigurations}
/>
<WorkflowModelOverridesSection
workflowConfigurations={workflowConfigurations}
workflowConfigurations={resolvedWorkflowConfigurationsForRender}
workflowName={workflowName}
onSave={saveWorkflowConfigurations}
modelConfigurationDefaults={modelConfigurationDefaults}
@ -1563,7 +1581,7 @@ function WorkflowSettingsInner({
{/* Voicemail Detection */}
<VoicemailSection
workflowConfigurations={workflowConfigurations}
workflowConfigurations={resolvedWorkflowConfigurationsForRender}
workflowName={workflowName}
onSave={saveWorkflowConfigurations}
/>

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -561,7 +561,9 @@ export type ByokPipelineAiModelConfiguration = {
provider: 'azure_speech';
} & AzureSpeechTtsConfiguration) | ({
provider: 'smallest';
} & SmallestAittsConfiguration);
} & SmallestAittsConfiguration) | ({
provider: 'xai';
} & XaittsConfiguration);
/**
* Stt
*/
@ -3307,10 +3309,6 @@ export type MpsBillingAccountResponse = {
* MPSBillingCreditsResponse
*/
export type MpsBillingCreditsResponse = {
/**
* Billing Version
*/
billing_version: 'legacy' | 'v2';
/**
* Total Credits Used
*/
@ -3436,24 +3434,6 @@ export type MpsCreditPurchaseUrlResponse = {
checkout_url: string;
};
/**
* MPSCreditsResponse
*/
export type MpsCreditsResponse = {
/**
* Total Credits Used
*/
total_credits_used: number;
/**
* Remaining Credits
*/
remaining_credits: number;
/**
* Total Quota
*/
total_quota: number;
};
/**
* McpRefreshResponse
*
@ -7178,6 +7158,32 @@ export type WorkflowVersionResponse = {
} | null;
};
/**
* xAI
*/
export type XaittsConfiguration = {
/**
* Provider
*/
provider?: 'xai';
/**
* Api Key
*/
api_key: string | Array<string>;
/**
* Voice
*
* xAI voice persona.
*/
voice?: string;
/**
* Language
*
* BCP-47 language code for synthesis (e.g. 'en', 'fr', 'de'), or 'auto' for automatic language detection.
*/
language?: string;
};
export type InitiateCallApiV1TelephonyInitiateCallPostData = {
body: InitiateCallRequest;
headers?: {
@ -12031,45 +12037,6 @@ export type GetCurrentPeriodUsageApiV1OrganizationsUsageCurrentPeriodGetResponse
export type GetCurrentPeriodUsageApiV1OrganizationsUsageCurrentPeriodGetResponse = GetCurrentPeriodUsageApiV1OrganizationsUsageCurrentPeriodGetResponses[keyof GetCurrentPeriodUsageApiV1OrganizationsUsageCurrentPeriodGetResponses];
export type GetMpsCreditsApiV1OrganizationsUsageMpsCreditsGetData = {
body?: never;
headers?: {
/**
* Authorization
*/
authorization?: string | null;
/**
* X-Api-Key
*/
'X-API-Key'?: string | null;
};
path?: never;
query?: never;
url: '/api/v1/organizations/usage/mps-credits';
};
export type GetMpsCreditsApiV1OrganizationsUsageMpsCreditsGetErrors = {
/**
* Not found
*/
404: unknown;
/**
* Validation Error
*/
422: HttpValidationError;
};
export type GetMpsCreditsApiV1OrganizationsUsageMpsCreditsGetError = GetMpsCreditsApiV1OrganizationsUsageMpsCreditsGetErrors[keyof GetMpsCreditsApiV1OrganizationsUsageMpsCreditsGetErrors];
export type GetMpsCreditsApiV1OrganizationsUsageMpsCreditsGetResponses = {
/**
* Successful Response
*/
200: MpsCreditsResponse;
};
export type GetMpsCreditsApiV1OrganizationsUsageMpsCreditsGetResponse = GetMpsCreditsApiV1OrganizationsUsageMpsCreditsGetResponses[keyof GetMpsCreditsApiV1OrganizationsUsageMpsCreditsGetResponses];
export type GetBillingCreditsApiV1OrganizationsBillingCreditsGetData = {
body?: never;
headers?: {

View file

@ -1,6 +1,6 @@
"use client";
import { KeyRound, Save } from "lucide-react";
import { Info, KeyRound, Save } from "lucide-react";
import { useEffect, useMemo, useState } from "react";
import type { OrganizationAiModelConfigurationV2 } from "@/client/types.gen";
@ -265,6 +265,23 @@ function optionalByokService(config: Record<string, unknown>, service: ServiceSe
return serviceConfiguration;
}
function ThirdPartyProviderNotice() {
return (
<div className="mb-4 flex gap-3 rounded-md border border-amber-500/40 bg-amber-500/10 px-4 py-3 text-sm text-amber-900 dark:text-amber-200">
<Info className="mt-0.5 h-4 w-4 shrink-0" />
<div>
<p className="font-medium">Third-party provider data notice</p>
<p className="mt-1 leading-6">
Dograh sends data required by the selected model service. This may include prompts,
transcripts, audio, generated text, tool data, and request metadata depending on the
provider and service type. Review the provider&apos;s data and retention policies before
using sensitive data.
</p>
</div>
</div>
);
}
export function AIModelConfigurationV2Editor({
defaults,
configuration,
@ -383,6 +400,7 @@ export function AIModelConfigurationV2Editor({
<p className="mb-4 text-sm text-muted-foreground">
A single speech-to-speech model handles the conversation in realtime (no separate transcriber or voice). An LLM is still required for variable extraction and QA.
</p>
<ThirdPartyProviderNotice />
<ServiceConfigurationForm
key={`realtime-${JSON.stringify(realtimeInitialConfig)}`}
mode="global"
@ -472,6 +490,7 @@ export function AIModelConfigurationV2Editor({
</TabsContent>
<TabsContent value="byok" className="mt-0">
<ThirdPartyProviderNotice />
<ServiceConfigurationForm
key={`byok-${JSON.stringify(pipelineInitialConfig)}`}
mode="global"

View file

@ -1,12 +1,11 @@
"use client";
import { ExternalLink, RefreshCw } from "lucide-react";
import { ExternalLink } from "lucide-react";
import { useEffect, useRef, useState } from "react";
import {
getModelConfigurationV2ApiV1OrganizationsModelConfigurationsV2Get,
getModelConfigurationV2DefaultsApiV1OrganizationsModelConfigurationsV2DefaultsGet,
migrateModelConfigurationV2ApiV1OrganizationsModelConfigurationsV2MigratePost,
saveModelConfigurationV2ApiV1OrganizationsModelConfigurationsV2Put,
} from "@/client/sdk.gen";
import type {
@ -14,47 +13,22 @@ import type {
OrganizationAiModelConfigurationV2,
} from "@/client/types.gen";
import { AIModelConfigurationV2Editor, type ModelConfigurationDefaultsV2 } from "@/components/AIModelConfigurationV2Editor";
import { ServiceConfigurationForm } from "@/components/ServiceConfigurationForm";
import {
AlertDialog,
AlertDialogCancel,
AlertDialogContent,
AlertDialogDescription,
AlertDialogFooter,
AlertDialogHeader,
AlertDialogTitle,
} from "@/components/ui/alert-dialog";
import { Badge } from "@/components/ui/badge";
import { Button } from "@/components/ui/button";
import { Skeleton } from "@/components/ui/skeleton";
import { useUserConfig } from "@/context/UserConfigContext";
import { detailFromError } from "@/lib/apiError";
import { useAuth } from "@/lib/auth";
export default function ModelConfigurationV2({
docsUrl,
initialAction,
}: {
docsUrl?: string;
initialAction?: string;
}) {
export default function ModelConfigurationV2({ docsUrl }: { docsUrl?: string }) {
const auth = useAuth();
const { refreshConfig, saveUserConfig } = useUserConfig();
const { refreshConfig } = useUserConfig();
const hasFetched = useRef(false);
const hasAppliedInitialMigrationAction = useRef(false);
const [defaults, setDefaults] = useState<ModelConfigurationDefaultsV2 | null>(null);
const [response, setResponse] = useState<OrganizationAiModelConfigurationResponse | null>(null);
const [loading, setLoading] = useState(true);
const [migrating, setMigrating] = useState(false);
const [migrationDialogOpen, setMigrationDialogOpen] = useState(false);
const [error, setError] = useState<string | null>(null);
const [notice, setNotice] = useState<string | null>(null);
const applyResponse = (nextResponse: OrganizationAiModelConfigurationResponse) => {
setResponse(nextResponse);
};
useEffect(() => {
if (auth.loading || !auth.user || hasFetched.current) return;
hasFetched.current = true;
@ -85,7 +59,7 @@ export default function ModelConfigurationV2({
return;
}
setDefaults(nextDefaults);
applyResponse(configResult.data);
setResponse(configResult.data);
setLoading(false);
};
@ -93,14 +67,6 @@ export default function ModelConfigurationV2({
}, [auth.loading, auth.user]);
useEffect(() => {
if (hasAppliedInitialMigrationAction.current) return;
if (initialAction !== "migrate_to_v2") return;
if (loading || response?.source !== "legacy_user_v1") return;
hasAppliedInitialMigrationAction.current = true;
setMigrationDialogOpen(true);
}, [initialAction, loading, response?.source]);
const saveConfiguration = async (configuration: OrganizationAiModelConfigurationV2) => {
if (!defaults) return;
setError(null);
@ -117,50 +83,11 @@ export default function ModelConfigurationV2({
throw new Error("Failed to save model configuration");
}
applyResponse(result.data);
setResponse(result.data);
await refreshConfig();
setNotice("Model configuration saved");
};
const migrateConfiguration = async () => {
if (!defaults) return;
setMigrating(true);
setError(null);
setNotice(null);
const result = await migrateModelConfigurationV2ApiV1OrganizationsModelConfigurationsV2MigratePost();
if (result.error) {
setError(detailFromError(result.error, "Failed to migrate model configuration"));
} else if (!result.data) {
setError("Failed to migrate model configuration");
} else {
applyResponse(result.data);
await refreshConfig();
setNotice("Configuration migrated to v2");
setMigrationDialogOpen(false);
}
setMigrating(false);
};
const migrationWarningDialog = (
<AlertDialog open={migrationDialogOpen} onOpenChange={setMigrationDialogOpen}>
<AlertDialogContent>
<AlertDialogHeader>
<AlertDialogTitle>Migrate model configuration to v2?</AlertDialogTitle>
<AlertDialogDescription>
Your configurations will be migrated to v2. After migration, check your global configuration and workflow model overrides, then run a test call to make sure everything is working.
</AlertDialogDescription>
</AlertDialogHeader>
<AlertDialogFooter>
<AlertDialogCancel disabled={migrating}>Cancel</AlertDialogCancel>
<Button type="button" onClick={migrateConfiguration} disabled={migrating}>
{migrating ? "Migrating..." : "Migrate to v2"}
</Button>
</AlertDialogFooter>
</AlertDialogContent>
</AlertDialog>
);
if (loading) {
return (
<div className="w-full max-w-4xl mx-auto space-y-6">
@ -171,68 +98,6 @@ export default function ModelConfigurationV2({
);
}
const source = response?.source || "empty";
if (source !== "organization_v2") {
return (
<div className="w-full max-w-4xl mx-auto space-y-6">
<div className="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
<div>
<div className="flex items-center gap-2">
<h1 className="text-3xl font-bold">AI Models Configuration</h1>
<Badge variant="outline">
{source === "legacy_user_v1" ? "legacy" : "v1"}
</Badge>
</div>
<p className="mt-2 text-sm text-muted-foreground">
Configure your AI model, voice, and transcription services.{" "}
{docsUrl && (
<a href={docsUrl} target="_blank" rel="noopener noreferrer" className="inline-flex items-center gap-0.5 underline">
Learn more <ExternalLink className="h-3 w-3" />
</a>
)}
</p>
</div>
{source === "legacy_user_v1" && (
<Button type="button" variant="outline" onClick={() => setMigrationDialogOpen(true)} disabled={migrating}>
<RefreshCw className="mr-2 h-4 w-4" />
{migrating ? "Migrating..." : "Migrate to v2"}
</Button>
)}
</div>
{error && (
<div className="rounded-md border border-destructive/40 bg-destructive/10 px-4 py-3 text-sm text-destructive">
{error}
</div>
)}
{notice && (
<div className="rounded-md border border-green-500/40 bg-green-500/10 px-4 py-3 text-sm text-green-700 dark:text-green-300">
{notice}
</div>
)}
<ServiceConfigurationForm
mode="global"
onSave={async (config) => {
setError(null);
setNotice(null);
await saveUserConfig(config as Parameters<typeof saveUserConfig>[0]);
await refreshConfig();
if (defaults) {
const configResult = await getModelConfigurationV2ApiV1OrganizationsModelConfigurationsV2Get();
if (configResult.data) {
applyResponse(configResult.data);
}
}
setNotice("Configuration saved");
}}
/>
{migrationWarningDialog}
</div>
);
}
return (
<div className="w-full max-w-4xl mx-auto space-y-6">
<div className="flex flex-col gap-3 sm:flex-row sm:items-start sm:justify-between">
@ -268,7 +133,6 @@ export default function ModelConfigurationV2({
onSave={saveConfiguration}
/>
)}
{migrationWarningDialog}
</div>
);
}

View file

@ -1,37 +0,0 @@
"use client";
import { ExternalLink } from "lucide-react";
import { ServiceConfigurationForm } from "@/components/ServiceConfigurationForm";
import { useUserConfig } from "@/context/UserConfigContext";
interface ServiceConfigurationProps {
docsUrl?: string;
}
export default function ServiceConfiguration({ docsUrl }: ServiceConfigurationProps) {
const { saveUserConfig } = useUserConfig();
return (
<div className="w-full max-w-2xl mx-auto">
<div className="mb-6">
<h1 className="text-3xl font-bold mb-2">AI Models Configuration</h1>
<p className="text-muted-foreground">
Configure your AI model, voice, and transcription services.{" "}
{docsUrl && (
<a href={docsUrl} target="_blank" rel="noopener noreferrer" className="inline-flex items-center gap-0.5 underline">
Learn more <ExternalLink className="h-3 w-3" />
</a>
)}
</p>
</div>
<ServiceConfigurationForm
mode="global"
onSave={async (config) => {
await saveUserConfig(config);
}}
/>
</div>
);
}

View file

@ -1,122 +0,0 @@
"use client";
import { UserRound } from "lucide-react";
import posthog from "posthog-js";
import { useCallback, useEffect, useState } from "react";
import { getMpsCreditsApiV1OrganizationsUsageMpsCreditsGet } from "@/client/sdk.gen";
import type { MpsCreditsResponse } from "@/client/types.gen";
import { BuyCreditsControl } from "@/components/billing/BuyCreditsControl";
import { Button } from "@/components/ui/button";
import { Card, CardContent, CardDescription, CardHeader, CardTitle } from "@/components/ui/card";
import { Progress } from "@/components/ui/progress";
import { PostHogEvent } from "@/constants/posthog-events";
import { useLeadForms } from "@/context/LeadFormsContext";
import { useAuth } from "@/lib/auth";
export function DograhCreditsCard() {
const auth = useAuth();
const { openHireExpert, openEnterprise } = useLeadForms();
const [mpsCredits, setMpsCredits] = useState<MpsCreditsResponse | null>(null);
const [isLoadingCredits, setIsLoadingCredits] = useState(true);
const fetchMpsCredits = useCallback(async () => {
if (!auth.isAuthenticated) return;
try {
const response = await getMpsCreditsApiV1OrganizationsUsageMpsCreditsGet();
// The generated client resolves to { data, error } and does NOT throw on
// 4xx/5xx (see ui/AGENTS.md) — check error explicitly.
if (response.error) {
console.error("Failed to fetch MPS credits:", response.error);
} else if (response.data) {
setMpsCredits(response.data);
}
} catch (error) {
console.error("Failed to fetch MPS credits:", error);
} finally {
setIsLoadingCredits(false);
}
}, [auth.isAuthenticated]);
useEffect(() => {
if (auth.isAuthenticated) {
fetchMpsCredits();
}
}, [auth.isAuthenticated, fetchMpsCredits]);
return (
<Card className="mb-6">
<CardHeader>
<CardTitle>Dograh Model Credits</CardTitle>
<CardDescription>
These track usage of Dograh models using Dograh Service Keys.
</CardDescription>
</CardHeader>
<CardContent>
{isLoadingCredits ? (
<div className="animate-pulse space-y-4">
<div className="h-4 bg-muted rounded w-1/4"></div>
<div className="h-8 bg-muted rounded"></div>
<div className="h-4 bg-muted rounded w-1/3"></div>
</div>
) : mpsCredits ? (
<div className="space-y-4">
<div className="flex justify-between items-baseline">
<div>
<p className="text-2xl font-bold">
{mpsCredits.total_credits_used.toFixed(2)}{" "}
<span className="text-lg font-normal text-muted-foreground">
/ {mpsCredits.total_quota.toFixed(2)}
</span>
</p>
<p className="text-sm text-muted-foreground">Credits Used</p>
</div>
<div className="text-right">
<p className="text-lg font-semibold">{mpsCredits.remaining_credits.toFixed(2)}</p>
<p className="text-sm text-muted-foreground">Remaining</p>
</div>
</div>
{mpsCredits.total_quota > 0 && (
<Progress value={Math.min(100, (mpsCredits.total_credits_used / mpsCredits.total_quota) * 100)} className="h-3" />
)}
</div>
) : (
<p className="text-muted-foreground">
No Dograh service keys configured. Set up a service key in your model configuration to see usage.
</p>
)}
{/* Footer CTAs self-serve + done-for-you side by side, with the
custom-pricing link directly beneath. */}
<div className="mt-6 space-y-4 border-t pt-4">
<div className="space-y-1">
<p className="text-sm font-medium">Running low?</p>
<p className="text-sm text-muted-foreground">Top up instantly, or have us build it for you.</p>
</div>
<div className="flex flex-col gap-2 sm:flex-row">
<BuyCreditsControl className="w-full sm:flex-1" />
<Button
variant="outline"
className="w-full gap-2 sm:flex-1"
onClick={() => openHireExpert("billing_card")}
>
<UserRound className="h-4 w-4" />
Hire an Expert
</Button>
</div>
<button
type="button"
onClick={() => {
posthog.capture(PostHogEvent.CUSTOM_PRICING_CLICKED);
openEnterprise("billing_custom_pricing");
}}
className="block text-xs text-muted-foreground underline decoration-dashed underline-offset-4 hover:text-foreground"
>
Book a Strategy Call: custom pricing for committed volume
</button>
</div>
</CardContent>
</Card>
);
}

View file

@ -38,6 +38,7 @@ export interface RealtimeFeedbackEvent {
final?: boolean;
user_id?: string;
timestamp?: string;
end_timestamp?: string;
function_name?: string;
tool_call_id?: string;
arguments?: unknown;

View file

@ -3,7 +3,7 @@
import { createContext, ReactNode, useCallback, useContext, useEffect, useRef, useState } from 'react';
import { client } from '@/client/client.gen';
import { getCurrentOrganizationContextApiV1OrganizationsContextGet, getUserConfigurationsApiV1UserConfigurationsUserGet, updateUserConfigurationsApiV1UserConfigurationsUserPut } from '@/client/sdk.gen';
import { getCurrentOrganizationContextApiV1OrganizationsContextGet, getUserConfigurationsApiV1UserConfigurationsUserGet } from '@/client/sdk.gen';
import type { OrganizationContextResponse, UserConfigurationRequestResponseSchema } from '@/client/types.gen';
import { setupAuthInterceptor } from '@/lib/apiClient';
import type { AuthUser } from '@/lib/auth';
@ -22,7 +22,6 @@ interface OrganizationPricing {
interface OrgConfigContextType {
orgContext: OrganizationContextResponse | null;
userConfig: UserConfigurationRequestResponseSchema | null;
saveUserConfig: (userConfig: UserConfigurationRequestResponseSchema) => Promise<void>;
loading: boolean;
error: Error | null;
refreshConfig: () => Promise<void>;
@ -133,33 +132,6 @@ export function OrgConfigProvider({ children }: { children: ReactNode }) {
fetchConfig();
}, [auth.loading, auth.isAuthenticated, fetchConfig]);
const saveUserConfig = useCallback(async (userConfigRequest: UserConfigurationRequestResponseSchema) => {
if (!authRef.current.isAuthenticated) throw new Error('No authentication available');
const response = await updateUserConfigurationsApiV1UserConfigurationsUserPut({
body: {
...userConfig,
...userConfigRequest,
} as UserConfigurationRequestResponseSchema,
});
if (response.error) {
let msg = 'Failed to save user configuration';
const detail = (response.error as unknown as { detail?: string | { errors: { model: string; message: string }[] } }).detail;
if (typeof detail === 'string') {
msg = detail;
} else if (Array.isArray(detail)) {
msg = detail
.map((e: { model: string; message: string }) => `${e.model}: ${e.message}`)
.join('\n');
}
throw new Error(msg);
}
if (response.data) {
setUserConfig(response.data);
setOrganizationPricing(pricingFromUserConfig(response.data));
}
}, [userConfig]);
const refreshConfig = useCallback(async () => {
await fetchConfig();
}, [fetchConfig]);
@ -169,7 +141,6 @@ export function OrgConfigProvider({ children }: { children: ReactNode }) {
value={{
orgContext,
userConfig,
saveUserConfig,
loading,
error,
refreshConfig,

View file

@ -60,6 +60,14 @@ export const DEFAULT_VOICEMAIL_DETECTION_CONFIGURATION: VoicemailDetectionConfig
long_speech_timeout: 8.0,
};
export interface TranscriptConfiguration {
include_end_timestamps: boolean;
}
export const DEFAULT_TRANSCRIPT_CONFIGURATION: TranscriptConfiguration = {
include_end_timestamps: false,
};
export interface ModelOverrides {
llm?: {
provider?: string;
@ -115,6 +123,7 @@ export type WorkflowConfigurations = WorkflowConfigurationBase & {
turn_stop_strategy: TurnStopStrategy; // Strategy for detecting end of user turn
dictionary?: string; // Comma-separated words for voice agent to listen for
voicemail_detection?: VoicemailDetectionConfiguration;
transcript_configuration: TranscriptConfiguration;
context_compaction_enabled: boolean; // Summarize context on node transitions to remove stale tool calls
model_overrides?: ModelOverrides; // Per-workflow model configuration overrides
model_configuration_v2_override?: OrganizationAiModelConfigurationV2; // Full v2 model configuration override
@ -134,6 +143,7 @@ const FALLBACK_WORKFLOW_CONFIGURATIONS: WorkflowConfigurations = {
provisional_vad_pause_secs: DEFAULT_PROVISIONAL_VAD_PAUSE_SECS,
turn_stop_strategy: 'transcription', // Default to transcription-based detection
dictionary: '',
transcript_configuration: DEFAULT_TRANSCRIPT_CONFIGURATION,
context_compaction_enabled: false,
};
@ -186,5 +196,10 @@ export function resolveWorkflowConfigurations(
configurations?.context_compaction_enabled
?? defaults?.context_compaction_enabled
?? FALLBACK_WORKFLOW_CONFIGURATIONS.context_compaction_enabled,
transcript_configuration: {
...DEFAULT_TRANSCRIPT_CONFIGURATION,
...(defaults?.transcript_configuration as Partial<TranscriptConfiguration> | undefined),
...(configurations?.transcript_configuration as Partial<TranscriptConfiguration> | undefined),
},
};
}