From 7ac3398312fa7bc8a558d278ce65ce97f4c2ee17 Mon Sep 17 00:00:00 2001 From: Alain Prasquier Date: Wed, 13 May 2026 14:20:55 +0300 Subject: [PATCH 01/44] apply dependabot insights --- uv.lock | 85 +++++++++++++++++++++++++++++---------------------------- 1 file changed, 43 insertions(+), 42 deletions(-) diff --git a/uv.lock b/uv.lock index d53f749..06841de 100644 --- a/uv.lock +++ b/uv.lock @@ -1257,16 +1257,17 @@ wheels = [ [[package]] name = "protobuf" -version = "6.32.1" +version = "6.33.6" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/fa/a4/cc17347aa2897568beece2e674674359f911d6fe21b0b8d6268cd42727ac/protobuf-6.32.1.tar.gz", hash = "sha256:ee2469e4a021474ab9baafea6cd070e5bf27c7d29433504ddea1a4ee5850f68d", size = 440635, upload-time = "2025-09-11T21:38:42.935Z" } +sdist = { url = "https://files.pythonhosted.org/packages/66/70/e908e9c5e52ef7c3a6c7902c9dfbb34c7e29c25d2f81ade3856445fd5c94/protobuf-6.33.6.tar.gz", hash = "sha256:a6768d25248312c297558af96a9f9c929e8c4cee0659cb07e780731095f38135", size = 444531, upload-time = "2026-03-18T19:05:00.988Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c0/98/645183ea03ab3995d29086b8bf4f7562ebd3d10c9a4b14ee3f20d47cfe50/protobuf-6.32.1-cp310-abi3-win32.whl", hash = "sha256:a8a32a84bc9f2aad712041b8b366190f71dde248926da517bde9e832e4412085", size = 424411, upload-time = "2025-09-11T21:38:27.427Z" }, - { url = "https://files.pythonhosted.org/packages/8c/f3/6f58f841f6ebafe076cebeae33fc336e900619d34b1c93e4b5c97a81fdfa/protobuf-6.32.1-cp310-abi3-win_amd64.whl", hash = "sha256:b00a7d8c25fa471f16bc8153d0e53d6c9e827f0953f3c09aaa4331c718cae5e1", size = 435738, upload-time = "2025-09-11T21:38:30.959Z" }, - { url = "https://files.pythonhosted.org/packages/10/56/a8a3f4e7190837139e68c7002ec749190a163af3e330f65d90309145a210/protobuf-6.32.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:d8c7e6eb619ffdf105ee4ab76af5a68b60a9d0f66da3ea12d1640e6d8dab7281", size = 426454, upload-time = "2025-09-11T21:38:34.076Z" }, - { url = "https://files.pythonhosted.org/packages/3f/be/8dd0a927c559b37d7a6c8ab79034fd167dcc1f851595f2e641ad62be8643/protobuf-6.32.1-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:2f5b80a49e1eb7b86d85fcd23fe92df154b9730a725c3b38c4e43b9d77018bf4", size = 322874, upload-time = "2025-09-11T21:38:35.509Z" }, - { url = "https://files.pythonhosted.org/packages/5c/f6/88d77011b605ef979aace37b7703e4eefad066f7e84d935e5a696515c2dd/protobuf-6.32.1-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:b1864818300c297265c83a4982fd3169f97122c299f56a56e2445c3698d34710", size = 322013, upload-time = "2025-09-11T21:38:37.017Z" }, - { url = "https://files.pythonhosted.org/packages/97/b7/15cc7d93443d6c6a84626ae3258a91f4c6ac8c0edd5df35ea7658f71b79c/protobuf-6.32.1-py3-none-any.whl", hash = "sha256:2601b779fc7d32a866c6b4404f9d42a3f67c5b9f3f15b4db3cccabe06b95c346", size = 169289, upload-time = "2025-09-11T21:38:41.234Z" }, + { url = "https://files.pythonhosted.org/packages/fc/9f/2f509339e89cfa6f6a4c4ff50438db9ca488dec341f7e454adad60150b00/protobuf-6.33.6-cp310-abi3-win32.whl", hash = "sha256:7d29d9b65f8afef196f8334e80d6bc1d5d4adedb449971fefd3723824e6e77d3", size = 425739, upload-time = "2026-03-18T19:04:48.373Z" }, + { url = "https://files.pythonhosted.org/packages/76/5d/683efcd4798e0030c1bab27374fd13a89f7c2515fb1f3123efdfaa5eab57/protobuf-6.33.6-cp310-abi3-win_amd64.whl", hash = "sha256:0cd27b587afca21b7cfa59a74dcbd48a50f0a6400cfb59391340ad729d91d326", size = 437089, upload-time = "2026-03-18T19:04:50.381Z" }, + { url = "https://files.pythonhosted.org/packages/5c/01/a3c3ed5cd186f39e7880f8303cc51385a198a81469d53d0fdecf1f64d929/protobuf-6.33.6-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:9720e6961b251bde64edfdab7d500725a2af5280f3f4c87e57c0208376aa8c3a", size = 427737, upload-time = "2026-03-18T19:04:51.866Z" }, + { url = "https://files.pythonhosted.org/packages/ee/90/b3c01fdec7d2f627b3a6884243ba328c1217ed2d978def5c12dc50d328a3/protobuf-6.33.6-cp39-abi3-manylinux2014_aarch64.whl", hash = "sha256:e2afbae9b8e1825e3529f88d514754e094278bb95eadc0e199751cdd9a2e82a2", size = 324610, upload-time = "2026-03-18T19:04:53.096Z" }, + { url = "https://files.pythonhosted.org/packages/9b/ca/25afc144934014700c52e05103c2421997482d561f3101ff352e1292fb81/protobuf-6.33.6-cp39-abi3-manylinux2014_s390x.whl", hash = "sha256:c96c37eec15086b79762ed265d59ab204dabc53056e3443e702d2681f4b39ce3", size = 339381, upload-time = "2026-03-18T19:04:54.616Z" }, + { url = "https://files.pythonhosted.org/packages/16/92/d1e32e3e0d894fe00b15ce28ad4944ab692713f2e7f0a99787405e43533a/protobuf-6.33.6-cp39-abi3-manylinux2014_x86_64.whl", hash = "sha256:e9db7e292e0ab79dd108d7f1a94fe31601ce1ee3f7b79e0692043423020b0593", size = 323436, upload-time = "2026-03-18T19:04:55.768Z" }, + { url = "https://files.pythonhosted.org/packages/c4/72/02445137af02769918a93807b2b7890047c32bfb9f90371cbc12688819eb/protobuf-6.33.6-py3-none-any.whl", hash = "sha256:77179e006c476e69bf8e8ce866640091ec42e1beb80b213c3900006ecfba6901", size = 170656, upload-time = "2026-03-18T19:04:59.826Z" }, ] [[package]] @@ -1308,11 +1309,11 @@ wheels = [ [[package]] name = "pyasn1" -version = "0.6.1" +version = "0.6.3" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/ba/e9/01f1a64245b89f039897cb0130016d79f77d52669aae6ee7b159a6c4c018/pyasn1-0.6.1.tar.gz", hash = "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034", size = 145322, upload-time = "2024-09-10T22:41:42.55Z" } +sdist = { url = "https://files.pythonhosted.org/packages/5c/5f/6583902b6f79b399c9c40674ac384fd9cd77805f9e6205075f828ef11fb2/pyasn1-0.6.3.tar.gz", hash = "sha256:697a8ecd6d98891189184ca1fa05d1bb00e2f84b5977c481452050549c8a72cf", size = 148685, upload-time = "2026-03-17T01:06:53.382Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c8/f1/d6a797abb14f6283c0ddff96bbdd46937f64122b8c925cab503dd37f8214/pyasn1-0.6.1-py3-none-any.whl", hash = "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629", size = 83135, upload-time = "2024-09-11T16:00:36.122Z" }, + { url = "https://files.pythonhosted.org/packages/5d/a0/7d793dce3fa811fe047d6ae2431c672364b462850c6235ae306c0efd025f/pyasn1-0.6.3-py3-none-any.whl", hash = "sha256:a80184d120f0864a52a073acc6fc642847d0be408e7c7252f31390c0f4eadcde", size = 83997, upload-time = "2026-03-17T01:06:52.036Z" }, ] [[package]] @@ -1428,11 +1429,11 @@ wheels = [ [[package]] name = "pygments" -version = "2.19.2" +version = "2.20.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/b0/77/a5b8c569bf593b0140bde72ea885a803b82086995367bf2037de0159d924/pygments-2.19.2.tar.gz", hash = "sha256:636cb2477cec7f8952536970bc533bc43743542f70392ae026374600add5b887", size = 4968631, upload-time = "2025-06-21T13:39:12.283Z" } +sdist = { url = "https://files.pythonhosted.org/packages/c3/b2/bc9c9196916376152d655522fdcebac55e66de6603a76a02bca1b6414f6c/pygments-2.20.0.tar.gz", hash = "sha256:6757cd03768053ff99f3039c1a36d6c0aa0b263438fcab17520b30a303a82b5f", size = 4955991, upload-time = "2026-03-29T13:29:33.898Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/c7/21/705964c7812476f378728bdf590ca4b771ec72385c533964653c68e86bdc/pygments-2.19.2-py3-none-any.whl", hash = "sha256:86540386c03d588bb81d44bc3928634ff26449851e99741617ecb9037ee5ec0b", size = 1225217, upload-time = "2025-06-21T13:39:07.939Z" }, + { url = "https://files.pythonhosted.org/packages/f4/7e/a72dd26f3b0f4f2bf1dd8923c85f7ceb43172af56d63c7383eb62b332364/pygments-2.20.0-py3-none-any.whl", hash = "sha256:81a9e26dd42fd28a23a2d169d86d7ac03b46e2f8b59ed4698fb4785f946d0176", size = 1231151, upload-time = "2026-03-29T13:29:30.038Z" }, ] [[package]] @@ -1636,7 +1637,7 @@ wheels = [ [[package]] name = "requests" -version = "2.32.5" +version = "2.34.0" source = { registry = "https://pypi.org/simple" } dependencies = [ { name = "certifi" }, @@ -1644,9 +1645,9 @@ dependencies = [ { name = "idna" }, { name = "urllib3" }, ] -sdist = { url = "https://files.pythonhosted.org/packages/c9/74/b3ff8e6c8446842c3f5c837e9c3dfcfe2018ea6ecef224c710c85ef728f4/requests-2.32.5.tar.gz", hash = "sha256:dbba0bac56e100853db0ea71b82b4dfd5fe2bf6d3754a8893c3af500cec7d7cf", size = 134517, upload-time = "2025-08-18T20:46:02.573Z" } +sdist = { url = "https://files.pythonhosted.org/packages/43/b8/7a707d60fea4c49094e40262cc0e2ca6c768cca21587e34d3f705afec47e/requests-2.34.0.tar.gz", hash = "sha256:7d62fe92f50eb82c529b0916bb445afa1531a566fc8f35ffdc64446e771b856a", size = 142436, upload-time = "2026-05-11T19:29:51.717Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/1e/db/4254e3eabe8020b458f1a747140d32277ec7a271daf1d235b70dc0b4e6e3/requests-2.32.5-py3-none-any.whl", hash = "sha256:2462f94637a34fd532264295e186976db0f5d453d1cdd31473c85a6a161affb6", size = 64738, upload-time = "2025-08-18T20:46:00.542Z" }, + { url = "https://files.pythonhosted.org/packages/ef/e6/e300fce5fe83c30520607a015dabd985df3251e188d234bfe9492e17a389/requests-2.34.0-py3-none-any.whl", hash = "sha256:917520a21b767485ce7c588f4ebb917c436b24a31231b44228715eaeb5a52c60", size = 73021, upload-time = "2026-05-11T19:29:49.923Z" }, ] [[package]] @@ -2099,11 +2100,11 @@ wheels = [ [[package]] name = "urllib3" -version = "2.5.0" +version = "2.7.0" source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/15/22/9ee70a2574a4f4599c47dd506532914ce044817c7752a79b6a51286319bc/urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760", size = 393185, upload-time = "2025-06-18T14:07:41.644Z" } +sdist = { url = "https://files.pythonhosted.org/packages/53/0c/06f8b233b8fd13b9e5ee11424ef85419ba0d8ba0b3138bf360be2ff56953/urllib3-2.7.0.tar.gz", hash = "sha256:231e0ec3b63ceb14667c67be60f2f2c40a518cb38b03af60abc813da26505f4c", size = 433602, upload-time = "2026-05-07T16:13:18.596Z" } wheels = [ - { url = "https://files.pythonhosted.org/packages/a7/c2/fe1e52489ae3122415c51f387e221dd0773709bad6c6cdaa599e8a2c5185/urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc", size = 129795, upload-time = "2025-06-18T14:07:40.39Z" }, + { url = "https://files.pythonhosted.org/packages/7f/3e/5db95bcf282c52709639744ca2a8b149baccf648e39c8cc87553df9eae0c/urllib3-2.7.0-py3-none-any.whl", hash = "sha256:9fb4c81ebbb1ce9531cce37674bbc6f1360472bc18ca9a553ede278ef7276897", size = 131087, upload-time = "2026-05-07T16:13:17.151Z" }, ] [[package]] @@ -2120,28 +2121,28 @@ wheels = [ [[package]] name = "uv" -version = "0.8.8" -source = { registry = "https://pypi.org/simple" } -sdist = { url = "https://files.pythonhosted.org/packages/9c/d0/4cd8ac2c7938da78c8e9ca791205f80e74b0f5a680f2a2d50323d54961d0/uv-0.8.8.tar.gz", hash = "sha256:6880e96cd994e53445d364206ddb4b2fff89fd2fbc74a74bef4a6f86384b07d9", size = 3477036, upload-time = "2025-08-09T00:26:00.883Z" } -wheels = [ - { url = "https://files.pythonhosted.org/packages/08/d5/49e188db80f3d8b1969bdbcb8a5468a3796827f15d773241204f206a9ff6/uv-0.8.8-py3-none-linux_armv6l.whl", hash = "sha256:fcdbee030de120478db1a4bb3e3bbf04eec572527ea9107ecf064a808259b6c9", size = 18470316, upload-time = "2025-08-09T00:25:11.956Z" }, - { url = "https://files.pythonhosted.org/packages/01/50/add1afadccd141d0d72b54e5146f8181fcc6efd1567a17c5b1edec444010/uv-0.8.8-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:461e8fb83931755cf0596bf1b8ccbfe02765e81a0d392c495c07685d6b6591f9", size = 18468770, upload-time = "2025-08-09T00:25:15.391Z" }, - { url = "https://files.pythonhosted.org/packages/8c/ac/3c6dc8781d37ef9854f412322caffac2978dd3fa1bf806f7daebcfebf2be/uv-0.8.8-py3-none-macosx_11_0_arm64.whl", hash = "sha256:58056e5ccebb0a1aad27bd89d0ccc5b65c086d5a7f6b0ac16a9dde030b63cf14", size = 17200419, upload-time = "2025-08-09T00:25:18.264Z" }, - { url = "https://files.pythonhosted.org/packages/a1/9e/c30ea1f634673d234999985984afbe96c3d2a4381986e36df0bb46c0f21b/uv-0.8.8-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:5b4c56a620137f562e1d7b09eac6c9d4adeb876aefc51be27973257fcb426c9d", size = 17779351, upload-time = "2025-08-09T00:25:20.891Z" }, - { url = "https://files.pythonhosted.org/packages/2f/89/f2885c6e97a265b4b18050df6285f56c81b603a867a63fcd8f2caa04d95c/uv-0.8.8-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5fc33adb91c4e3db550648aa30c2b97e8e4d8b8842ead7784a9e76dae3cb14dc", size = 18139292, upload-time = "2025-08-09T00:25:23.352Z" }, - { url = "https://files.pythonhosted.org/packages/38/5f/98dad16987919e7dc02f2566026a263ea6307bf57e8de0008dde4717d9cf/uv-0.8.8-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:19a82d6738d3aa58e6646b9d6c343d103abf0c4caf97a68d16a8cab55282e4be", size = 18932468, upload-time = "2025-08-09T00:25:25.691Z" }, - { url = "https://files.pythonhosted.org/packages/56/99/52d0d9f53cc5df11b1a459e743bd7b2f4660d49f125a63640eb85ce993e0/uv-0.8.8-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:9dce4de70098cb5b98feea9ef0b8f7db5d6b9deea003a926bc044a793872d719", size = 20251614, upload-time = "2025-08-09T00:25:28.122Z" }, - { url = "https://files.pythonhosted.org/packages/9e/b1/0698099a905b4a07b8fa9d6838e0680de707216ccf003433ca1b4afff224/uv-0.8.8-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1038324c178d2d7407a4005c4c3294cbad6a02368ba5a85242308de62a6f4e12", size = 19916222, upload-time = "2025-08-09T00:25:30.732Z" }, - { url = "https://files.pythonhosted.org/packages/7f/29/8384e0f3f3536ef376d94b7ab177753179906a6c2f5bab893e3fb9525b45/uv-0.8.8-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3bd016beea3935f9148b3d2482e3d60dee36f0260f9e99d4f57acfd978c1142a", size = 19238516, upload-time = "2025-08-09T00:25:33.637Z" }, - { url = "https://files.pythonhosted.org/packages/0e/f1/6c107deccd6e66eb1c46776d8cef4ca9274aac73cec1b14453fe85e18a54/uv-0.8.8-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0a2b5ebc96aba2b0bf54283d2906b40f32949298cbc6ec48648097ddeac5c5d", size = 19232295, upload-time = "2025-08-09T00:25:37.154Z" }, - { url = "https://files.pythonhosted.org/packages/c5/96/9f5e935cd970102c67ce2a753ac721665fb4477c262e86afa0ab385cefff/uv-0.8.8-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:e529dc0a1be5e896d299e4eae4599fa68909f8cb3e6c5ee1a46f66c9048e3334", size = 18046917, upload-time = "2025-08-09T00:25:39.72Z" }, - { url = "https://files.pythonhosted.org/packages/32/75/97f371add0a02e5e37156ac0fea908ab4a1160fdf716d0e6c257b6767122/uv-0.8.8-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:5d58d986c3b6a9ce0fb48cd48b3aee6cb1b1057f928d598432e75a4fcaa370f4", size = 18949133, upload-time = "2025-08-09T00:25:42.139Z" }, - { url = "https://files.pythonhosted.org/packages/1a/1b/ea988ae9d8c5531454ea6904290e229624c9ea830a5c37b91ec74ebde9a4/uv-0.8.8-py3-none-musllinux_1_1_armv7l.whl", hash = "sha256:e117e1230559058fd286292dd5839e8e82d1aaf05763bf4a496e91fe07b69fa1", size = 18080018, upload-time = "2025-08-09T00:25:44.645Z" }, - { url = "https://files.pythonhosted.org/packages/ff/14/3b16af331b79ae826d00a73e98f26f7f660dabedc0f82acb99069601b355/uv-0.8.8-py3-none-musllinux_1_1_i686.whl", hash = "sha256:372934fd94193c98dec59bd379cf39e73f906ae6162cbfb66686f32afd75fa0f", size = 18437896, upload-time = "2025-08-09T00:25:49.162Z" }, - { url = "https://files.pythonhosted.org/packages/1c/b6/c866684da5571dbf42e9a60b6587a62adc8a2eb592f07411d3b29cb09871/uv-0.8.8-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:9330c924faa9df00a5e78b54561ecf4e5eac1211066f027620dbe85bd6f479ce", size = 19341221, upload-time = "2025-08-09T00:25:51.444Z" }, - { url = "https://files.pythonhosted.org/packages/49/ea/55a0eff462b2ec5a6327dd87c401c53306406c830fa8f2cabd2af79dd97f/uv-0.8.8-py3-none-win32.whl", hash = "sha256:65113735aa3427d3897e2f537da1331d1391735c6eecb9b820da6a15fd2f6738", size = 18244601, upload-time = "2025-08-09T00:25:53.696Z" }, - { url = "https://files.pythonhosted.org/packages/bf/c0/f56ddb1b2276405618e3d2522018c962c010fc71f97f385d01b7e1dcd8df/uv-0.8.8-py3-none-win_amd64.whl", hash = "sha256:66189ca0b4051396aa19a6f036351477656073d0fd01618051faca699e1b3cdc", size = 20233481, upload-time = "2025-08-09T00:25:56.247Z" }, - { url = "https://files.pythonhosted.org/packages/ac/1a/70dc4c730c19f3af40be9450b98b801e03cd6d16609743013f7258f69a29/uv-0.8.8-py3-none-win_arm64.whl", hash = "sha256:1d829486e88ebbf7895306ff09a8b6014d3af7a18e27d751979ee37bf3a27832", size = 18786215, upload-time = "2025-08-09T00:25:58.941Z" }, +version = "0.11.14" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/30/a3/be4a946c7c2fc4094c020c8f7d8bd0a739bad55ebe4e2817d6e2b1bc6bff/uv-0.11.14.tar.gz", hash = "sha256:0ea006a117b586b2681b6dfd9703a540d2ad2a136ec0f48d272767e599cc3dfb", size = 4130699, upload-time = "2026-05-12T18:00:37.321Z" } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f7/15/9b2138b16eb1fa8c2cd84b1037ad10c38b3acc36ce96c6d27000bfb7e716/uv-0.11.14-py3-none-linux_armv6l.whl", hash = "sha256:78411a883f230a710af19f2ac6e6f0ba8eae90f0e5af4605f923fd367539fff4", size = 23545199, upload-time = "2026-05-12T18:01:34.526Z" }, + { url = "https://files.pythonhosted.org/packages/75/81/c678e8b9a8e624f9c338c66cd57dd9cfc6b5a0501ad3c87fd0cc0bf8850a/uv-0.11.14-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:078f2e63da89c8fcf6d578f02156045c5990c57d76464aab3f3f798d3fff95cd", size = 22957064, upload-time = "2026-05-12T18:00:54.225Z" }, + { url = "https://files.pythonhosted.org/packages/f7/ad/95fbd15b23f26f36d0cfb0ddf159b9602a1b1c0feced60a7f98385e919f1/uv-0.11.14-py3-none-macosx_11_0_arm64.whl", hash = "sha256:dcdad43d52c130e3159e84ab1844e04d819d2c4a2495a687d27f80d560a3650e", size = 21678307, upload-time = "2026-05-12T18:00:57.132Z" }, + { url = "https://files.pythonhosted.org/packages/8b/cb/b3da1c4d95d6dd507896bca16dbd643118013b2b151f5f35a08d3391728c/uv-0.11.14-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:9923da7c63d70de9fe71829503d7e7ebfd6304e804d7232aad5f716e190db25b", size = 23353409, upload-time = "2026-05-12T18:01:27.512Z" }, + { url = "https://files.pythonhosted.org/packages/51/ad/78c6b8d6bcc04c5043b50631e9b413422a03a0bd7c4a997748f8e9cbac25/uv-0.11.14-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl", hash = "sha256:3b0759ca504e48dcd4fafb1a61ef69aeb24c5a60fbf5f504a7873c8db1b24718", size = 23103964, upload-time = "2026-05-12T18:01:31.094Z" }, + { url = "https://files.pythonhosted.org/packages/0f/7d/acb66e09bc54a74e4288e996d841af04d88588fd6bdbfbab2468ab7169a7/uv-0.11.14-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:78b51b117549ee4db7197ea5ece0848cecd443e464fb9dff9f254cdc1e4ed96f", size = 23104638, upload-time = "2026-05-12T18:01:10.093Z" }, + { url = "https://files.pythonhosted.org/packages/31/0a/8497be61accdb8e56d02e11edd3ac471466259420e0bd9c05c1966df134a/uv-0.11.14-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a1ddbe8a2ab160affc179e9c3a40913b23a08cdf55254e1f3829cc22a51a0d8d", size = 24625888, upload-time = "2026-05-12T18:01:17.192Z" }, + { url = "https://files.pythonhosted.org/packages/95/91/f730799fd20a45777b255e20cf9f648a4e4e0979bf65e87a8633197cf7d9/uv-0.11.14-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f3005a2db1e8d72e125630d4f22ac4ceddb2c033e1f9b94b7f3ea38ebac46dd6", size = 25445231, upload-time = "2026-05-12T18:00:40.012Z" }, + { url = "https://files.pythonhosted.org/packages/f5/4d/106463fc27e63e402aec2e791774dac2db5bd5e1c36cdcf38125aa97ab1c/uv-0.11.14-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d5c8f9ea36274ef2f9d24f0522085e280844172e901d9213f66a21b212266706", size = 24571961, upload-time = "2026-05-12T18:00:43.713Z" }, + { url = "https://files.pythonhosted.org/packages/12/4d/163fe746b97bd1129627e8b1f943e17583ddc143eaab532d56a799a9ba5a/uv-0.11.14-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:379e64b236cf55f762a8308d7efe4365d5296ba29f3a4868761bc45b4e915a71", size = 24718523, upload-time = "2026-05-12T18:01:06.587Z" }, + { url = "https://files.pythonhosted.org/packages/19/fb/7a3673494a0cf70267559166398f9c50c4925ff20122f99a28d6c5a80d83/uv-0.11.14-py3-none-manylinux_2_28_aarch64.whl", hash = "sha256:29c12a562441fc2d604e6920c558cacce74a55f889468708683a79b35a6e18a1", size = 23454821, upload-time = "2026-05-12T18:00:51.166Z" }, + { url = "https://files.pythonhosted.org/packages/bb/43/6358394a567d865f3a5ce27b1e0d939549911e36d9b59f0c545a167f92f7/uv-0.11.14-py3-none-manylinux_2_31_riscv64.musllinux_1_1_riscv64.whl", hash = "sha256:e84069681c0334e07cbc7f114eb09d7fe1335e1db0297a66dbca80a1b393fe6d", size = 24087843, upload-time = "2026-05-12T18:00:47.272Z" }, + { url = "https://files.pythonhosted.org/packages/ef/f6/7d0ae1e1f52b85057ca24d8876d6a4cc87b541ea6aca627fe36594c06099/uv-0.11.14-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:b15bf7c146e38d7c938d3a207115d5fdd8ef764fe1f866c225b1bed27e88da1e", size = 24147611, upload-time = "2026-05-12T18:01:20.499Z" }, + { url = "https://files.pythonhosted.org/packages/5a/a2/511ad0c5da5697fd990b99569425b62b81cbc3458c35acc845211b55d6b5/uv-0.11.14-py3-none-musllinux_1_1_i686.whl", hash = "sha256:ddda5c5e41097814adac535c74851bae55e8097b9afc79aeae7fcffd8d86c06d", size = 23920348, upload-time = "2026-05-12T18:01:24.033Z" }, + { url = "https://files.pythonhosted.org/packages/6b/b6/7084e3401b1f1020f215a125136eec1ed2bd541e10a5fea1625515579599/uv-0.11.14-py3-none-musllinux_1_1_x86_64.whl", hash = "sha256:e54326703f1eca83a6fd73275e0f398b16b7d3f81531bf58899c2869bc403f6c", size = 24928981, upload-time = "2026-05-12T18:01:13.961Z" }, + { url = "https://files.pythonhosted.org/packages/4d/6a/7e81729fe729889c8cc63bbf64291734359bd7f6ba84852dc0504453511d/uv-0.11.14-py3-none-win32.whl", hash = "sha256:b384d873d0d18552c7524226125efd3965d921b7134c2f476c333771beb733e1", size = 22573503, upload-time = "2026-05-12T18:00:34.36Z" }, + { url = "https://files.pythonhosted.org/packages/94/5d/f8905f9af5cd46af2a688b2246dbb5a4d95b8557eeffd7f241e037659d9e/uv-0.11.14-py3-none-win_amd64.whl", hash = "sha256:f0a8b58b38e984241bca5d7a5a47bf9ffe1ca2ab392a640887db8a04c4a9ec95", size = 25175590, upload-time = "2026-05-12T18:01:00.38Z" }, + { url = "https://files.pythonhosted.org/packages/04/cb/7333d08d944f3018eb89242cd5e646e7b37faa1b567faeaf9254a8b59d53/uv-0.11.14-py3-none-win_arm64.whl", hash = "sha256:6a13e7e064563050c6606b3fd77091d427cdbdc5938b6f134baf8d8ec79bfdb7", size = 23594775, upload-time = "2026-05-12T18:01:03.55Z" }, ] [[package]] From 22d50aa5583d135440fc6a8eb33c178d6a7b5b02 Mon Sep 17 00:00:00 2001 From: Alain Prasquier Date: Wed, 13 May 2026 15:32:41 +0300 Subject: [PATCH 02/44] minor --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 0929216..51c6bf8 100644 --- a/.gitignore +++ b/.gitignore @@ -256,3 +256,4 @@ uv.lock / but/ .gitnexus +.claude/scheduled_tasks.lock From 2a896604b0176d446fbdfa9c5e8f060fdbc3fdf4 Mon Sep 17 00:00:00 2001 From: "Alain@Runwaize" Date: Wed, 13 May 2026 15:53:57 +0300 Subject: [PATCH 03/44] chore(ci): SHA-pin actions/checkout and actions/setup-python (#43) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Pin all uses of actions/checkout@v6 and actions/setup-python@v6 to their commit SHAs across every workflow, closing the remaining floating-tag attack surface. - actions/checkout → de0fac2e (v6) - actions/setup-python → a309ff8b (v6) --- .github/workflows/publish-pypi.yml | 4 ++-- .github/workflows/publish.yml | 4 ++-- .github/workflows/python-package.yml | 8 ++++---- .github/workflows/release.yml | 2 +- .github/workflows/trufflehog-full-scan.yml | 2 +- .github/workflows/trufflehog-security.yml | 2 +- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/.github/workflows/publish-pypi.yml b/.github/workflows/publish-pypi.yml index 4fcff7d..199b243 100644 --- a/.github/workflows/publish-pypi.yml +++ b/.github/workflows/publish-pypi.yml @@ -29,13 +29,13 @@ jobs: contents: write # required for committing version bump steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: fetch-depth: 0 token: ${{ secrets.GITHUB_TOKEN }} - name: Set up Python - uses: actions/setup-python@v6 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 with: python-version: "3.13" diff --git a/.github/workflows/publish.yml b/.github/workflows/publish.yml index 96e78d3..3bc2e40 100644 --- a/.github/workflows/publish.yml +++ b/.github/workflows/publish.yml @@ -15,10 +15,10 @@ jobs: id-token: write # required for trusted publishing if using PyPI's OIDC steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Set up Python - uses: actions/setup-python@v6 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 with: python-version: "3.13" diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index 1a78b28..ea2975e 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -14,8 +14,8 @@ jobs: pre-commit: runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6 - - uses: actions/setup-python@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 with: python-version: "3.13" - uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 @@ -43,9 +43,9 @@ jobs: python-version: ["3.10", "3.11", "3.12", "3.13"] steps: - - uses: actions/checkout@v6 + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 - name: Set up Python ${{ matrix.python-version }} - uses: actions/setup-python@v6 + uses: actions/setup-python@a309ff8b426b58ec0e2a45f0f869d46889d02405 # v6 with: python-version: ${{ matrix.python-version }} - name: Install uv diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index cc5c8ab..dc8b1e1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,7 +13,7 @@ jobs: contents: write steps: - name: Checkout code - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: fetch-depth: 0 # Required for generating release notes diff --git a/.github/workflows/trufflehog-full-scan.yml b/.github/workflows/trufflehog-full-scan.yml index 6037795..1cc69d8 100644 --- a/.github/workflows/trufflehog-full-scan.yml +++ b/.github/workflows/trufflehog-full-scan.yml @@ -18,7 +18,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: fetch-depth: 0 # Full git history for complete scanning diff --git a/.github/workflows/trufflehog-security.yml b/.github/workflows/trufflehog-security.yml index 3954d46..e3840a9 100644 --- a/.github/workflows/trufflehog-security.yml +++ b/.github/workflows/trufflehog-security.yml @@ -16,7 +16,7 @@ jobs: steps: - name: Checkout code - uses: actions/checkout@v6 + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 with: fetch-depth: 0 # Required for TruffleHog to scan git history From 297d98e857560632951293c68a2f461317e317f1 Mon Sep 17 00:00:00 2001 From: "Alain@Runwaize" Date: Wed, 13 May 2026 15:54:26 +0300 Subject: [PATCH 04/44] docs(changelog): add unreleased dependency security refresh entry (#44) --- docs/CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index d04ea06..9818aa2 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -17,6 +17,10 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +### Security + +- **`uv.lock`** — Refreshed transitive versions to address open Dependabot / GHSA advisories on the default branch graph: **urllib3** (redirect and decompression-chain issues), **requests** (`extract_zipped_paths` temp reuse), **protobuf** (JSON recursion depth), **pyasn1** (decoder / recursion DoS), **pygments** (ReDoS in GUID lexer), and **uv** (ZIP / tar / RECORD handling; dev dependency via hatch). + ## [0.20.0] - 2026-05-13 ### Security From 1c41f541f5201e447b6420320ab77819a7e2dcbf Mon Sep 17 00:00:00 2001 From: "Alain@Runwaize" Date: Wed, 13 May 2026 16:30:45 +0300 Subject: [PATCH 05/44] chore(ci): add uv cache-suffix per Python version + update AGENTS.md facts (#46) Prevents parallel matrix jobs racing on the same Actions cache reservation. Also records two CI tooling facts in AGENTS.md. --- .github/workflows/python-package.yml | 3 +++ AGENTS.md | 4 ++++ 2 files changed, 7 insertions(+) diff --git a/.github/workflows/python-package.yml b/.github/workflows/python-package.yml index ea2975e..781d29a 100644 --- a/.github/workflows/python-package.yml +++ b/.github/workflows/python-package.yml @@ -50,6 +50,9 @@ jobs: python-version: ${{ matrix.python-version }} - name: Install uv uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0 + with: + # Avoid parallel matrix jobs racing on the same Actions cache reservation + cache-suffix: py-${{ matrix.python-version }} - name: Install dependencies run: uv sync --frozen --extra dev --extra deploy - name: Test with pytest diff --git a/AGENTS.md b/AGENTS.md index 53879e0..5c23e15 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -29,6 +29,8 @@ Reference specific personas when requesting work: ## Learned User Preferences +- When preparing a merge to `main` or a release, keep `docs/CHANGELOG.md` **Unreleased** accurate; on request, align listed dependency or tooling changes with the delta since the previous git tag (including `pyproject.toml`). + ## Learned Workspace Facts - `supervaizer start --reload` (or `SUPERVAIZER_RELOAD=true`) enables Uvicorn’s `reload` (file watching, dev-only; leave off in production). @@ -36,6 +38,8 @@ Reference specific personas when requesting work: - Compliance for this repo expects explicit type annotations, including return types, on functions in new or modified Python files (including tests), for mypy-clean CI. - `ADMIN_ALLOWED_IPS` restricts `/admin` when set (comma-separated IPs/CIDR); unset or empty allows all client IPs. - In `9agents/agent_interviewer`, empty `MANAGE_ALLOWED_IPS` still requires `MANAGE_AUTH_TOKEN` when that env is set; supervaizer’s admin IP middleware has no equivalent token fallback when the allowlist is empty. +- CI (`python-package` workflow): the pre-commit job checks **Ruff** formatting (`ruff format --check`) and **YAML** in `.github/workflows` via `yamllint` (not Black). +- In the matrix **build** job, `astral-sh/setup-uv` sets `cache-suffix: py-${{ matrix.python-version }}` so parallel Python versions do not race on the same GitHub Actions cache reservation. ## Security and Supply-Chain Rules From 1f5c176c74f1cb5ee534ad42f2e6037cda3f337a Mon Sep 17 00:00:00 2001 From: "Alain@Runwaize" Date: Sun, 17 May 2026 15:06:05 +0300 Subject: [PATCH 06/44] supervaizer-v2-mvp-contracts (#47) * feat: add supervaizer v2 contract primitives * feat: add supervaizer v2 a2a action endpoint * feat: expose supervaizer v2 registration in a2a card * feat: add supervaizer v2 action decorator * docs: update supervaizer v2 changelog * precommit fix * refactor: move controller api version to contracts * minor * fix: scope v2 action handlers by agent * feat: guard supervaizer v2 agent identity * feat: include v2 job state in sync result * feat: add v2 resource form fields * feat: add v2 resource option sources * feat: add v2 awaiting form fields * feat: load supervaizer v2 surfaces over a2a * feat: expose local hello world v2 contract * feat: add v2 job source target type * feat: stream v2 action effects over a2a * fix: advertise v2 push notifications as unsupported * refactor: remove legacy dynamic choices * feat: complete local hello world v2 hitl flow * refactor: remove legacy job poll * docs: refresh generated contract docs * test: align v2 prompt editor fixture * test: align v2 contact import fixture * test: align v2 scenario builder fixture * test: align v2 overview fixture * test: align v2 campaign contact fixture * feat: add v2 registration builder * feat: type v2 dataset display metadata * minor * fix: precommit * feat: add comprehensive documentation for SUPERVAIZER API, Admin Interface, CLI, Parameter Validation, Persistence, Protocols, and REST API * minor * chore: change copyright dates from 2024-2025 to 2024-2026 * fix: harden agent model surface and v2 contract hygiene Use modern typing in agent.py, keep server encrypted params internal, document deterministic agent ids, tighten A2A health status rules, drop legacy hello-world v2 input aliases, and clarify v2 contract fields. * feat: enhance agent method validation and improve v2 action safety - Introduced validation to reject agent methods using blocked module roots.- Added checks to ensure declared method paths are used in agent execution.- Enhanced v2 action results with replay safety metadata validation.- Updated changelog and documentation to reflect these changes. * feat: add v2 resource import contracts * test: align v2 contract fixtures * minor * fix: require auth for a2a controller * minor --- AGENTS.md | 3 + README.md | 33 +- ..._REFERENCE.md => 2025_04_API_REFERENCE.md} | 4 + ...DMIN_README.md => 2025_08_ADMIN_README.md} | 4 + docs/{CLI.md => 2025_08_CLI.md} | 8 +- ...08_PARAMETER_VALIDATION_IMPLEMENTATION.md} | 4 + ...{PERSISTENCE.md => 2025_08_PERSISTENCE.md} | 4 + docs/2025_08_PROTOCOLS.md | 169 ++ docs/{REST_API.md => 2025_08_REST_API.md} | 4 + ...AL_TESTING.md => 2025_10_LOCAL_TESTING.md} | 4 + docs/2026_05_PROTOCOLS.md | 179 ++ docs/2026_05_SUPERVAIZER_v2.md | 415 +++++ docs/CHANGELOG.md | 60 +- docs/PROTOCOLS.md | 56 - docs/api/openapi.json | 1621 +++++++++-------- docs/model_reference/model_core.md | 16 +- docs/model_reference/model_extra.md | 801 +++++++- ...md => 2025_10_001-cloud-deployment-cli.md} | 8 +- ...nt.md => 2026_04_002-async-http-client.md} | 4 + ... 2026_03_2026-03-16-manage-hello-world.md} | 6 +- ... => 2026_04_2026-04-08-dynamic-choices.md} | 4 + ...3_2026-03-16-manage-hello-world-design.md} | 4 + src/supervaizer/__init__.py | 98 +- src/supervaizer/__version__.py | 9 +- src/supervaizer/access/__init__.py | 2 +- src/supervaizer/access/api_auth.py | 2 +- src/supervaizer/access/client_ip.py | 2 +- src/supervaizer/access/tailscale.py | 2 +- src/supervaizer/account.py | 8 +- src/supervaizer/account_service.py | 2 +- src/supervaizer/admin/ip_allowlist.py | 2 +- src/supervaizer/admin/routes.py | 5 +- .../admin/static/js/workbench-form.js | 34 +- .../admin/templates/workbench.html | 15 - src/supervaizer/admin/workbench_routes.py | 48 +- src/supervaizer/agent.py | 249 ++- src/supervaizer/case.py | 69 +- src/supervaizer/cli.py | 17 +- src/supervaizer/common.py | 31 +- src/supervaizer/contracts.py | 566 +++++- src/supervaizer/data_resource.py | 17 +- src/supervaizer/data_routes.py | 4 +- src/supervaizer/deploy/__init__.py | 2 +- src/supervaizer/deploy/cli.py | 16 +- src/supervaizer/deploy/commands/__init__.py | 6 +- src/supervaizer/deploy/commands/clean.py | 5 +- src/supervaizer/deploy/commands/down.py | 11 +- src/supervaizer/deploy/commands/local.py | 6 +- src/supervaizer/deploy/commands/plan.py | 13 +- src/supervaizer/deploy/commands/status.py | 11 +- src/supervaizer/deploy/commands/up.py | 13 +- src/supervaizer/deploy/docker.py | 17 +- src/supervaizer/deploy/driver_factory.py | 8 +- src/supervaizer/deploy/drivers/__init__.py | 8 +- .../deploy/drivers/aws_app_runner.py | 26 +- src/supervaizer/deploy/drivers/base.py | 62 +- src/supervaizer/deploy/drivers/cloud_run.py | 34 +- .../deploy/drivers/do_app_platform.py | 27 +- src/supervaizer/deploy/health.py | 50 +- src/supervaizer/deploy/state.py | 26 +- src/supervaizer/deploy/templates/debug_env.py | 2 +- src/supervaizer/deploy/utils.py | 2 +- src/supervaizer/event.py | 10 +- .../examples/controller_template.py | 17 +- src/supervaizer/examples/hello_world_agent.py | 340 +++- src/supervaizer/examples/local_server.py | 75 +- src/supervaizer/instructions.py | 2 +- src/supervaizer/job.py | 57 +- src/supervaizer/job_service.py | 17 +- src/supervaizer/lifecycle.py | 34 +- src/supervaizer/parameter.py | 21 +- src/supervaizer/protocol/__init__.py | 2 +- src/supervaizer/protocol/a2a/__init__.py | 5 +- src/supervaizer/protocol/a2a/controller.py | 300 +++ src/supervaizer/protocol/a2a/events.py | 91 + src/supervaizer/protocol/a2a/model.py | 53 +- src/supervaizer/protocol/a2a/routes.py | 57 +- src/supervaizer/routers/__init__.py | 2 +- src/supervaizer/routers/api.py | 4 +- src/supervaizer/routers/private.py | 2 +- src/supervaizer/routers/public.py | 13 +- src/supervaizer/routes.py | 70 +- src/supervaizer/server.py | 112 +- src/supervaizer/server_utils.py | 2 +- src/supervaizer/storage.py | 38 +- src/supervaizer/telemetry.py | 8 +- src/supervaizer/utils/__init__.py | 2 +- src/supervaizer/utils/version_check.py | 2 +- test_dockerfile_generation.py | 2 +- test_local.py | 2 +- tests/__init__.py | 6 +- tests/conftest.py | 12 +- .../supervaizer_v2/agent_interviewer_mvp.json | 475 +++++ tests/mock_api_responses.py | 2 +- tests/test_a2a.py | 557 +++++- tests/test_access_api_auth.py | 2 +- tests/test_access_client_ip.py | 2 +- tests/test_access_tailscale.py | 5 +- tests/test_account.py | 2 +- tests/test_account_service.py | 5 +- tests/test_admin_routes.py | 2 +- tests/test_agent.py | 351 ++-- tests/test_case.py | 6 +- tests/test_cli.py | 4 +- tests/test_common.py | 10 +- tests/test_contracts.py | 525 ++++++ tests/test_data_resource.py | 22 +- tests/test_deploy_commands.py | 11 +- tests/test_deploy_drivers.py | 7 +- tests/test_deploy_local_testing.py | 14 +- tests/test_deploy_phase1.py | 12 +- tests/test_entity_repository.py | 2 +- tests/test_event.py | 6 +- tests/test_full_integration.py | 2 +- tests/test_instructions.py | 2 +- tests/test_job.py | 48 +- tests/test_job_service.py | 2 +- tests/test_lifecycle.py | 2 +- tests/test_parameter.py | 2 +- tests/test_routes.py | 188 +- tests/test_routes_case_update.py | 4 +- tests/test_server.py | 269 ++- tests/test_server_utils.py | 2 +- tests/test_storage.py | 2 +- tests/test_telemetry.py | 2 +- tests/test_validation_endpoints.py | 7 +- tests/test_workbench_routes.py | 3 +- tools/dev_version.py | 8 +- tools/export_openapi.py | 3 +- tools/gen_model_docs.py | 44 +- tools/get_applied_but_branch_id.py | 2 +- tools/persistence_test.py | 2 +- tools/start_server.py | 2 +- tools/start_server_with_reload.py | 2 +- tools/storage_example.py | 2 +- tools/test_admin.py | 2 +- tools/test_startup_loading.py | 2 +- 137 files changed, 6830 insertions(+), 2092 deletions(-) rename docs/{API_REFERENCE.md => 2025_04_API_REFERENCE.md} (98%) rename docs/{ADMIN_README.md => 2025_08_ADMIN_README.md} (99%) rename docs/{CLI.md => 2025_08_CLI.md} (97%) rename docs/{PARAMETER_VALIDATION_IMPLEMENTATION.md => 2025_08_PARAMETER_VALIDATION_IMPLEMENTATION.md} (99%) rename docs/{PERSISTENCE.md => 2025_08_PERSISTENCE.md} (99%) create mode 100644 docs/2025_08_PROTOCOLS.md rename docs/{REST_API.md => 2025_08_REST_API.md} (97%) rename docs/{LOCAL_TESTING.md => 2025_10_LOCAL_TESTING.md} (99%) create mode 100644 docs/2026_05_PROTOCOLS.md create mode 100644 docs/2026_05_SUPERVAIZER_v2.md delete mode 100644 docs/PROTOCOLS.md rename docs/rfc/{001-cloud-deployment-cli.md => 2025_10_001-cloud-deployment-cli.md} (98%) rename docs/rfc/{002-async-http-client.md => 2026_04_002-async-http-client.md} (99%) rename docs/superpowers/plans/{2026-03-16-manage-hello-world.md => 2026_03_2026-03-16-manage-hello-world.md} (99%) rename docs/superpowers/plans/{2026-04-08-dynamic-choices.md => 2026_04_2026-04-08-dynamic-choices.md} (99%) rename docs/superpowers/specs/{2026-03-16-manage-hello-world-design.md => 2026_03_2026-03-16-manage-hello-world-design.md} (98%) create mode 100644 src/supervaizer/protocol/a2a/controller.py create mode 100644 src/supervaizer/protocol/a2a/events.py create mode 100644 tests/fixtures/supervaizer_v2/agent_interviewer_mvp.json diff --git a/AGENTS.md b/AGENTS.md index 5c23e15..ea537c7 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -5,6 +5,7 @@ This is the canonical agent guide for the Supervaizer controller repo. Supervaiz ## Working Rules - Prefer simple, typed Python changes that match existing FastAPI/Pydantic patterns. +- **No guessing / no implicit fallbacks:** when protocol versions, workspace identity, action/resource contracts, authentication, or transport configuration are missing or inconsistent, fail with a clear error that names the missing configuration. Do not infer another context, broaden scope, or silently fall back. - Use `just` recipes from this repo for local commands. - Use `uv` for Python environment and package operations. - Add or update targeted tests for changed behavior. @@ -40,6 +41,8 @@ Reference specific personas when requesting work: - In `9agents/agent_interviewer`, empty `MANAGE_ALLOWED_IPS` still requires `MANAGE_AUTH_TOKEN` when that env is set; supervaizer’s admin IP middleware has no equivalent token fallback when the allowlist is empty. - CI (`python-package` workflow): the pre-commit job checks **Ruff** formatting (`ruff format --check`) and **YAML** in `.github/workflows` via `yamllint` (not Black). - In the matrix **build** job, `astral-sh/setup-uv` sets `cache-suffix: py-${{ matrix.python-version }}` so parallel Python versions do not race on the same GitHub Actions cache reservation. +- `@singleton` (from `supervaizer.common`) replaces the decorated class name with a function at import time; modules that annotate with that class in unions (e.g. `StorageManager | None` in `storage.py`) need `from __future__ import annotations` or class-body evaluation raises `TypeError`. +- `UTC` lives on the `datetime` module (`from datetime import UTC`), not on `datetime.datetime`; use `datetime.now(UTC)`, not `datetime.now(datetime.UTC)` (the latter raises `AttributeError` at runtime). ## Security and Supply-Chain Rules diff --git a/README.md b/README.md index c5a9e2f..a097bf6 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,9 @@ # SUPERVAIZER + +> **Created:** 2024-12-28 +> **Updated:** 2026-05-16 + [Operate AI Agents with confidence] A Python toolkit for building, managing, and connecting AI agents with full [Agent-to-Agent (A2A)](https://a2a-protocol.org/) protocol support. @@ -23,6 +27,7 @@ A Python toolkit for building, managing, and connecting AI agents with full [Age - [What's next?](#whats-next) - [Features](#features) - [Protocol Support](#protocol-support) + - [Supervaizer v2](#supervaizer-v2) - [Cloud Deployment](#cloud-deployment) - [Quick Start](#quick-start-1) - [Deployment Commands](#deployment-commands) @@ -45,6 +50,7 @@ With comprehensive support for the A2A protocol specification, SUPERVAIZER allow - Enhance the capabilities of your agents, making them automatically discoverable by other A2A compatible systems - Expose standardized agent capabilities through agent cards +- Expose typed Supervaizer v2 surfaces and actions so Studio can operate the agent through generic UI primitives - Monitor agent health and status through dedicated endpoints - Connect your agents to the growing ecosystem of A2A-compatible tools @@ -147,6 +153,7 @@ export SUPERVAIZE_MAX_HTTP_RETRIES=3 # Will attempt up to 4 times total (1 orig - Add more **custom methods** (`chat`, `custom`) to extend control - Turn on **A2A** discovery for interoperability +- Add a **Supervaizer v2 registration** when Studio should manage resources, datasets, job start surfaces, HITL steps, and artifact rendering through the generic SDK contract - Hook your controller into Supervaize to **monitor, audit, and operate** the agent For detailed instructions on customizing your controller, see the [Controller Setup Guide](https://doc.supervaize.com/docs/supervaizer-controller/controller-setup) @@ -159,6 +166,7 @@ For detailed instructions on customizing your controller, see the [Controller Se - **Custom Routes**: Agents can mount their own FastAPI routers under `/api/agents/{slug}/...` for tool endpoints, webhooks, or custom APIs - **Scheduled Steps**: Defer step execution to a future time with automatic background polling and workbench controls (execute now, cancel, reschedule) - **Human-in-the-Loop (HITL)**: Form-based and dialog-based interactive content review with chat interface +- **Supervaizer v2 SDK contract**: Typed resources, datasets, A2UI surfaces, actions, job snapshots, case lanes, steps, awaiting state, and artifact references for generic Studio operation - **Agent Workbench**: Built-in testing interface with real-time monitoring, job control, HITL forms, and live console - **🚀 Cloud Deployment**: Automated deployment to GCP Cloud Run, AWS App Runner, and DigitalOcean App Platform - **A2A Protocol Support**: Full integration with the Agent-to-Agent protocol for standardized agent discovery and interaction @@ -167,7 +175,18 @@ For detailed instructions on customizing your controller, see the [Controller Se ## Protocol Support -SUPERVAIZER provides comprehensive support for the A2A agent communication protocol. See [Protocol Documentation](docs/PROTOCOLS.md) for complete details. +SUPERVAIZER provides comprehensive support for the A2A agent communication protocol. See [Protocol Documentation](docs/2025_08_PROTOCOLS.md) for complete details. + +### Supervaizer v2 + +Supervaizer v2 is the Studio operation contract layered on top of A2A discovery/transport and A2UI surface payloads. It lets an agent declare: + +- generic business resources and datasets Studio can list, edit, import, and query +- agent-owned A2UI surfaces such as `job.start`, `case.step.awaiting`, `case.step.detail`, `mission.analytics`, and mounted resource views +- typed actions such as `job.start`, `job.stop`, `job.sync`, `step.awaiting.submit`, `resource..`, and `dataset..query` +- convergent job state snapshots made of Jobs, Cases, Steps, awaiting forms, and artifact references + +Start with [Supervaizer v2 Concepts](docs/2026_05_SUPERVAIZER_v2.md) for the new model and [Protocol Documentation](docs/2025_08_PROTOCOLS.md) for the A2A/A2UI transport layer. ## Cloud Deployment @@ -211,23 +230,23 @@ supervaizer deploy up --platform do-app-platform --region nyc ### Documentation -- [RFC-001: Cloud Deployment CLI](docs/rfc/001-cloud-deployment-cli.md) - Complete specification -- [Local Testing Guide](docs/LOCAL_TESTING.md) - Docker testing documentation +- [RFC-001: Cloud Deployment CLI](docs/rfc/2025_10_001-cloud-deployment-cli.md) - Complete specification +- [Local Testing Guide](docs/2025_10_LOCAL_TESTING.md) - Docker testing documentation ## Using the CLI -SUPERVAIZER includes a command-line interface to simplify setup and operation. See [CLI Documentation](docs/CLI.md) for complete details. +SUPERVAIZER includes a command-line interface to simplify setup and operation. See [CLI Documentation](docs/2025_08_CLI.md) for complete details. -Also, check the list of [Environment variables](CLI.md#environment-variables). +Also, check the list of [Environment variables](docs/2025_08_CLI.md#environment-variables). ## API Documentation & User Interfaces -SUPERVAIZER provides multiple ways to interact with and explore the API. See [REST API Documentation](docs/REST_API.md) for complete details. +SUPERVAIZER provides multiple ways to interact with and explore the API. See [REST API Documentation](docs/2025_08_REST_API.md) for complete details. ### Admin Interface (`/admin`) A comprehensive web-based admin interface for managing your SUPERVAIZER instance -See [Admin documentation](docs/ADMIN_README.md) +See [Admin documentation](docs/2025_08_ADMIN_README.md) #### Quick Start diff --git a/docs/API_REFERENCE.md b/docs/2025_04_API_REFERENCE.md similarity index 98% rename from docs/API_REFERENCE.md rename to docs/2025_04_API_REFERENCE.md index 89e1f01..5138e0f 100644 --- a/docs/API_REFERENCE.md +++ b/docs/2025_04_API_REFERENCE.md @@ -1,5 +1,9 @@ # SUPERVAIZER API Reference + +> **Created:** 2025-04-15 +> **Updated:** 2025-08-05 + This document provides details about the core components and APIs of SUPERVAIZER. ## Core Components diff --git a/docs/ADMIN_README.md b/docs/2025_08_ADMIN_README.md similarity index 99% rename from docs/ADMIN_README.md rename to docs/2025_08_ADMIN_README.md index a77eb71..ecb0885 100644 --- a/docs/ADMIN_README.md +++ b/docs/2025_08_ADMIN_README.md @@ -1,5 +1,9 @@ # Supervaizer Admin Interface + +> **Created:** 2025-08-05 +> **Updated:** 2026-03-23 + A lightweight web-based admin interface for managing WorkflowEntity objects (Jobs and Cases) using FastAPI, TinyDB, and HTMX. ## Features diff --git a/docs/CLI.md b/docs/2025_08_CLI.md similarity index 97% rename from docs/CLI.md rename to docs/2025_08_CLI.md index fdeb95b..287da9b 100644 --- a/docs/CLI.md +++ b/docs/2025_08_CLI.md @@ -1,5 +1,9 @@ # SUPERVAIZER CLI + +> **Created:** 2025-08-06 +> **Updated:** 2026-03-16 + SUPERVAIZER includes a command-line interface to simplify setup, operation, and deployment: ```bash @@ -234,8 +238,8 @@ supervaizer deploy clean --verbose For detailed deployment documentation, see: -- [RFC-001: Cloud Deployment CLI](rfc/001-cloud-deployment-cli.md) - Complete specification -- [Local Testing Guide](LOCAL_TESTING.md) - Docker testing documentation +- [RFC-001: Cloud Deployment CLI](rfc/2025_10_001-cloud-deployment-cli.md) - Complete specification +- [Local Testing Guide](2025_10_LOCAL_TESTING.md) - Docker testing documentation ## Environment Variables diff --git a/docs/PARAMETER_VALIDATION_IMPLEMENTATION.md b/docs/2025_08_PARAMETER_VALIDATION_IMPLEMENTATION.md similarity index 99% rename from docs/PARAMETER_VALIDATION_IMPLEMENTATION.md rename to docs/2025_08_PARAMETER_VALIDATION_IMPLEMENTATION.md index 8052f93..77aad7b 100644 --- a/docs/PARAMETER_VALIDATION_IMPLEMENTATION.md +++ b/docs/2025_08_PARAMETER_VALIDATION_IMPLEMENTATION.md @@ -1,5 +1,9 @@ # Parameter Validation Guide + +> **Created:** 2025-08-12 +> **Updated:** 2025-08-12 + This document provides instructions for implementing parameter validation in the Supervaize web application to leverage the new parameter validation system. ## Overview diff --git a/docs/PERSISTENCE.md b/docs/2025_08_PERSISTENCE.md similarity index 99% rename from docs/PERSISTENCE.md rename to docs/2025_08_PERSISTENCE.md index 9615486..a0cf816 100644 --- a/docs/PERSISTENCE.md +++ b/docs/2025_08_PERSISTENCE.md @@ -1,5 +1,9 @@ # TinyDB Persistence Layer + +> **Created:** 2025-08-05 +> **Updated:** 2026-02-04 + The Supervaizer TinyDB persistence layer provides thread-safe, local storage for WorkflowEntity instances (Jobs, Cases, Missions) across sessions and processes. ## Features diff --git a/docs/2025_08_PROTOCOLS.md b/docs/2025_08_PROTOCOLS.md new file mode 100644 index 0000000..4bb3c79 --- /dev/null +++ b/docs/2025_08_PROTOCOLS.md @@ -0,0 +1,169 @@ +# Protocol Support + +> **Created:** 2025-08-06 +> **Updated:** 2026-05-16 + +SUPERVAIZER uses several protocol layers. They are related, but they do different jobs: + +| Layer | Role in Supervaizer | Current status | +| ------------------ | ------------------------------------------------------------------------------------------------------------------------------------ | -------------------------------------------------------------------------------------------------------- | +| **A2A** | Transport and discovery: Agent Cards, controller URL, JSON-RPC method calls, and event streams. | Implemented for discovery, `supervaizer/action.invoke`, `supervaizer/surface.load`, and SSE observation. | +| **A2UI** | Surface payloads: declarative UI documents for Studio-rendered forms, dashboards, detail views, and mounted resource workflows. | Implemented as the payload format returned by `supervaizer/surface.load`. | +| **AG-UI** | Live agent-user runtime: bidirectional event flow for streaming messages, tool calls, state updates, and interactive agent sessions. | Not part of the MVP runtime; v2 registration only carries optional `ag_ui_version` metadata. | +| **Supervaizer v2** | Application semantics: Jobs, Cases, Steps, Resources, Datasets, Surfaces, Actions, Artifacts, and sync/offline policy. | Implemented as the Studio operation contract layered on A2A and A2UI. | + +The detailed Supervaizer v2 model is documented in [2026_05_SUPERVAIZER_v2.md](2026_05_SUPERVAIZER_v2.md). + +## Agent-to-Agent (A2A) Protocol + +### Overview + +SUPERVAIZER implements the [Agent-to-Agent (A2A) protocol](https://a2a-protocol.org/) for standardized agent discovery and interaction. + +### Implemented A2A Features + +- **Agent Discovery**: `/.well-known/agents.json` endpoint for listing all available agents + Note: the current version of the A2A protocol does not support yet multiple agents. +- **Agent Cards**: Detailed agent information available at `/.well-known/agents/v{version}/{agent_slug}_agent.json` +- **Health Monitoring**: Real-time system and agent health data at `/.well-known/health` +- **Versioned Endpoints**: Support for agent versioning with backward compatibility +- **OpenAPI Integration**: Direct links to OpenAPI specifications and documentation +- **Version Information**: Comprehensive version tracking with changelog access +- **JSON-RPC Controller Endpoint**: `/a2a` supports Supervaizer v2 methods including `supervaizer/action.invoke` and `supervaizer/surface.load` +- **Server-Sent Events**: `/a2a/events` streams Supervaizer v2 action effects for observers that need a live feed + +### Supervaizer v2 Agent Card Extension + +When an agent declares `supervaizer_v2_registration`, its A2A Agent Card includes a `supervaizer.v2` extension. Studio reads this extension to validate protocol compatibility and discover: + +- pinned protocol versions: `supervaizer_contract_version`, `a2a_version`, `a2ui_version`, optional `ag_ui_version`, and agent-specific `a2ui_catalog_version` +- controller URLs and transport support +- supported surfaces and actions +- case lanes and artifact types +- resource and dataset contracts +- job policy, including `job.sync` support and offline behavior + +This extension does **not** replace the existing Studio server-registration trust model. Studio registration still owns server identity, public key exchange, and encrypted payload handling. The A2A Agent Card advertises the v2 operational contract after the controller is known. + +### Supervaizer v2 JSON-RPC Methods + +Supervaizer v2 currently exposes two A2A JSON-RPC methods: + +| Method | Purpose | +| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | +| `supervaizer/surface.load` | Load an agent-owned A2UI document for a known surface such as `job.start`, `case.step.awaiting`, or `mission.analytics`. | +| `supervaizer/action.invoke` | Invoke a typed agent action such as `job.start`, `job.sync`, `step.awaiting.submit`, `resource.contacts.create`, or `dataset.session_metrics.query`. | + +Both methods are scoped by `agent_slug`. In multi-agent controllers, handlers must be registered for the correct agent slug. + +### Transport Status + +The current MVP advertises: + +- `json_rpc: true` +- `sse: true` +- `push_notifications: false` + +A2A push notifications are intentionally not advertised until they are implemented. External A2A interop flags, such as inbound tasks and outbound delegation, default to `false` and should be enabled only when a controller actually implements those flows. + +### A2UI Version Pinning + +Supervaizer v2 registrations include a frozen A2UI protocol version and an agent-owned A2UI catalog version. This is separate from the Python package version: + +- `SUPERVAIZER_V2_CONTRACT_VERSION` identifies the Supervaizer v2 semantic contract. +- `SUPERVAIZER_V2_A2A_VERSION` identifies the supported A2A protocol version. +- `SUPERVAIZER_V2_A2UI_VERSION` identifies the supported A2UI payload version. +- `a2ui_catalog_version` identifies the agent's own surface-document catalog. + +Studio should reject incompatible protocol versions explicitly instead of attempting best-effort rendering. + +## Agent-to-User Interface (A2UI) Protocol + +SUPERVAIZER uses the [A2UI protocol](https://a2ui.org/) for agent-driven interface documents. A2UI is a declarative UI protocol: agents return structured component descriptions, and clients render those descriptions with their own native widgets instead of executing arbitrary agent-provided code. + +Useful source links: + +- [A2UI home](https://a2ui.org/) +- [What is A2UI?](https://a2ui.org/introduction/what-is-a2ui/) +- [A2UI v0.8 specification](https://a2ui.org/specification/v0.8-a2ui/) +- [A2UI v0.9 specification](https://a2ui.org/specification/v0.9-a2ui/) + +In Supervaizer v2, A2UI is used for surface payloads: + +- `job.start` forms +- `case.step.awaiting` HITL forms or review UIs +- `case.step.detail` rich step/artifact detail views +- `mission.analytics` dashboards +- `mission.agent.overview` pages +- mounted resource views such as prompt editors, scenario builders, or contact import flows + +SUPERVAIZER does not render A2UI. The controller transports A2UI documents through `supervaizer/surface.load`; Studio validates the declared `a2ui_version` and renders the document. + +## Agent-User Interaction (AG-UI) Protocol + +AG-UI is the [Agent-User Interaction Protocol](https://docs.ag-ui.com/introduction). It is an event-based protocol for connecting agent backends to user-facing applications when the interaction is live, streaming, and bidirectional. + +Useful source links: + +- [AG-UI documentation](https://docs.ag-ui.com/introduction) +- [AG-UI core architecture](https://docs.ag-ui.com/concepts/architecture) +- [AG-UI agents concept](https://docs.ag-ui.com/concepts/agents) +- [AG-UI GitHub repository](https://github.com/ag-ui-protocol/ag-ui) + +AG-UI is a good fit for: + +- streaming assistant messages and partial outputs +- exposing tool calls and tool results while they happen +- synchronizing live agent state into a frontend +- collaborative chat-style workflows +- interrupt, approval, or live human-in-the-loop interactions + +In the Supervaizer v2 MVP, AG-UI is **not** the runtime used for Studio job management. Studio currently operates agents through A2A JSON-RPC actions, A2UI surface documents, and `job.sync` snapshots. The v2 registration has an optional `ag_ui_version` field so an agent can later advertise a compatible AG-UI runtime without changing the rest of the v2 contract. + +The intended division is: + +| Need | Use | +| ---------------------------------------------------------------- | -------------- | +| Discover an agent and call controller methods | A2A | +| Render a stable Studio form, dashboard, detail view, or workflow | A2UI | +| Run a live streaming agent-user session | AG-UI | +| Persist and reconcile Studio operational state | Supervaizer v2 | + +### A2A Examples + +```bash +# Discovering Agents +curl https://your-server/.well-known/agents.json + +# Agent card +curl https://your-server/.well-known/agents/v1.0.0/myagent_agent.json +``` + +Full documentation of A2A endpoints can be found at [local A2A](http://127.0.0.1:8001/docs#/Protocol%20A2A) + +### Future A2A Enhancements + +- **Webhooks**: Event subscription for real-time updates +- **Rich Authentication**: OAuth2 and API key options with scope control +- **Tool Streaming**: Support for streaming responses in long-running operations +- **Extended Metadata**: Licensing, pricing, and usage limit information +- **Localization**: Multi-language support for agent interfaces +- **A2A Push Notifications**: push delivery for environments that need callback delivery instead of JSON-RPC polling/SSE observation +- **AG-UI Runtime Integration**: optional bidirectional streaming UI runtime for live agent interactions; current v2 registrations only carry `ag_ui_version` metadata + +## Enabling Protocol Support + +A2A endpoints are enabled by default. You can control protocol support when creating your server: + +```python +server = Server( + agents=[agent], + a2a_endpoints=True, # Enable A2A protocol support (default: True) +) +``` + +## Protocol Evolution + +The A2A protocol has evolved to incorporate features from multiple agent communication standards, including the former Agent Communication Protocol (ACP). This unified approach provides a comprehensive standard for agent interoperability across different systems and platforms. + +For the latest protocol specifications and updates, visit [a2a-protocol.org](https://a2a-protocol.org/). diff --git a/docs/REST_API.md b/docs/2025_08_REST_API.md similarity index 97% rename from docs/REST_API.md rename to docs/2025_08_REST_API.md index 881173f..d60be51 100644 --- a/docs/REST_API.md +++ b/docs/2025_08_REST_API.md @@ -1,5 +1,9 @@ # REST API Documentation + +> **Created:** 2025-08-06 +> **Updated:** 2025-08-06 + SUPERVAIZER provides multiple ways to interact with and explore the API: ## Interactive REST API Documentation diff --git a/docs/LOCAL_TESTING.md b/docs/2025_10_LOCAL_TESTING.md similarity index 99% rename from docs/LOCAL_TESTING.md rename to docs/2025_10_LOCAL_TESTING.md index 4b6fdc7..675db16 100644 --- a/docs/LOCAL_TESTING.md +++ b/docs/2025_10_LOCAL_TESTING.md @@ -1,5 +1,9 @@ # Local Docker Testing + +> **Created:** 2025-10-07 +> **Updated:** 2026-01-29 + This document describes how to test Supervaizer deployments locally using Docker before deploying to cloud platforms. ## Overview diff --git a/docs/2026_05_PROTOCOLS.md b/docs/2026_05_PROTOCOLS.md new file mode 100644 index 0000000..be95be9 --- /dev/null +++ b/docs/2026_05_PROTOCOLS.md @@ -0,0 +1,179 @@ +# Protocol Support + +> **Created:** 2025-08-06 +> **Updated:** 2026-05-17 + +SUPERVAIZER uses several protocol layers. They are related, but they do different jobs: + +| Layer | Role in Supervaizer | Current status | +| ------------------ | ------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------- | +| **A2A** | Transport and discovery: | Implemented for discovery, | +| | Agent Cards, controller URL, JSON-RPC method calls, and event streams. | `supervaizer/action.invoke`, `supervaizer/surface.load`, and SSE observation. | +| **A2UI** | Surface payloads: | Implemented as the payload format | +| | declarative UI documents for Studio-rendered forms, dashboards, detail views, and mounted resource workflows. | returned by `supervaizer/surface.load`. | +| **AG-UI** | Live agent-user runtime: | Not part of the MVP runtime; | +| | bidirectional event flow for streaming messages, tool calls, state updates, and interactive agent sessions. | v2 registration only carries optional `ag_ui_version` metadata. | +| **Supervaizer v2** | Application semantics: | Implemented as the Studio operation contract | +| | Jobs, Cases, Steps, Resources, Datasets, Surfaces, Actions, Artifacts, and sync/offline policy. | layered on A2A and A2UI. | + +The detailed Supervaizer v2 model is documented in [2026_05_SUPERVAIZER_v2.md](2026_05_SUPERVAIZER_v2.md). + +## Agent-to-Agent (A2A) Protocol + +### Overview + +SUPERVAIZER implements the [Agent-to-Agent (A2A) protocol](https://a2a-protocol.org/) for standardized agent discovery and interaction. + +### Implemented A2A Features + +- **Agent Discovery**: `/.well-known/agents.json` endpoint for listing all available agents + Note: the current version of the A2A protocol does not support yet multiple agents. +- **Agent Cards**: Detailed agent information available at `/.well-known/agents/v{version}/{agent_slug}_agent.json` +- **Health Monitoring**: Real-time system and agent health data at `/.well-known/health` +- **Versioned Endpoints**: Support for agent versioning with backward compatibility +- **OpenAPI Integration**: Direct links to OpenAPI specifications and documentation +- **Version Information**: Comprehensive version tracking with changelog access +- **JSON-RPC Controller Endpoint**: `POST /a2a` supports Supervaizer v2 methods including `supervaizer/action.invoke` and `supervaizer/surface.load`; requests require `X-API-Key` with write scope +- **Server-Sent Events**: `GET /a2a/events` streams Supervaizer v2 action effects for observers that need a live feed; requests require `X-API-Key` with read scope + +### Supervaizer v2 Agent Card Extension + +When an agent declares `supervaizer_v2_registration`, its A2A Agent Card includes a `supervaizer.v2` extension. Studio reads this extension to validate protocol compatibility and discover: + +- pinned protocol versions: `supervaizer_contract_version`, `a2a_version`, `a2ui_version`, optional `ag_ui_version`, and agent-specific `a2ui_catalog_version` +- controller URLs and transport support +- supported surfaces and actions +- case lanes and artifact types +- resource, dataset, and dashboard contracts +- job policy, including `job.sync` support and offline behavior + +This extension does **not** replace the existing Studio server-registration trust model. Studio registration still owns server identity, public key exchange, and encrypted payload handling. The A2A Agent Card advertises the v2 operational contract after the controller is known. + +### Supervaizer v2 JSON-RPC Methods + +Supervaizer v2 currently exposes two A2A JSON-RPC methods: + +| Method | Purpose | +| --------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- | +| `supervaizer/surface.load` | Load an agent-owned A2UI document for a known surface such as `job.start`, `case.step.awaiting`, or `mission.analytics`. | +| `supervaizer/action.invoke` | Invoke a typed agent action such as `job.start`, `job.sync`, `step.awaiting.submit`, `resource.contacts.create`, or `dataset.session_metrics.query`. | + +Both methods are scoped by `agent_slug`. In multi-agent controllers, handlers must be registered for the correct agent slug. + +### Transport Status + +The current MVP advertises: + +- `json_rpc: true` +- `sse: true` +- `push_notifications: false` + +A2A push notifications are intentionally not advertised until they are implemented. External A2A interop flags, such as inbound tasks and outbound delegation, default to `false` and should be enabled only when a controller actually implements those flows. + +### A2UI Version Pinning + +Supervaizer v2 registrations include a frozen A2UI protocol version and an agent-owned A2UI catalog version. This is separate from the Python package version: + +- `SUPERVAIZER_V2_CONTRACT_VERSION` identifies the Supervaizer v2 semantic contract. +- `SUPERVAIZER_V2_A2A_VERSION` identifies the supported A2A protocol version. +- `SUPERVAIZER_V2_A2UI_VERSION` identifies the supported A2UI payload version. +- `a2ui_catalog_version` identifies the agent's own surface-document catalog. + +Studio should reject incompatible protocol versions explicitly instead of attempting best-effort rendering. + +## Agent-to-User Interface (A2UI) Protocol + +SUPERVAIZER uses the [A2UI protocol](https://a2ui.org/) for agent-driven interface documents. A2UI is a declarative UI protocol: agents return structured component descriptions, and clients render those descriptions with their own native widgets instead of executing arbitrary agent-provided code. + +Useful source links: + +- [A2UI home](https://a2ui.org/) +- [What is A2UI?](https://a2ui.org/introduction/what-is-a2ui/) +- [A2UI v0.8 specification](https://a2ui.org/specification/v0.8-a2ui/) +- [A2UI v0.9 specification](https://a2ui.org/specification/v0.9-a2ui/) + +In Supervaizer v2, A2UI is used for surface payloads: + +- `job.start` forms +- `case.step.awaiting` HITL forms or review UIs +- `case.step.detail` rich step/artifact detail views +- `mission.analytics` dashboards +- `mission.agent.overview` pages +- mounted resource views such as prompt editors, scenario builders, or contact import flows + +Mounted HITL surfaces can return specialized A2UI document types, such as `DocumentReview`, through the generic `V2SurfaceResult.document` payload. Supervaizer keeps this opaque and typed only as an A2UI document transport; the agent declares the surface/action and Studio renders the document. + +Mounted resource import views can return `ResourceImport`. This document declares contextual fields, accepted file formats, row columns, and the submit action. Studio uses it to communicate and enforce the import structure, while the agent still owns validation and persistence. + +Dashboard declarations live in the Supervaizer v2 registration contract. Widgets can point at datasets, typed actions, or inline data, and can declare `visualization: { type: "vega-lite", spec: ... }` using the [Vega-Lite](https://vega.github.io/vega-lite/) JSON grammar. This ports the useful chart declaration idea into the generic contract without reviving AnalyticsResource REST routes. + +SUPERVAIZER does not render A2UI. The controller transports A2UI documents through `supervaizer/surface.load`; Studio validates the declared `a2ui_version` and renders the document. + +## Agent-User Interaction (AG-UI) Protocol + +AG-UI is the [Agent-User Interaction Protocol](https://docs.ag-ui.com/introduction). It is an event-based protocol for connecting agent backends to user-facing applications when the interaction is live, streaming, and bidirectional. + +Useful source links: + +- [AG-UI documentation](https://docs.ag-ui.com/introduction) +- [AG-UI core architecture](https://docs.ag-ui.com/concepts/architecture) +- [AG-UI agents concept](https://docs.ag-ui.com/concepts/agents) +- [AG-UI GitHub repository](https://github.com/ag-ui-protocol/ag-ui) + +AG-UI is a good fit for: + +- streaming assistant messages and partial outputs +- exposing tool calls and tool results while they happen +- synchronizing live agent state into a frontend +- collaborative chat-style workflows +- interrupt, approval, or live human-in-the-loop interactions + +In the Supervaizer v2 MVP, AG-UI is **not** the runtime used for Studio job management. Studio currently operates agents through A2A JSON-RPC actions, A2UI surface documents, and `job.sync` snapshots. The v2 registration has an optional `ag_ui_version` field so an agent can later advertise a compatible AG-UI runtime without changing the rest of the v2 contract. + +The intended division is: + +| Need | Use | +| ---------------------------------------------------------------- | -------------- | +| Discover an agent and call controller methods | A2A | +| Render a stable Studio form, dashboard, detail view, or workflow | A2UI | +| Run a live streaming agent-user session | AG-UI | +| Persist and reconcile Studio operational state | Supervaizer v2 | + +### A2A Examples + +```bash +# Discovering Agents +curl https://your-server/.well-known/agents.json + +# Agent card +curl https://your-server/.well-known/agents/v1.0.0/myagent_agent.json +``` + +Full documentation of A2A endpoints can be found at [local A2A](http://127.0.0.1:8001/docs#/Protocol%20A2A) + +### Future A2A Enhancements + +- **Webhooks**: Event subscription for real-time updates +- **Rich Authentication**: OAuth2 and API key options with scope control +- **Tool Streaming**: Support for streaming responses in long-running operations +- **Extended Metadata**: Licensing, pricing, and usage limit information +- **Localization**: Multi-language support for agent interfaces +- **A2A Push Notifications**: push delivery for environments that need callback delivery instead of JSON-RPC polling/SSE observation +- **AG-UI Runtime Integration**: optional bidirectional streaming UI runtime for live agent interactions; current v2 registrations only carry `ag_ui_version` metadata + +## Enabling Protocol Support + +A2A endpoints are enabled by default. You can control protocol support when creating your server: + +```python +server = Server( + agents=[agent], + a2a_endpoints=True, # Enable A2A protocol support (default: True) +) +``` + +## Protocol Evolution + +The A2A protocol has evolved to incorporate features from multiple agent communication standards, including the former Agent Communication Protocol (ACP). This unified approach provides a comprehensive standard for agent interoperability across different systems and platforms. + +For the latest protocol specifications and updates, visit [a2a-protocol.org](https://a2a-protocol.org/). diff --git a/docs/2026_05_SUPERVAIZER_v2.md b/docs/2026_05_SUPERVAIZER_v2.md new file mode 100644 index 0000000..0f240a6 --- /dev/null +++ b/docs/2026_05_SUPERVAIZER_v2.md @@ -0,0 +1,415 @@ +# Supervaizer v2 + + +> **Created:** 2026-05-16 +> **Updated:** 2026-05-17 + +Supervaizer v2 is the new operation contract between an agent controller and Supervaize Studio. + +The goal is simple: Studio should be able to operate many different agents through one generic UI, while each agent keeps ownership of its own business vocabulary and business logic. + +## Layering + +Supervaizer v2 is layered, not monolithic: + +| Layer | Owned by | Role | +| --- | --- | --- | +| A2A | protocol/runtime | discovery, Agent Card, JSON-RPC controller endpoint, SSE events | +| A2UI | protocol/surface payload | UI document shape for forms, dashboards, tables, details, and custom surfaces | +| Supervaizer v2 | Supervaizer SDK + agent | Jobs, Cases, Steps, Resources, Datasets, Artifacts, Surfaces, Actions, and sync semantics | +| Studio | Supervaize Studio | authentication, permissions, rendering, persistence, polling, offline policy, and operator workflow | +| Agent | agent author | business objects, action handlers, validation, resource mutations, artifact content, and state snapshots | + +The key rule is: **the universal protocol owns the shape; the agent owns the vocabulary.** + +For example, Supervaizer v2 defines that a Case has a `lane`, but the agent decides which lanes exist. Studio knows how to render `setup`, `work`, and `deliverable`, but custom lanes can also be declared and rendered generically. + +## Versioning + +Supervaizer v2 protocol versions are independent from the Python package version. + +| Constant | Meaning | +| --- | --- | +| `SUPERVAIZER_V2_CONTRACT_VERSION` | The semantic contract version for Supervaizer v2. | +| `SUPERVAIZER_V2_A2A_VERSION` | The A2A protocol version the controller advertises. | +| `SUPERVAIZER_V2_A2UI_VERSION` | The A2UI document version the controller emits. | + +Every registration also declares `a2ui_catalog_version`, which is the agent-owned version for its own surface documents. Studio can use this to detect when an agent changed its UI catalog even if the shared A2UI version did not change. + +Because A2UI is pre-1.0, agents should pin the supported A2UI version in registration. Studio should reject incompatible versions explicitly instead of guessing. + +## Registration + +An agent declares v2 support through `supervaizer_v2_registration` on the `Agent`. + +The recommended path is `build_v2_agent_registration()`: + +```python +from supervaizer import Agent +from supervaizer.contracts import ( + V2ResourceDefinition, + build_v2_agent_registration, +) + +registration = build_v2_agent_registration( + agent_id="research-agent", + agent_slug="research-agent", + display_name="Research Agent", + agent_card_url="/.well-known/agents/v1.0.0/research-agent_agent.json", + controller_url="/a2a", + a2ui_catalog_version="research-agent.2026-05-16", + surfaces=[ + "job.start", + "case.step.awaiting", + "case.step.detail", + "mission.analytics", + ], + actions=[ + "job.start", + "job.stop", + "step.awaiting.submit", + ], + case_lanes=[ + {"id": "setup", "label": "Setup"}, + {"id": "work", "label": "Work", "default": True}, + {"id": "deliverable", "label": "Deliverables"}, + ], + artifact_types=[ + {"type": "transcript", "label": "Transcript"}, + {"type": "synthesis", "label": "Synthesis"}, + ], + job_policy={"sync": {"action": "job.sync"}}, + resources=[ + V2ResourceDefinition( + id="contacts", + label="Contacts", + auto_surface=True, + operations=["list", "create", "update", "import"], + ) + ], +) + +agent = Agent( + name="Research Agent", + version="1.0.0", + supervaizer_v2_registration=registration, + # v1 fields may still exist during transition in older agents, + # but new v2 agents should model Studio operation through v2. +) +``` + +The v2 registration is exposed in the A2A Agent Card under `supervaizer.v2`. + +This does not replace the existing Studio server registration process. Server identity, public key exchange, and encrypted payload handling still belong to the normal Studio registration path. The v2 extension tells Studio how to operate the already-registered controller. + +## Runtime Handlers + +Agents register action and surface handlers on the `Server`. + +```python +from supervaizer import Server +from supervaizer.contracts import V2ActionRequest, V2ActionResult, V2SurfaceRequest + +server = Server(agents=[agent]) + + +@server.v2_surface("job.start", agent_slug="research-agent") +def load_job_start(request: V2SurfaceRequest) -> dict: + return { + "surface": request.surface, + "document": { + "type": "Form", + "fields": [ + {"id": "topic_id", "label": "Topic", "type": "string"}, + ], + "submit": {"label": "Start research", "action": "job.start"}, + }, + } + + +@server.v2_action("job.start", agent_slug="research-agent") +def start_job(request: V2ActionRequest) -> V2ActionResult: + topic_id = request.input["topic_id"] + return V2ActionResult( + status="ok", + effects=[{"type": "job.started", "data": {"topic_id": topic_id}}], + ) +``` + +Surface handlers return A2UI documents. Action handlers perform business logic and return typed effects, optionally with a full `job_state` snapshot for sync convergence. + +## Core Model + +### Job + +A Job is committed work Studio tracks for an agent. + +Studio may load `job.start` before a Job exists. In that case the request can include `draft_session_id`. Agents should treat this as transient UI context. Persistent business state should be created on `job.start`, not on surface load. + +Status convergence happens through `job.sync`. `job.sync` does not need to be strictly idempotent in the sense of byte-for-byte identical responses. It should be **convergent**: repeated calls for the same external state should lead Studio to the same Job/Case/Step projection. + +### Case + +A Case is a unit of work inside a Job. Cases declare a `lane`, which is a rendering hint. + +The default lane is `work`. Agents can declare standard or custom lanes: + +- `setup`: preparation and pre-flight review +- `work`: primary execution +- `deliverable`: final outputs and reviews +- custom lanes such as `extract`, `transform`, `load`, `verify` + +Studio renders unknown lanes generically. + +### Step + +A Step is an observable activity inside a Case. + +In the current SDK model: + +- `activity` is `operation` or `delegation` +- `status` carries lifecycle state such as pending, active, awaiting, completed, failed, or cancelled +- `awaiting` carries HITL state when Studio must collect operator input +- `outputs` carries produced artifacts + +HITL is therefore not a Step kind. It is represented by `status="awaiting"` plus an `awaiting` object with a surface, action, and fields. + +The awaiting `surface` can return any valid A2UI document through `V2SurfaceResult.document`. For mounted review workflows, agents can return a generic `DocumentReview` document that contains document content, submit metadata, and typed fields. Supervaizer does not interpret document-review semantics; Studio renders the A2UI document and invokes the declared action, usually `step.awaiting.submit`. + +Example: + +```python +V2SurfaceResult( + surface="case.step.awaiting", + a2ui_version="v0.8", + document={ + "type": "DocumentReview", + "document": { + "title": "Review", + "field": "review_text", + "language": "markdown", + "value": "# Draft\n\nReview this content.", + "validation": [ + {"id": "readiness", "label": "Ready for approval", "status": "review"} + ], + }, + "submit": {"action": "step.awaiting.submit", "label": "Approve"}, + "fields": [ + { + "id": "review_text", + "label": "Review text", + "type": "text", + "multiline": True, + "required": True, + }, + { + "id": "approve_review", + "label": "Approve review", + "type": "boolean", + "required": True, + } + ], + }, +) +``` + +### Artifact + +Artifacts are agent-owned outputs. The protocol only defines the reference shape: + +- `id` +- `type` +- `title` +- optional external id and media type + +Artifact types such as `transcript`, `synthesis`, `report`, `metric`, or `decision` belong to the agent registration. Studio can render known artifact types richly and fall back to generic previews for unknown types. + +## Resources + +Resources are agent-owned business objects Studio can manage generically. + +Examples: + +- projects +- contacts +- prompts +- scenarios +- project_contacts + +A resource declaration can include: + +- operations such as `list`, `get`, `create`, `update`, `delete`, `import` +- display metadata for title, columns, and search fields +- simple form fields +- typed resource-backed option sources +- mounted custom views for cases where generic CRUD is not enough + +Dynamic behavior should not be implemented as opaque Python callbacks. It should reduce to: + +- A2UI-local declarative behavior inside the surface document, or +- typed action calls such as `resource.contacts.list`, `resource.contacts.create`, or an agent-specific validation action. + +This avoids repeating the v1 dynamic-choice callback model. + +## Datasets + +Datasets are read-oriented tables or metric streams that Studio can query through typed actions. + +An auto-surfaced dataset declares: + +- `id` +- `label` +- display columns +- `auto_surface=True` + +The SDK derives the action id `dataset..query`. Studio can render the result in generic tables and dashboards, including `mission.analytics` surfaces. + +## Dashboards + +Dashboards are declarative registration metadata for Studio-rendered views. They do not create AnalyticsResource routes and they do not imply agent-specific analytics business logic. + +A dashboard declares: + +- `id` +- `label` +- `surface`, defaulting to `mission.analytics` +- `widgets` + +Each widget can reference data from a dataset, typed action, or inline sample data. Widgets carry a `visualization` object whose `type` is `table`, `metric`, `vega-lite`, or `custom`. For Vega-Lite charts, use `visualization.type = "vega-lite"` and place the Vega-Lite JSON spec in `visualization.spec`. Studio is responsible for rendering and validating the visualization; Supervaizer only transports the typed contract. + +Example: + +```python +registration = build_v2_agent_registration( + # ... + datasets=[ + { + "id": "progress_metrics", + "label": "Progress Metrics", + "auto_surface": True, + "display": {"columns": ["label", "value"]}, + } + ], + dashboards=[ + { + "id": "mission_overview", + "label": "Mission Overview", + "widgets": [ + { + "id": "progress_chart", + "title": "Progress", + "data": {"mode": "ref", "datasetId": "progress_metrics"}, + "visualization": { + "type": "vega-lite", + "spec": { + "$schema": "https://vega.github.io/schema/vega-lite/v5.json", + "mark": "bar", + "encoding": { + "x": {"field": "label", "type": "nominal"}, + "y": {"field": "value", "type": "quantitative"}, + }, + }, + }, + } + ], + } + ], +) +``` + +## Surfaces + +Surfaces are named UI entry points. A surface handler returns an A2UI document. + +Common surface IDs: + +| Surface | Purpose | +| --- | --- | +| `job.start` | Form used before `job.start`. | +| `case.step.awaiting` | HITL form or review UI for an awaiting step. | +| `case.step.detail` | Rich detail view for a step or artifact. | +| `mission.analytics` | Mission-scoped dashboard over agent datasets. | +| `mission.agent.overview` | Optional agent overview and quick links. | +| `mission.agent.resource.` | Studio-generated resource CRUD surface. | +| `mission.agent.dataset.` | Studio-generated dataset surface. | + +Mounted resource views use a resource-shaped URL in Studio but let the agent replace a whole view, such as `edit` or `import`, with a custom A2UI surface. + +For imports, agents should use the `ResourceImport` A2UI document shape. The document declares: + +- `resource`, such as `campaign_contacts` +- `accepted_formats`, currently `csv` and optionally `xlsx` +- contextual `fields`, such as a required campaign picker +- row `columns`, such as `email` and `phone_number` +- `submit.action`, such as `resource.campaign_contacts.import` + +Studio reads this document to show the required format, validate CSV rows before submit, and route the typed action. The agent remains responsible for tenant checks, business validation, persistence, and returning typed effects. If an import changes an existing Job, the action can return a top-level `job_state`; Studio treats that like `job.sync` and upserts the returned cases and steps. + +## Actions + +Actions are typed commands invoked through A2A JSON-RPC. + +Common action IDs: + +| Action | Purpose | +| --- | --- | +| `job.start` | Commit a new Job and start agent work. | +| `job.stop` | Stop or cancel agent work. | +| `job.sync` | Return a convergent state snapshot for Studio. | +| `step.awaiting.submit` | Submit operator input for a HITL step. | +| `resource..` | Run a resource operation. | +| `dataset..query` | Query an agent-owned dataset. | +| `artifact.get` | Load artifact content by reference. | + +Action requests include `actor`, `workspace`, `mission_id`, `agent_slug`, `surface`, `action`, `input`, and optional correlation fields such as `job_id`, `case_id`, `step_id`, `draft_session_id`, and `idempotency_key`. + +## Sync and Offline Semantics + +Studio owns operator-facing job lifecycle, but the agent owns actual business state. `job.sync` is the reconciliation point between the two. + +Recommended behavior: + +- new starts go through `job.start` +- already-started external work can be loaded by creating a Studio Job and calling `job.sync` +- repeated sync calls should be convergent +- offline agents block new starts +- if Studio marks a running Job failed because the agent is offline, resuming later should use a new Job plus `job.sync` + +## A2A, A2UI, and AG-UI + +Supervaizer v2 currently uses: + +- A2A for Agent Card discovery, `/a2a` JSON-RPC calls, and `/a2a/events` SSE observation +- A2UI for Studio-rendered surface documents such as `job.start`, `case.step.awaiting`, `case.step.detail`, and `mission.analytics` +- Supervaizer v2 semantics for Jobs, Cases, Steps, Resources, Datasets, Actions, Artifacts, and sync/offline policy + +The current transport advertises JSON-RPC and SSE, not A2A push notifications. + +AG-UI is not required for the MVP. It is the right layer for future live streaming agent-user sessions where Studio needs bidirectional events, streaming messages, tool-call visualization, live state synchronization, or interrupt/approval flows. Registrations can include `ag_ui_version` metadata for that future runtime, but the implemented v2 flow works through A2UI surface documents and typed actions. + +## Migration From v1 + +The v2 model intentionally replaces v1 field/dynamic-choice/job-poll behavior. + +| v1 concept | v2 replacement | +| --- | --- | +| `AgentMethodField` for Studio job start | A2UI `job.start` surface | +| `dynamic_choices_callback` | typed resource option sources or typed actions | +| `job_poll` | `job.sync` | +| controller-specific HITL payloads | `case.step.awaiting` surface plus `step.awaiting.submit` | +| fixed Studio assumptions about agent outputs | agent-declared artifact types and `case.step.detail` surfaces | + +New agents should model Studio integration through v2 from the start. + +## Minimal Checklist For A v2 Agent + +- Declare `supervaizer_v2_registration`. +- Pin `a2ui_version`, `a2a_version`, and `a2ui_catalog_version`. +- Declare at least one surface, usually `job.start`. +- Register `job.start`. +- Register `job.sync` if Studio needs status convergence or catch-up. +- Declare resources and datasets that Studio should manage generically. +- Register handlers for every declared action. +- Use `awaiting` state for HITL. +- Return stable external ids in Job/Case/Step/Artifact snapshots. +- Keep business validation inside agent actions, not inside Studio-specific code paths. diff --git a/docs/CHANGELOG.md b/docs/CHANGELOG.md index deb0c37..bdf1069 100644 --- a/docs/CHANGELOG.md +++ b/docs/CHANGELOG.md @@ -1,13 +1,16 @@ # Supervaizer Changelog +> **Created:** 2025-08-05 +> **Updated:** 2026-05-16 + All notable changes to this project will be documented in this file. > The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). ## TODO -- Review and test feature/data-persistance -- Complete feature/smartinstall implementation +- Review and test feature/data-persistence +- Complete feature/smart-install implementation - Fix receive_human_input - When AgentMethodField returns its value (in the kwargs of job_start), the value should be casted in the appropriate type : - example: here the 'How many times to say hello' is supposed to be an 'int'. @@ -15,6 +18,47 @@ All notable changes to this project will be documented in this file. ## [Unreleased] +### Supervaizer v2 2️⃣ + +- **Supervaizer v2 documentation** — Added `docs/2026_05_SUPERVAIZER_v2.md` and updated the README/protocol docs to explain the v2 A2A/A2UI layering, registration model, resources, datasets, surfaces, actions, HITL, artifacts, and `job.sync` convergence semantics. +- **Supervaizer v2 contract primitives** — Added typed SDK models for the v2 registration and action contract, including pinned A2UI/A2A versions, resources, datasets, case lanes, artifact declarations, job snapshots, sync metadata, and replay-safety metadata. +- **A2A JSON-RPC action runtime** — Added the `/a2a` `supervaizer/action.invoke` dispatcher, v2 Agent Card extension payloads, and public SDK helpers for registering typed v2 actions through `Server.register_v2_action()` and `@server.v2_action(...)`. +- **A2A SSE event stream** — Added `/a2a/events` and an in-process v2 event bus so action effects returned through `supervaizer/action.invoke` can also be observed over Server-Sent Events. +- **Supervaizer v2 transport honesty** — `V2A2ATransport.push_notifications` now defaults to `false`; the MVP advertises JSON-RPC and SSE support only until A2A push notifications are implemented. +- **A2A JSON-RPC surface runtime** — Added `supervaizer/surface.load`, typed `V2SurfaceRequest`/`V2SurfaceResult` models, and public SDK helpers for registering A2UI surface handlers through `Server.register_v2_surface()` and `@server.v2_surface(...)`. +- **Supervaizer v2 agent identity guard** — `Agent` now rejects v2 registration payloads whose declared `agent.slug` differs from the runtime SDK slug, preventing A2A action handlers from registering under one slug while Studio invokes another. +- **Supervaizer v2 job sync state** — `V2JobSyncResult` now carries an optional `job_state` snapshot so agents can return convergent Job/Case/Step/Artifact state through `job.sync`. +- **Supervaizer v2 job source target metadata** — `V2JobSource` now includes an optional `target_type` so external sources can declare the business object Studio should use for dedupe and catch-up. +- **Supervaizer v2 resource form fields** — `V2ResourceDefinition` now carries typed `fields` metadata so Studio can render simple agent-owned resource create/edit forms without callback-style dynamic field logic. +- **Supervaizer v2 ResourceImport documents** — Added a typed A2UI `ResourceImport` document contract so agents can declare import formats, contextual fields, row columns, and submit actions without adding agent-specific protocol fields. +- **Supervaizer v2 resource option sources** — Resource fields can now declare typed resource-backed `options_source` metadata so Studio can render relationship selectors without callback-style dynamic choices. +- **Supervaizer v2 workspace-scoped resources** — Resource declarations now advertise `scope` and `requires_context` metadata, and legacy DataResource registration info carries the same workspace context requirement for Studio-side access control. +- **Supervaizer v2 dataset display metadata** — `V2DatasetDefinition` now carries typed display columns so Studio can render generic dataset surfaces from the registration contract. +- **Supervaizer v2 dashboard widgets** — Added generic dashboard and widget registration contracts, including dataset/action/inline data refs and Vega-Lite widget specs under `visualization: { type: "vega-lite", spec: ... }` without AnalyticsResource REST routes. +- **Supervaizer v2 mounted HITL review docs** — Documented `DocumentReview` as a generic A2UI document payload for mounted awaiting-step surfaces without adding agent-specific protocol fields. +- **Supervaizer v2 registration builder** — Added `build_v2_agent_registration()` to derive validated v2 registration payloads from public SDK primitives, including generated resource/dataset surfaces and actions. +- **Supervaizer v2 public SDK ergonomics** — Exported the remaining v2 registration helper models from `supervaizer` and neutralized agent-specific examples in v2 public documentation and contract descriptions. +- **Legacy dynamic choices removed** — Removed the v1 `dynamic_choices` field metadata, `dynamic_choices_callback`, `/start/dynamic_choices` route, and related contract exports; dynamic options now belong to v2 resource `options_source` metadata or typed A2A actions. +- **Legacy job poll removed** — Removed `job_poll` from the public v1 method contract and the local workbench poll route/button; v2 status convergence is represented by the typed `job.sync` action. +- **Supervaizer v2 awaiting form fields** — Step awaiting state can now declare typed form fields so Studio can submit HITL actions through `step.awaiting.submit`. +- **Local Hello World v2 contract** — The built-in local Hello World agent now declares a minimal Supervaizer v2 registration through the SDK builder and registers `job.start`, `job.sync`, `case.step.awaiting`, and a generated resource handler for local Studio and SDK smoke tests. +- **Controller correctness fixes** — Scoped `Jobs.get_job(..., agent_name=...)` to the requested agent, gave `EventType.AGENT_SEND_ANOMALY` a distinct value, and fixed custom method routes to parse normal JSON request bodies. +- **Supervaizer v2 runtime hardening** — Added typed common fields to v2 action effects, including resource import counts, rows, errors, gaps, summaries, and case snapshots; validated `job_state` on action results; authenticated the A2A JSON-RPC controller and SSE event stream while keeping A2A discovery/health public; sanitized A2A handler errors; and constrained legacy method execution to declared non-blocked method paths. +- **Supervaizer v2 replay and context contracts** — Action results now validate and serialize replay-safety metadata, and DataResource context header generation includes the agent slug advertised by the contract model. + +### Tests + +- `uv run pytest tests/test_a2a.py tests/test_contracts.py -q` + +`just test` + +| Status | Count | +| ---------- | ----- | +| ✅ Passed | 601 | +| 🤔 Skipped | 0 | +| 🔴 Failed | 0 | +| ⏱️ in | 69s | + ## [0.20.1] - 2026-05-13 ### Security @@ -558,7 +602,7 @@ All notable changes to this project will be documented in this file. - Set `SUPERVAIZER_PERSISTENCE=true` (or `1`/`yes`) to enable file persistence. - CLI: `supervaizer start --persist` enables persistence for that run. - Explicit `StorageManager(db_path=...)` in code still uses file storage (e.g. tests). - - See [PERSISTENCE.md](PERSISTENCE.md) for configuration. + - See [2025_08_PERSISTENCE.md](2025_08_PERSISTENCE.md) for configuration. ### Unit Tests Results @@ -588,7 +632,7 @@ All notable changes to this project will be documented in this file. ### Added - **🚀 Cloud Deployment CLI** - Complete automated deployment system for Supervaizer agents - - Full implementation of [RFC-001: Cloud Deployment CLI](docs/rfc/001-cloud-deployment-cli.md) + - Full implementation of [RFC-001: Cloud Deployment CLI](rfc/2025_10_001-cloud-deployment-cli.md) - Support for three major cloud platforms: - **Google Cloud Run** with Artifact Registry and Secret Manager - **AWS App Runner** with ECR and Secrets Manager @@ -605,7 +649,7 @@ All notable changes to this project will be documented in this file. - **Health Verification**: Automatic health checks at `/.well-known/health` endpoint - **Idempotent Deployments**: Safe create/update operations with rollback on failure - **Local Testing**: Full Docker Compose environment for pre-deployment testing - - See [Local Testing Documentation](docs/LOCAL_TESTING.md) for details + - See [Local Testing Documentation](2025_10_LOCAL_TESTING.md) for details - **Agent Instructions Template** - New HTML page served by FastAPI for Supervaize integration instructions - Accessible at `/admin/supervaize-instructions` @@ -644,7 +688,7 @@ All notable changes to this project will be documented in this file. - Added comprehensive deployment documentation - Updated model reference documentation - Improved README with deployment examples - - Updated PROTOCOLS.md to focus on unified A2A protocol + - Updated 2025_08_PROTOCOLS.md to focus on unified A2A protocol - Added Protocol Evolution section explaining ACP merger ### Fixed @@ -709,7 +753,7 @@ All notable changes to this project will be documented in this file. ## [0.9.6] - Public release to Pypi -- Fixed the gihut workflows +- Fixed the github workflows - Improve README.md ## [0.9.5] @@ -759,7 +803,7 @@ All notable changes to this project will be documented in this file. ### Changed -- Paramater.to_dict : override to avoid storing secrets. +- Parameter.to_dict : override to avoid storing secrets. - Removed Case Nodes - Improved test coverage : accounts, admin/routes, diff --git a/docs/PROTOCOLS.md b/docs/PROTOCOLS.md deleted file mode 100644 index 66030cb..0000000 --- a/docs/PROTOCOLS.md +++ /dev/null @@ -1,56 +0,0 @@ -# Protocol Support - -SUPERVAIZER provides comprehensive support for the Agent-to-Agent (A2A) protocol, enabling seamless interoperability between different AI agent systems. - -## Agent-to-Agent (A2A) Protocol - -### Overview - -SUPERVAIZER implements the [Agent-to-Agent (A2A) protocol](https://a2a-protocol.org/) for standardized agent discovery and interaction. - -### Implemented A2A Features - -- **Agent Discovery**: `/.well-known/agents.json` endpoint for listing all available agents - Note: the current version of the A2A protocol does not support yet multiple agents. -- **Agent Cards**: Detailed agent information available at `/.well-known/agents/v{version}/{agent_slug}_agent.json` -- **Health Monitoring**: Real-time system and agent health data at `/.well-known/health` -- **Versioned Endpoints**: Support for agent versioning with backward compatibility -- **OpenAPI Integration**: Direct links to OpenAPI specifications and documentation -- **Version Information**: Comprehensive version tracking with changelog access - -### A2A Examples - -```bash -# Discovering Agents -curl https://your-server/.well-known/agents.json - -# Agent card -curl https://your-server/.well-known/agents/v1.0.0/myagent_agent.json -``` - -Full documentation of A2A endpoints can be found at [local A2A](http://127.0.0.1:8001/docs#/Protocol%20A2A) - -### Future A2A Enhancements - -- **Webhooks**: Event subscription for real-time updates -- **Rich Authentication**: OAuth2 and API key options with scope control -- **Tool Streaming**: Support for streaming responses in long-running operations -- **Extended Metadata**: Licensing, pricing, and usage limit information -- **Localization**: Multi-language support for agent interfaces - -## Enabling Protocol Support - -A2A endpoints are enabled by default. You can control protocol support when creating your server: - -```python -server = Server( - agents=[agent], - a2a_endpoints=True, # Enable A2A protocol support (default: True) -) -``` - -## Protocol Evolution - -The A2A protocol has evolved to incorporate features from multiple agent communication standards, including the former Agent Communication Protocol (ACP). This unified approach provides a comprehensive standard for agent interoperability across different systems and platforms. - -For the latest protocol specifications and updates, visit [a2a-protocol.org](https://a2a-protocol.org/). diff --git a/docs/api/openapi.json b/docs/api/openapi.json index c09260f..fc272bb 100644 --- a/docs/api/openapi.json +++ b/docs/api/openapi.json @@ -2,7 +2,7 @@ "openapi": "3.1.0", "info": { "title": "Supervaize API", - "description": "API version: v1 Controller version: 0.13.0\n\nAPI for controlling and managing Supervaize agents. \n\nMore information at [https://doc.supervaize.com](https://doc.supervaize.com)\n\n## Authentication\n\nSome endpoints require API key authentication. Protected endpoints expect the API key in the X-API-Key header.\n\n[Swagger](/docs)\n[Redoc](/redoc)\n[OpenAPI](/openapi.json)\n", + "description": "API version: v1 Controller version: 0.20.1\n\nAPI for controlling and managing Supervaize agents. \n\nMore information at [https://doc.supervaize.com](https://doc.supervaize.com)\n\n## Authentication\n\nSome endpoints require API key authentication. Protected endpoints expect the API key in the X-API-Key header.\n\n[Swagger](/docs)\n[Redoc](/redoc)\n[OpenAPI](/openapi.json)\n", "termsOfService": "https://supervaize.com/terms/", "contact": { "name": "Support Team", @@ -16,19 +16,135 @@ "version": "v1" }, "paths": { - "/supervaizer/jobs/{job_id}": { + "/api/supervaizer/contract": { "get": { "tags": [ "Supervision" ], - "summary": "Get Job Status", - "description": "Get the status of a job by its ID", - "operationId": "get_job_status_supervaizer_jobs__job_id__get", - "security": [ + "summary": "Get Controller Contract", + "description": "Return the controller contract Studio should use for route resolution.", + "operationId": "get_controller_contract_api_supervaizer_contract_get", + "parameters": [ { - "APIKeyHeader": [] + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + } + ], + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": true, + "title": "Response Get Controller Contract Api Supervaizer Contract Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/api/supervaizer/registration/refresh": { + "post": { + "tags": [ + "Supervision" + ], + "summary": "Refresh Controller Registration", + "description": "Accept a Studio request to re-send the canonical server.register event.", + "operationId": "refresh_controller_registration_api_supervaizer_registration_refresh_post", + "parameters": [ + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + } + ], + "requestBody": { + "content": { + "application/json": { + "schema": { + "anyOf": [ + { + "$ref": "#/components/schemas/RegistrationRefreshRequest" + }, + { + "type": "null" + } + ], + "title": "Request Data" + } + } + } + }, + "responses": { + "202": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": true, + "title": "Response Refresh Controller Registration Api Supervaizer Registration Refresh Post" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } } + } + } + }, + "/api/supervaizer/jobs/{job_id}": { + "get": { + "tags": [ + "Supervision" ], + "summary": "Get Job Status", + "description": "Get the status of a job by its ID", + "operationId": "get_job_status_api_supervaizer_jobs__job_id__get", "parameters": [ { "name": "job_id", @@ -38,6 +154,22 @@ "type": "string", "title": "Job Id" } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } } ], "responses": { @@ -64,19 +196,14 @@ } } }, - "/supervaizer/jobs": { + "/api/supervaizer/jobs": { "get": { "tags": [ "Supervision" ], "summary": "Get All Jobs", "description": "Get all jobs across all agents with pagination and optional status filtering", - "operationId": "get_all_jobs_supervaizer_jobs_get", - "security": [ - { - "APIKeyHeader": [] - } - ], + "operationId": "get_all_jobs_api_supervaizer_jobs_get", "parameters": [ { "name": "skip", @@ -122,6 +249,22 @@ "title": "Status" }, "description": "Filter jobs by status" + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } } ], "responses": { @@ -137,7 +280,7 @@ "$ref": "#/components/schemas/JobResponse" } }, - "title": "Response Get All Jobs Supervaizer Jobs Get" + "title": "Response Get All Jobs Api Supervaizer Jobs Get" } } } @@ -155,19 +298,14 @@ } } }, - "/supervaizer/jobs/{job_id}/cases/{case_id}/update": { + "/api/supervaizer/jobs/{job_id}/cases/{case_id}/update": { "post": { "tags": [ "Supervision" ], "summary": "Update case with answer to question", "description": "Provide an answer to a question that was requested by a case step", - "operationId": "update_case_with_answer_supervaizer_jobs__job_id__cases__case_id__update_post", - "security": [ - { - "APIKeyHeader": [] - } - ], + "operationId": "update_case_with_answer_api_supervaizer_jobs__job_id__cases__case_id__update_post", "parameters": [ { "name": "job_id", @@ -186,6 +324,22 @@ "type": "string", "title": "Case Id" } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } } ], "requestBody": { @@ -208,7 +362,7 @@ "additionalProperties": { "type": "string" }, - "title": "Response 200 Update Case With Answer Supervaizer Jobs Job Id Cases Case Id Update Post" + "title": "Response 200 Update Case With Answer Api Supervaizer Jobs Job Id Cases Case Id Update Post" } } } @@ -256,14 +410,14 @@ } } }, - "/supervaizer/agents": { + "/api/supervaizer/agents": { "get": { "tags": [ "Supervision" ], "summary": "Get All Agents", "description": "Get all registered agents with pagination", - "operationId": "get_all_agents_supervaizer_agents_get", + "operationId": "get_all_agents_api_supervaizer_agents_get", "parameters": [ { "name": "skip", @@ -291,6 +445,22 @@ "title": "Limit" }, "description": "Number of jobs to return" + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } } ], "responses": { @@ -303,7 +473,7 @@ "items": { "$ref": "#/components/schemas/AgentResponse" }, - "title": "Response Get All Agents Supervaizer Agents Get" + "title": "Response Get All Agents Api Supervaizer Agents Get" } } } @@ -321,14 +491,14 @@ } } }, - "/supervaizer/agent/{agent_id}": { + "/api/supervaizer/agent/{agent_id}": { "get": { "tags": [ "Supervision" ], "summary": "Get Agent Details", "description": "Get details of a specific agent by ID", - "operationId": "get_agent_details_supervaizer_agent__agent_id__get", + "operationId": "get_agent_details_api_supervaizer_agent__agent_id__get", "parameters": [ { "name": "agent_id", @@ -338,6 +508,22 @@ "type": "string", "title": "Agent Id" } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } } ], "responses": { @@ -364,14 +550,32 @@ } } }, - "/supervaizer/utils/public_key": { + "/api/supervaizer/utils/public_key": { "get": { "tags": [ "Supervision" ], "summary": "Get server's public key", "description": "Returns the server's public key in PEM format", - "operationId": "get_public_key_supervaizer_utils_public_key_get", + "operationId": "get_public_key_api_supervaizer_utils_public_key_get", + "parameters": [ + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + } + ], "responses": { "200": { "description": "Successful Response", @@ -379,7 +583,17 @@ "application/json": { "schema": { "type": "string", - "title": "Response Get Public Key Supervaizer Utils Public Key Get" + "title": "Response Get Public Key Api Supervaizer Utils Public Key Get" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" } } } @@ -387,15 +601,34 @@ } } }, - "/supervaizer/utils/encrypt": { + "/api/supervaizer/utils/encrypt": { "post": { "tags": [ "Supervision" ], "summary": "Encrypt a string", "description": "Encrypts a string using the server's public key. Example: {'key':'value'}", - "operationId": "encrypt_string_supervaizer_utils_encrypt_post", + "operationId": "encrypt_string_api_supervaizer_utils_encrypt_post", + "parameters": [ + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + } + ], "requestBody": { + "required": true, "content": { "application/json": { "schema": { @@ -403,8 +636,7 @@ "title": "Text" } } - }, - "required": true + } }, "responses": { "200": { @@ -413,7 +645,7 @@ "application/json": { "schema": { "type": "string", - "title": "Response Encrypt String Supervaizer Utils Encrypt Post" + "title": "Response Encrypt String Api Supervaizer Utils Encrypt Post" } } } @@ -431,7 +663,7 @@ } } }, - "/supervaizer/agents/competitor-summary/": { + "/api/supervaizer/agents/competitor-summary/": { "get": { "tags": [ "Supervision", @@ -440,7 +672,25 @@ ], "summary": "Get information about the agent competitor_summary", "description": "Detailed information about the agent, returned as a JSON object with Agent class fields", - "operationId": "agent_info_supervaizer_agents_competitor_summary__get", + "operationId": "agent_info_api_supervaizer_agents_competitor_summary__get", + "parameters": [ + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + } + ], "responses": { "200": { "description": "Successful Response", @@ -451,16 +701,21 @@ } } } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } } - }, - "security": [ - { - "APIKeyHeader": [] - } - ] + } } }, - "/supervaizer/agents/competitor-summary/supervaize_instructions.html": { + "/api/supervaizer/agents/competitor-summary/supervaize_instructions.html": { "get": { "tags": [ "Supervision", @@ -469,71 +724,32 @@ ], "summary": "Get supervaize instructions page for agent competitor_summary", "description": "HTML page displaying agent registration information and instructions", - "operationId": "supervaize_instructions_supervaizer_agents_competitor_summary_supervaize_instructions_html_get", - "responses": { - "200": { - "description": "Successful Response", - "content": { - "text/html": { - "schema": { + "operationId": "supervaize_instructions_api_supervaizer_agents_competitor_summary_supervaize_instructions_html_get", + "parameters": [ + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { "type": "string" + }, + { + "type": "null" } - } + ], + "title": "X-Api-Key" } } - } - } - }, - "/supervaizer/agents/competitor-summary/validate-agent-parameters": { - "post": { - "tags": [ - "Supervision", - "Supervision" ], - "summary": "Validate agent parameters for agent: competitor_summary", - "description": "Validate agent configuration parameters (secrets, API keys, etc.) before starting a job", - "operationId": "validate_agent_parameters_supervaizer_agents_competitor_summary_validate_agent_parameters_post", - "requestBody": { - "content": { - "application/json": { - "schema": { - "title": "Body Params" - } - } - }, - "required": true - }, "responses": { "200": { "description": "Successful Response", "content": { - "application/json": { - "schema": { - "additionalProperties": true, - "type": "object", - "title": "Response 200 Validate Agent Parameters Supervaizer Agents Competitor Summary Validate Agent Parameters Post" - } - } - } - }, - "400": { - "description": "Bad Request", - "content": { - "application/json": { - "schema": { - "additionalProperties": true, - "type": "object", - "title": "Response 400 Validate Agent Parameters Supervaizer Agents Competitor Summary Validate Agent Parameters Post" - } - } - } - }, - "500": { - "description": "Internal Server Error", - "content": { - "application/json": { + "text/html": { "schema": { - "$ref": "#/components/schemas/ErrorResponse" + "type": "string" } } } @@ -548,32 +764,45 @@ } } } - }, - "security": [ - { - "APIKeyHeader": [] - } - ] + } } }, - "/supervaizer/agents/competitor-summary/validate-method-fields": { + "/api/supervaizer/agents/competitor-summary/validate-agent-parameters": { "post": { "tags": [ "Supervision", "Supervision" ], - "summary": "Validate method fields for agent: competitor_summary", - "description": "Validate job input fields against the method's field definitions before starting a job", - "operationId": "validate_method_fields_supervaizer_agents_competitor_summary_validate_method_fields_post", + "summary": "Validate agent parameters for agent: competitor_summary", + "description": "Validate agent configuration parameters (secrets, API keys, etc.) before starting a job", + "operationId": "validate_agent_parameters_api_supervaizer_agents_competitor_summary_validate_agent_parameters_post", + "parameters": [ + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + } + ], "requestBody": { + "required": true, "content": { "application/json": { "schema": { "title": "Body Params" } } - }, - "required": true + } }, "responses": { "200": { @@ -581,34 +810,34 @@ "content": { "application/json": { "schema": { - "additionalProperties": true, "type": "object", - "title": "Response 200 Validate Method Fields Supervaizer Agents Competitor Summary Validate Method Fields Post" + "additionalProperties": true, + "title": "Response 200 Validate Agent Parameters Api Supervaizer Agents Competitor Summary Validate Agent Parameters Post" } } } }, "400": { - "description": "Bad Request", "content": { "application/json": { "schema": { - "additionalProperties": true, "type": "object", - "title": "Response 400 Validate Method Fields Supervaizer Agents Competitor Summary Validate Method Fields Post" + "additionalProperties": true, + "title": "Response 400 Validate Agent Parameters Api Supervaizer Agents Competitor Summary Validate Agent Parameters Post" } } - } + }, + "description": "Bad Request" }, "500": { - "description": "Internal Server Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } - } + }, + "description": "Internal Server Error" }, "422": { "description": "Validation Error", @@ -620,32 +849,45 @@ } } } - }, - "security": [ - { - "APIKeyHeader": [] - } - ] + } } }, - "/supervaizer/agents/competitor-summary/start/dynamic_choices": { + "/api/supervaizer/agents/competitor-summary/validate-method-fields": { "post": { "tags": [ "Supervision", "Supervision" ], - "summary": "Get dynamic choices for agent: competitor_summary start method", - "description": "Returns dynamic choice values for fields that use dynamic_choices. Accepts workspace and mission context (including workspace slug) for contextualized choices.", - "operationId": "get_dynamic_choices_supervaizer_agents_competitor_summary_start_dynamic_choices_post", + "summary": "Validate method fields for agent: competitor_summary", + "description": "Validate job input fields against the method's field definitions before starting a job", + "operationId": "validate_method_fields_api_supervaizer_agents_competitor_summary_validate_method_fields_post", + "parameters": [ + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + } + ], "requestBody": { + "required": true, "content": { "application/json": { "schema": { "title": "Body Params" } } - }, - "required": true + } }, "responses": { "200": { @@ -653,32 +895,34 @@ "content": { "application/json": { "schema": { - "additionalProperties": true, "type": "object", - "title": "Response 200 Get Dynamic Choices Supervaizer Agents Competitor Summary Start Dynamic Choices Post" + "additionalProperties": true, + "title": "Response 200 Validate Method Fields Api Supervaizer Agents Competitor Summary Validate Method Fields Post" } } } }, - "404": { - "description": "Not Found", + "400": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ErrorResponse" + "type": "object", + "additionalProperties": true, + "title": "Response 400 Validate Method Fields Api Supervaizer Agents Competitor Summary Validate Method Fields Post" } } - } + }, + "description": "Bad Request" }, "500": { - "description": "Internal Server Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } - } + }, + "description": "Internal Server Error" }, "422": { "description": "Validation Error", @@ -690,15 +934,10 @@ } } } - }, - "security": [ - { - "APIKeyHeader": [] - } - ] + } } }, - "/supervaizer/agents/competitor-summary/jobs": { + "/api/supervaizer/agents/competitor-summary/jobs": { "post": { "tags": [ "Supervision", @@ -706,10 +945,23 @@ ], "summary": "Start a job with agent: competitor_summary", "description": "Start the collection of new competitor summary", - "operationId": "start_job_supervaizer_agents_competitor_summary_jobs_post", - "security": [ + "operationId": "start_job_api_supervaizer_agents_competitor_summary_jobs_post", + "parameters": [ { - "APIKeyHeader": [] + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } } ], "requestBody": { @@ -739,7 +991,7 @@ "schema": { "type": "object", "additionalProperties": true, - "title": "Response 400 Start Job Supervaizer Agents Competitor Summary Jobs Post" + "title": "Response 400 Start Job Api Supervaizer Agents Competitor Summary Jobs Post" } } }, @@ -784,12 +1036,7 @@ ], "summary": "Get all jobs for agent: competitor_summary", "description": "Get all jobs for this agent with pagination and optional status filtering", - "operationId": "get_agent_jobs_supervaizer_agents_competitor_summary_jobs_get", - "security": [ - { - "APIKeyHeader": [] - } - ], + "operationId": "get_agent_jobs_api_supervaizer_agents_competitor_summary_jobs_get", "parameters": [ { "name": "skip", @@ -835,6 +1082,22 @@ "title": "Status" }, "description": "Filter jobs by status" + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } } ], "responses": { @@ -847,7 +1110,7 @@ "items": { "$ref": "#/components/schemas/JobResponse" }, - "title": "Response 200 Get Agent Jobs Supervaizer Agents Competitor Summary Jobs Get" + "title": "Response 200 Get Agent Jobs Api Supervaizer Agents Competitor Summary Jobs Get" } } } @@ -875,7 +1138,7 @@ } } }, - "/supervaizer/agents/competitor-summary/jobs/{job_id}": { + "/api/supervaizer/agents/competitor-summary/jobs/{job_id}": { "get": { "tags": [ "Supervision", @@ -883,12 +1146,7 @@ ], "summary": "Get job status for agent: competitor_summary", "description": "Get the status and details of a specific job", - "operationId": "get_job_status_supervaizer_agents_competitor_summary_jobs__job_id__get", - "security": [ - { - "APIKeyHeader": [] - } - ], + "operationId": "get_job_status_api_supervaizer_agents_competitor_summary_jobs__job_id__get", "parameters": [ { "name": "job_id", @@ -898,6 +1156,22 @@ "type": "string", "title": "Job Id" } + }, + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } } ], "responses": { @@ -944,7 +1218,7 @@ } } }, - "/supervaizer/agents/competitor-summary/stop": { + "/api/supervaizer/agents/competitor-summary/stop": { "post": { "tags": [ "Supervision", @@ -952,18 +1226,36 @@ ], "summary": "Stop the agent: competitor_summary", "description": "Stop the agent", - "operationId": "stop_agent_supervaizer_agents_competitor_summary_stop_post", + "operationId": "stop_agent_api_supervaizer_agents_competitor_summary_stop_post", + "parameters": [ + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + } + ], "requestBody": { + "required": true, "content": { "application/json": { "schema": { - "additionalProperties": true, "type": "object", + "additionalProperties": true, "title": "Params" } } - }, - "required": true + } }, "responses": { "200": { @@ -977,14 +1269,14 @@ } }, "202": { - "description": "Accepted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AgentResponse" } } - } + }, + "description": "Accepted" }, "422": { "description": "Validation Error", @@ -996,15 +1288,10 @@ } } } - }, - "security": [ - { - "APIKeyHeader": [] - } - ] + } } }, - "/supervaizer/agents/competitor-summary/status": { + "/api/supervaizer/agents/competitor-summary/status": { "post": { "tags": [ "Supervision", @@ -1012,16 +1299,34 @@ ], "summary": "Get the status of the agent: competitor_summary", "description": "Get the status of the agent", - "operationId": "status_agent_supervaizer_agents_competitor_summary_status_post", + "operationId": "status_agent_api_supervaizer_agents_competitor_summary_status_post", + "parameters": [ + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + } + ], "requestBody": { + "required": true, "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AgentMethodParams" } } - }, - "required": true + } }, "responses": { "200": { @@ -1035,34 +1340,34 @@ } }, "400": { - "description": "Bad Request", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } - } + }, + "description": "Bad Request" }, "404": { - "description": "Not Found", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } - } + }, + "description": "Not Found" }, "500": { - "description": "Internal Server Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } - } + }, + "description": "Internal Server Error" }, "422": { "description": "Validation Error", @@ -1074,15 +1379,10 @@ } } } - }, - "security": [ - { - "APIKeyHeader": [] - } - ] + } } }, - "/supervaizer/agents/competitor-summary/parameters": { + "/api/supervaizer/agents/competitor-summary/parameters": { "post": { "tags": [ "Supervision", @@ -1090,12 +1390,30 @@ ], "summary": "Server updates agent: competitor_summary", "description": "Server updates agent onboarding status and/or encrypted parameters", - "operationId": "server_update_agent_supervaizer_agents_competitor_summary_parameters_post", + "operationId": "server_update_agent_api_supervaizer_agents_competitor_summary_parameters_post", + "parameters": [ + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + } + ], "requestBody": { "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Body_server_update_agent_supervaizer_agents_competitor_summary_parameters_post" + "$ref": "#/components/schemas/Body_server_update_agent_api_supervaizer_agents_competitor_summary_parameters_post" } } } @@ -1112,14 +1430,14 @@ } }, "500": { - "description": "Internal Server Error", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } - } + }, + "description": "Internal Server Error" }, "422": { "description": "Validation Error", @@ -1131,15 +1449,10 @@ } } } - }, - "security": [ - { - "APIKeyHeader": [] - } - ] + } } }, - "/supervaizer/agents/competitor-summary/custom/custom1": { + "/api/supervaizer/agents/competitor-summary/custom/custom1": { "post": { "tags": [ "Supervision", @@ -1147,16 +1460,34 @@ ], "summary": "Trigger custom method 'custom1' for agent: competitor_summary", "description": "Custom method", - "operationId": "competitor_summary_custom_custom1_supervaizer_agents_competitor_summary_custom_custom1_post", + "operationId": "competitor_summary_custom_custom1_api_supervaizer_agents_competitor_summary_custom_custom1_post", + "parameters": [ + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + } + ], "requestBody": { + "required": true, "content": { "application/json": { "schema": { "title": "Body Params" } } - }, - "required": true + } }, "responses": { "200": { @@ -1170,36 +1501,36 @@ } }, "202": { - "description": "Accepted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/JobResponse" } } - } + }, + "description": "Accepted" }, "400": { - "description": "Bad Request", "content": { "application/json": { "schema": { - "additionalProperties": true, "type": "object", - "title": "Response 400 Competitor Summary Custom Custom1 Supervaizer Agents Competitor Summary Custom Custom1 Post" + "additionalProperties": true, + "title": "Response 400 Competitor Summary Custom Custom1 Api Supervaizer Agents Competitor Summary Custom Custom1 Post" } } - } + }, + "description": "Bad Request" }, "405": { - "description": "Method Not Allowed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } - } + }, + "description": "Method Not Allowed" }, "422": { "description": "Validation Error", @@ -1211,15 +1542,10 @@ } } } - }, - "security": [ - { - "APIKeyHeader": [] - } - ] + } } }, - "/supervaizer/agents/competitor-summary/custom/custom2": { + "/api/supervaizer/agents/competitor-summary/custom/custom2": { "post": { "tags": [ "Supervision", @@ -1227,16 +1553,34 @@ ], "summary": "Trigger custom method 'custom2' for agent: competitor_summary", "description": "Custom method", - "operationId": "competitor_summary_custom_custom2_supervaizer_agents_competitor_summary_custom_custom2_post", + "operationId": "competitor_summary_custom_custom2_api_supervaizer_agents_competitor_summary_custom_custom2_post", + "parameters": [ + { + "name": "X-API-Key", + "in": "header", + "required": false, + "schema": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "X-Api-Key" + } + } + ], "requestBody": { + "required": true, "content": { "application/json": { "schema": { "title": "Body Params" } } - }, - "required": true + } }, "responses": { "200": { @@ -1250,58 +1594,75 @@ } }, "202": { - "description": "Accepted", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/JobResponse" } } - } + }, + "description": "Accepted" }, "400": { - "description": "Bad Request", "content": { "application/json": { "schema": { - "additionalProperties": true, "type": "object", - "title": "Response 400 Competitor Summary Custom Custom2 Supervaizer Agents Competitor Summary Custom Custom2 Post" + "additionalProperties": true, + "title": "Response 400 Competitor Summary Custom Custom2 Api Supervaizer Agents Competitor Summary Custom Custom2 Post" } } - } + }, + "description": "Bad Request" }, "405": { - "description": "Method Not Allowed", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ErrorResponse" } } - } + }, + "description": "Method Not Allowed" }, "422": { "description": "Validation Error", "content": { - "application/json": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/": { + "get": { + "tags": [ + "Public" + ], + "summary": "Home Page", + "operationId": "home_page__get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "text/html": { "schema": { - "$ref": "#/components/schemas/HTTPValidationError" + "type": "string" } } } } - }, - "security": [ - { - "APIKeyHeader": [] - } - ] + } } }, "/.well-known/agents.json": { "get": { "tags": [ + "Public", "Protocol A2A" ], "summary": "A2A Agents Discovery", @@ -1326,6 +1687,7 @@ "/.well-known/health": { "get": { "tags": [ + "Public", "Protocol A2A" ], "summary": "A2A Health Status", @@ -1350,6 +1712,7 @@ "/.well-known/agents/v1.3/competitor-summary_agent.json": { "get": { "tags": [ + "Public", "Protocol A2A" ], "summary": "A2A Agent Card for competitor_summary (v1)", @@ -1374,6 +1737,7 @@ "/.well-known/agents/competitor-summary_agent.json": { "get": { "tags": [ + "Public", "Protocol A2A" ], "summary": "A2A Agent Card for competitor_summary (Legacy)", @@ -1395,14 +1759,82 @@ } } }, - "/admin/": { + "/a2a": { + "post": { + "tags": [ + "Public", + "Protocol A2A" + ], + "summary": "A2A JSON-RPC Controller", + "description": "Dispatches Supervaizer v2 controller methods over A2A JSON-RPC.", + "operationId": "post_a2a_controller_a2a_post", + "requestBody": { + "content": { + "application/json": { + "schema": { + "additionalProperties": true, + "type": "object", + "title": "Body" + } + } + }, + "required": true + }, + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": { + "additionalProperties": true, + "type": "object", + "title": "Response Post A2A Controller A2A Post" + } + } + } + }, + "422": { + "description": "Validation Error", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HTTPValidationError" + } + } + } + } + } + } + }, + "/a2a/events": { + "get": { + "tags": [ + "Public", + "Protocol A2A" + ], + "summary": "A2A SSE Event Stream", + "description": "Streams Supervaizer v2 controller effects over Server-Sent Events.", + "operationId": "get_a2a_events_a2a_events_get", + "responses": { + "200": { + "description": "Successful Response", + "content": { + "application/json": { + "schema": {} + } + } + } + } + } + }, + "/manage/": { "get": { "tags": [ "admin" ], "summary": "Admin Dashboard", "description": "Admin dashboard page.", - "operationId": "admin_dashboard_admin__get", + "operationId": "admin_dashboard_manage__get", "responses": { "200": { "description": "Successful Response", @@ -1417,14 +1849,14 @@ } } }, - "/admin/jobs": { + "/manage/jobs": { "get": { "tags": [ "admin" ], "summary": "Admin Jobs Page", "description": "Jobs management page.", - "operationId": "admin_jobs_page_admin_jobs_get", + "operationId": "admin_jobs_page_manage_jobs_get", "responses": { "200": { "description": "Successful Response", @@ -1439,14 +1871,14 @@ } } }, - "/admin/cases": { + "/manage/cases": { "get": { "tags": [ "admin" ], "summary": "Admin Cases Page", "description": "Cases management page.", - "operationId": "admin_cases_page_admin_cases_get", + "operationId": "admin_cases_page_manage_cases_get", "responses": { "200": { "description": "Successful Response", @@ -1461,14 +1893,14 @@ } } }, - "/admin/server": { + "/manage/server": { "get": { "tags": [ "admin" ], "summary": "Admin Server Page", "description": "Server status and configuration page.", - "operationId": "admin_server_page_admin_server_get", + "operationId": "admin_server_page_manage_server_get", "responses": { "200": { "description": "Successful Response", @@ -1483,14 +1915,14 @@ } } }, - "/admin/agents": { + "/manage/agents": { "get": { "tags": [ "admin" ], "summary": "Admin Agents Page", "description": "Agents management page.", - "operationId": "admin_agents_page_admin_agents_get", + "operationId": "admin_agents_page_manage_agents_get", "responses": { "200": { "description": "Successful Response", @@ -1505,14 +1937,14 @@ } } }, - "/admin/job-start-test": { + "/manage/job-start-test": { "get": { "tags": [ "admin" ], "summary": "Admin Job Start Test Page", "description": "Job start form test page.", - "operationId": "admin_job_start_test_page_admin_job_start_test_get", + "operationId": "admin_job_start_test_page_manage_job_start_test_get", "responses": { "200": { "description": "Successful Response", @@ -1527,14 +1959,14 @@ } } }, - "/admin/static/{file_path}": { + "/manage/static/{file_path}": { "get": { "tags": [ "admin" ], "summary": "Serve Static", "description": "Serve static files from the admin static directory.", - "operationId": "serve_static_admin_static__file_path__get", + "operationId": "serve_static_manage_static__file_path__get", "parameters": [ { "name": "file_path", @@ -1568,14 +2000,14 @@ } } }, - "/admin/console": { + "/manage/console": { "get": { "tags": [ "admin" ], "summary": "Admin Console Page", - "description": "Interactive console page - publicly accessible, authentication handled by frontend.", - "operationId": "admin_console_page_admin_console_get", + "description": "Interactive console page \u2014 access enforced by Tailscale at router level.", + "operationId": "admin_console_page_manage_console_get", "responses": { "200": { "description": "Successful Response", @@ -1590,14 +2022,14 @@ } } }, - "/admin/api/stats": { + "/manage/api/stats": { "get": { "tags": [ "admin" ], "summary": "Get Stats", "description": "Get system statistics.", - "operationId": "get_stats_admin_api_stats_get", + "operationId": "get_stats_manage_api_stats_get", "responses": { "200": { "description": "Successful Response", @@ -1612,14 +2044,14 @@ } } }, - "/admin/api/server/status": { + "/manage/api/server/status": { "get": { "tags": [ "admin" ], "summary": "Get Server Status Api", "description": "Get current server status for HTMX refresh.", - "operationId": "get_server_status_api_admin_api_server_status_get", + "operationId": "get_server_status_api_manage_api_server_status_get", "responses": { "200": { "description": "Successful Response", @@ -1632,14 +2064,14 @@ } } }, - "/admin/api/server/register": { + "/manage/api/server/register": { "post": { "tags": [ "admin" ], "summary": "Register Server With Supervisor", "description": "Trigger SERVER_REGISTER to the supervaizer supervisor (no frontend API key; backend sends to SUPERVAIZE_API_URL).", - "operationId": "register_server_with_supervisor_admin_api_server_register_post", + "operationId": "register_server_with_supervisor_manage_api_server_register_post", "responses": { "200": { "description": "Successful Response", @@ -1652,14 +2084,14 @@ } } }, - "/admin/api/agents": { + "/manage/api/agents": { "get": { "tags": [ "admin" ], "summary": "Get Agents Api", "description": "Get agents with filtering for HTMX refresh.", - "operationId": "get_agents_api_admin_api_agents_get", + "operationId": "get_agents_api_manage_api_agents_get", "parameters": [ { "name": "status", @@ -1742,14 +2174,14 @@ } } }, - "/admin/api/agents/{agent_slug}": { + "/manage/api/agents/{agent_slug}": { "get": { "tags": [ "admin" ], "summary": "Get Agent Details", "description": "Get detailed agent information.", - "operationId": "get_agent_details_admin_api_agents__agent_slug__get", + "operationId": "get_agent_details_manage_api_agents__agent_slug__get", "parameters": [ { "name": "agent_slug", @@ -1783,14 +2215,14 @@ } } }, - "/admin/api/jobs": { + "/manage/api/jobs": { "get": { "tags": [ "admin" ], "summary": "Get Jobs Api", "description": "Get jobs with filtering and pagination.", - "operationId": "get_jobs_api_admin_api_jobs_get", + "operationId": "get_jobs_api_manage_api_jobs_get", "parameters": [ { "name": "status", @@ -1895,14 +2327,14 @@ } } }, - "/admin/api/jobs/{job_id}": { + "/manage/api/jobs/{job_id}": { "get": { "tags": [ "admin" ], "summary": "Get Job Details", "description": "Get detailed job information.", - "operationId": "get_job_details_admin_api_jobs__job_id__get", + "operationId": "get_job_details_manage_api_jobs__job_id__get", "parameters": [ { "name": "job_id", @@ -1941,7 +2373,7 @@ ], "summary": "Delete Job", "description": "Delete a job and its related cases.", - "operationId": "delete_job_admin_api_jobs__job_id__delete", + "operationId": "delete_job_manage_api_jobs__job_id__delete", "parameters": [ { "name": "job_id", @@ -1963,7 +2395,7 @@ "additionalProperties": { "type": "string" }, - "title": "Response Delete Job Admin Api Jobs Job Id Delete" + "title": "Response Delete Job Manage Api Jobs Job Id Delete" } } } @@ -1981,14 +2413,14 @@ } } }, - "/admin/api/cases": { + "/manage/api/cases": { "get": { "tags": [ "admin" ], "summary": "Get Cases Api", "description": "Get cases with filtering and pagination.", - "operationId": "get_cases_api_admin_api_cases_get", + "operationId": "get_cases_api_manage_api_cases_get", "parameters": [ { "name": "status", @@ -2093,14 +2525,14 @@ } } }, - "/admin/api/cases/{case_id}": { + "/manage/api/cases/{case_id}": { "get": { "tags": [ "admin" ], "summary": "Get Case Details", "description": "Get detailed case information.", - "operationId": "get_case_details_admin_api_cases__case_id__get", + "operationId": "get_case_details_manage_api_cases__case_id__get", "parameters": [ { "name": "case_id", @@ -2139,7 +2571,7 @@ ], "summary": "Delete Case", "description": "Delete a case.", - "operationId": "delete_case_admin_api_cases__case_id__delete", + "operationId": "delete_case_manage_api_cases__case_id__delete", "parameters": [ { "name": "case_id", @@ -2161,7 +2593,7 @@ "additionalProperties": { "type": "string" }, - "title": "Response Delete Case Admin Api Cases Case Id Delete" + "title": "Response Delete Case Manage Api Cases Case Id Delete" } } } @@ -2179,14 +2611,14 @@ } } }, - "/admin/api/jobs/{job_id}/status": { + "/manage/api/jobs/{job_id}/status": { "post": { "tags": [ "admin" ], "summary": "Update Job Status", "description": "Update job status.", - "operationId": "update_job_status_admin_api_jobs__job_id__status_post", + "operationId": "update_job_status_manage_api_jobs__job_id__status_post", "parameters": [ { "name": "job_id", @@ -2222,7 +2654,7 @@ "additionalProperties": { "type": "string" }, - "title": "Response Update Job Status Admin Api Jobs Job Id Status Post" + "title": "Response Update Job Status Manage Api Jobs Job Id Status Post" } } } @@ -2240,14 +2672,14 @@ } } }, - "/admin/api/cases/{case_id}/status": { + "/manage/api/cases/{case_id}/status": { "post": { "tags": [ "admin" ], "summary": "Update Case Status", "description": "Update case status.", - "operationId": "update_case_status_admin_api_cases__case_id__status_post", + "operationId": "update_case_status_manage_api_cases__case_id__status_post", "parameters": [ { "name": "case_id", @@ -2283,7 +2715,7 @@ "additionalProperties": { "type": "string" }, - "title": "Response Update Case Status Admin Api Cases Case Id Status Post" + "title": "Response Update Case Status Manage Api Cases Case Id Status Post" } } } @@ -2301,14 +2733,14 @@ } } }, - "/admin/api/recent-activity": { + "/manage/api/recent-activity": { "get": { "tags": [ "admin" ], "summary": "Get Recent Activity", "description": "Get recent entity activity.", - "operationId": "get_recent_activity_admin_api_recent_activity_get", + "operationId": "get_recent_activity_manage_api_recent_activity_get", "responses": { "200": { "description": "Successful Response", @@ -2321,48 +2753,14 @@ } } }, - "/admin/log-stream": { + "/manage/log-stream": { "get": { "tags": [ "admin" ], "summary": "Log Stream", "description": "Stream log messages via Server-Sent Events.", - "operationId": "log_stream_admin_log_stream_get", - "parameters": [ - { - "name": "token", - "in": "query", - "required": false, - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Token" - } - }, - { - "name": "key", - "in": "query", - "required": false, - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Key" - } - } - ], + "operationId": "log_stream_manage_log_stream_get", "responses": { "200": { "description": "Successful Response", @@ -2371,28 +2769,18 @@ "schema": {} } } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } } } } }, - "/admin/test-log": { + "/manage/test-log": { "get": { "tags": [ "admin" ], "summary": "Test Log", "description": "Test endpoint to generate a log message.", - "operationId": "test_log_admin_test_log_get", + "operationId": "test_log_manage_test_log_get", "responses": { "200": { "description": "Successful Response", @@ -2403,31 +2791,7 @@ "type": "string" }, "type": "object", - "title": "Response Test Log Admin Test Log Get" - } - } - } - } - } - } - }, - "/admin/debug-tokens": { - "get": { - "tags": [ - "admin" - ], - "summary": "Debug Tokens", - "description": "Debug endpoint to see current tokens.", - "operationId": "debug_tokens_admin_debug_tokens_get", - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": { - "additionalProperties": true, - "type": "object", - "title": "Response Debug Tokens Admin Debug Tokens Get" + "title": "Response Test Log Manage Test Log Get" } } } @@ -2435,14 +2799,14 @@ } } }, - "/admin/test-loguru": { + "/manage/test-loguru": { "get": { "tags": [ "admin" ], "summary": "Test Loguru", "description": "Test endpoint to generate loguru messages.", - "operationId": "test_loguru_admin_test_loguru_get", + "operationId": "test_loguru_manage_test_loguru_get", "responses": { "200": { "description": "Successful Response", @@ -2453,7 +2817,7 @@ "type": "string" }, "type": "object", - "title": "Response Test Loguru Admin Test Loguru Get" + "title": "Response Test Loguru Manage Test Loguru Get" } } } @@ -2461,14 +2825,14 @@ } } }, - "/admin/debug-queue": { + "/manage/debug-queue": { "get": { "tags": [ "admin" ], "summary": "Debug Queue", "description": "Debug endpoint to check log queue status.", - "operationId": "debug_queue_admin_debug_queue_get", + "operationId": "debug_queue_manage_debug_queue_get", "responses": { "200": { "description": "Successful Response", @@ -2477,7 +2841,7 @@ "schema": { "additionalProperties": true, "type": "object", - "title": "Response Debug Queue Admin Debug Queue Get" + "title": "Response Debug Queue Manage Debug Queue Get" } } } @@ -2485,45 +2849,27 @@ } } }, - "/admin/api/console/execute": { + "/manage/api/console/execute": { "post": { "tags": [ "admin" ], "summary": "Execute Console Command", - "description": "Execute a console command and add output to log stream.", - "operationId": "execute_console_command_admin_api_console_execute_post", - "parameters": [ - { - "name": "token", - "in": "query", - "required": false, - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Token" - } - } - ], + "description": "Execute a console command \u2014 access enforced by Tailscale at router level.", + "operationId": "execute_console_command_manage_api_console_execute_post", "requestBody": { - "required": true, "content": { "application/json": { "schema": { - "type": "object", "additionalProperties": { "type": "string" }, + "type": "object", "title": "Command Data" } } - } + }, + "required": true }, "responses": { "200": { @@ -2531,11 +2877,11 @@ "content": { "application/json": { "schema": { - "type": "object", "additionalProperties": { "type": "string" }, - "title": "Response Execute Console Command Admin Api Console Execute Post" + "type": "object", + "title": "Response Execute Console Command Manage Api Console Execute Post" } } } @@ -2553,7 +2899,7 @@ } } }, - "/admin/agents/{slug}/workbench": { + "/manage/agents/{slug}/workbench": { "get": { "tags": [ "admin", @@ -2561,12 +2907,7 @@ ], "summary": "Workbench Page", "description": "Render the main workbench page.", - "operationId": "workbench_page_admin_agents__slug__workbench_get", - "security": [ - { - "APIKeyHeader": [] - } - ], + "operationId": "workbench_page_manage_agents__slug__workbench_get", "parameters": [ { "name": "slug", @@ -2576,22 +2917,6 @@ "type": "string", "title": "Slug" } - }, - { - "name": "key", - "in": "query", - "required": false, - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Key" - } } ], "responses": { @@ -2618,7 +2943,7 @@ } } }, - "/admin/agents/{slug}/workbench/start": { + "/manage/agents/{slug}/workbench/start": { "post": { "tags": [ "admin", @@ -2626,108 +2951,15 @@ ], "summary": "Workbench Start Job", "description": "Start a job from the workbench \u2014 no Studio communication.", - "operationId": "workbench_start_job_admin_agents__slug__workbench_start_post", - "security": [ - { - "APIKeyHeader": [] - } - ], - "parameters": [ - { - "name": "slug", - "in": "path", - "required": true, - "schema": { - "type": "string", - "title": "Slug" - } - }, - { - "name": "key", - "in": "query", - "required": false, - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Key" - } - } - ], - "responses": { - "200": { - "description": "Successful Response", - "content": { - "application/json": { - "schema": {} - } - } - }, - "422": { - "description": "Validation Error", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/HTTPValidationError" - } - } - } - } - } - } - }, - "/admin/agents/{slug}/workbench/jobs/{job_id}": { - "get": { - "tags": [ - "admin", - "workbench" - ], - "summary": "Workbench Job Monitor", - "description": "HTMX partial \u2014 returns execution monitor HTML for polling.", - "operationId": "workbench_job_monitor_admin_agents__slug__workbench_jobs__job_id__get", - "security": [ - { - "APIKeyHeader": [] - } - ], + "operationId": "workbench_start_job_manage_agents__slug__workbench_start_post", "parameters": [ { "name": "slug", "in": "path", "required": true, "schema": { - "type": "string", - "title": "Slug" - } - }, - { - "name": "job_id", - "in": "path", - "required": true, - "schema": { - "type": "string", - "title": "Job Id" - } - }, - { - "name": "key", - "in": "query", - "required": false, - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Key" + "type": "string", + "title": "Slug" } } ], @@ -2735,10 +2967,8 @@ "200": { "description": "Successful Response", "content": { - "text/html": { - "schema": { - "type": "string" - } + "application/json": { + "schema": {} } } }, @@ -2755,20 +2985,15 @@ } } }, - "/admin/agents/{slug}/workbench/jobs/{job_id}/stop": { - "post": { + "/manage/agents/{slug}/workbench/jobs/{job_id}": { + "get": { "tags": [ "admin", "workbench" ], - "summary": "Workbench Stop Job", - "description": "Stop a running job.", - "operationId": "workbench_stop_job_admin_agents__slug__workbench_jobs__job_id__stop_post", - "security": [ - { - "APIKeyHeader": [] - } - ], + "summary": "Workbench Job Monitor", + "description": "HTMX partial \u2014 returns execution monitor HTML for polling.", + "operationId": "workbench_job_monitor_manage_agents__slug__workbench_jobs__job_id__get", "parameters": [ { "name": "slug", @@ -2787,30 +3012,16 @@ "type": "string", "title": "Job Id" } - }, - { - "name": "key", - "in": "query", - "required": false, - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Key" - } } ], "responses": { "200": { "description": "Successful Response", "content": { - "application/json": { - "schema": {} + "text/html": { + "schema": { + "type": "string" + } } } }, @@ -2827,20 +3038,15 @@ } } }, - "/admin/agents/{slug}/workbench/jobs/{job_id}/poll": { + "/manage/agents/{slug}/workbench/jobs/{job_id}/stop": { "post": { "tags": [ "admin", "workbench" ], - "summary": "Workbench Poll Job", - "description": "Trigger manual poll for external updates on a job.", - "operationId": "workbench_poll_job_admin_agents__slug__workbench_jobs__job_id__poll_post", - "security": [ - { - "APIKeyHeader": [] - } - ], + "summary": "Workbench Stop Job", + "description": "Stop a running job.", + "operationId": "workbench_stop_job_manage_agents__slug__workbench_jobs__job_id__stop_post", "parameters": [ { "name": "slug", @@ -2859,22 +3065,6 @@ "type": "string", "title": "Job Id" } - }, - { - "name": "key", - "in": "query", - "required": false, - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Key" - } } ], "responses": { @@ -2899,7 +3089,7 @@ } } }, - "/admin/agents/{slug}/workbench/jobs/{job_id}/status": { + "/manage/agents/{slug}/workbench/jobs/{job_id}/status": { "get": { "tags": [ "admin", @@ -2907,12 +3097,7 @@ ], "summary": "Workbench Job Status", "description": "Get job status via agent's job_status method.", - "operationId": "workbench_job_status_admin_agents__slug__workbench_jobs__job_id__status_get", - "security": [ - { - "APIKeyHeader": [] - } - ], + "operationId": "workbench_job_status_manage_agents__slug__workbench_jobs__job_id__status_get", "parameters": [ { "name": "slug", @@ -2931,22 +3116,6 @@ "type": "string", "title": "Job Id" } - }, - { - "name": "key", - "in": "query", - "required": false, - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Key" - } } ], "responses": { @@ -2971,7 +3140,7 @@ } } }, - "/admin/agents/{slug}/workbench/jobs/{job_id}/cases/{case_id}/answer": { + "/manage/agents/{slug}/workbench/jobs/{job_id}/cases/{case_id}/answer": { "post": { "tags": [ "admin", @@ -2979,12 +3148,7 @@ ], "summary": "Workbench Answer Hitl", "description": "Submit HITL answer \u2014 two-step dispatch (receive + invoke human_answer).", - "operationId": "workbench_answer_hitl_admin_agents__slug__workbench_jobs__job_id__cases__case_id__answer_post", - "security": [ - { - "APIKeyHeader": [] - } - ], + "operationId": "workbench_answer_hitl_manage_agents__slug__workbench_jobs__job_id__cases__case_id__answer_post", "parameters": [ { "name": "slug", @@ -3012,22 +3176,6 @@ "type": "string", "title": "Case Id" } - }, - { - "name": "key", - "in": "query", - "required": false, - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Key" - } } ], "responses": { @@ -3052,7 +3200,7 @@ } } }, - "/admin/agents/{slug}/workbench/jobs/{job_id}/steps/{case_id}/{step_index}/execute": { + "/manage/agents/{slug}/workbench/jobs/{job_id}/steps/{case_id}/{step_index}/execute": { "post": { "tags": [ "admin", @@ -3060,12 +3208,7 @@ ], "summary": "Workbench Execute Step", "description": "Execute a scheduled step immediately.", - "operationId": "workbench_execute_step_admin_agents__slug__workbench_jobs__job_id__steps__case_id___step_index__execute_post", - "security": [ - { - "APIKeyHeader": [] - } - ], + "operationId": "workbench_execute_step_manage_agents__slug__workbench_jobs__job_id__steps__case_id___step_index__execute_post", "parameters": [ { "name": "slug", @@ -3102,22 +3245,6 @@ "type": "integer", "title": "Step Index" } - }, - { - "name": "key", - "in": "query", - "required": false, - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Key" - } } ], "responses": { @@ -3142,7 +3269,7 @@ } } }, - "/admin/agents/{slug}/workbench/jobs/{job_id}/steps/{case_id}/{step_index}/cancel": { + "/manage/agents/{slug}/workbench/jobs/{job_id}/steps/{case_id}/{step_index}/cancel": { "post": { "tags": [ "admin", @@ -3150,12 +3277,7 @@ ], "summary": "Workbench Cancel Step", "description": "Cancel a pending scheduled step.", - "operationId": "workbench_cancel_step_admin_agents__slug__workbench_jobs__job_id__steps__case_id___step_index__cancel_post", - "security": [ - { - "APIKeyHeader": [] - } - ], + "operationId": "workbench_cancel_step_manage_agents__slug__workbench_jobs__job_id__steps__case_id___step_index__cancel_post", "parameters": [ { "name": "slug", @@ -3192,22 +3314,6 @@ "type": "integer", "title": "Step Index" } - }, - { - "name": "key", - "in": "query", - "required": false, - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Key" - } } ], "responses": { @@ -3232,7 +3338,7 @@ } } }, - "/admin/agents/{slug}/workbench/jobs/{job_id}/steps/{case_id}/{step_index}/schedule": { + "/manage/agents/{slug}/workbench/jobs/{job_id}/steps/{case_id}/{step_index}/schedule": { "patch": { "tags": [ "admin", @@ -3240,12 +3346,7 @@ ], "summary": "Workbench Reschedule Step", "description": "Reschedule a pending scheduled step.", - "operationId": "workbench_reschedule_step_admin_agents__slug__workbench_jobs__job_id__steps__case_id___step_index__schedule_patch", - "security": [ - { - "APIKeyHeader": [] - } - ], + "operationId": "workbench_reschedule_step_manage_agents__slug__workbench_jobs__job_id__steps__case_id___step_index__schedule_patch", "parameters": [ { "name": "slug", @@ -3282,22 +3383,6 @@ "type": "integer", "title": "Step Index" } - }, - { - "name": "key", - "in": "query", - "required": false, - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Key" - } } ], "responses": { @@ -3322,7 +3407,7 @@ } } }, - "/admin/agents/{slug}/workbench/console": { + "/manage/agents/{slug}/workbench/console": { "get": { "tags": [ "admin", @@ -3330,12 +3415,7 @@ ], "summary": "Workbench Console", "description": "HTMX partial \u2014 returns recent console log entries.", - "operationId": "workbench_console_admin_agents__slug__workbench_console_get", - "security": [ - { - "APIKeyHeader": [] - } - ], + "operationId": "workbench_console_manage_agents__slug__workbench_console_get", "parameters": [ { "name": "slug", @@ -3345,22 +3425,6 @@ "type": "string", "title": "Slug" } - }, - { - "name": "key", - "in": "query", - "required": false, - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Key" - } } ], "responses": { @@ -3387,7 +3451,7 @@ } } }, - "/admin/agents/{slug}/workbench/jobs": { + "/manage/agents/{slug}/workbench/jobs": { "get": { "tags": [ "admin", @@ -3395,12 +3459,7 @@ ], "summary": "Workbench Jobs List", "description": "HTMX partial \u2014 returns job history list.", - "operationId": "workbench_jobs_list_admin_agents__slug__workbench_jobs_get", - "security": [ - { - "APIKeyHeader": [] - } - ], + "operationId": "workbench_jobs_list_manage_agents__slug__workbench_jobs_get", "parameters": [ { "name": "slug", @@ -3410,22 +3469,6 @@ "type": "string", "title": "Slug" } - }, - { - "name": "key", - "in": "query", - "required": false, - "schema": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Key" - } } ], "responses": { @@ -3451,24 +3494,6 @@ } } } - }, - "/": { - "get": { - "summary": "Home Page", - "operationId": "home_page__get", - "responses": { - "200": { - "description": "Successful Response", - "content": { - "text/html": { - "schema": { - "type": "string" - } - } - } - } - } - } } }, "components": { @@ -3561,6 +3586,19 @@ "description": "Whether the method is asynchronous", "default": false }, + "timeout": { + "anyOf": [ + { + "type": "integer" + }, + { + "type": "null" + } + ], + "title": "Timeout", + "description": "Maximum automatic job duration in seconds. Use None for jobs that must run until Studio stops them manually.", + "default": 600 + }, "nodes": { "anyOf": [ { @@ -3668,18 +3706,6 @@ "title": "Required", "description": "Whether field is required for form submission", "default": false - }, - "dynamic_choices": { - "anyOf": [ - { - "type": "string" - }, - { - "type": "null" - } - ], - "title": "Dynamic Choices", - "description": "Key name for dynamic choices resolved at runtime via Agent.dynamic_choices_callback. Mutually exclusive with 'choices'." } }, "type": "object", @@ -3758,16 +3784,6 @@ } ] }, - "job_poll": { - "anyOf": [ - { - "$ref": "#/components/schemas/AgentMethod" - }, - { - "type": "null" - } - ] - }, "human_answer": { "anyOf": [ { @@ -3867,6 +3883,17 @@ "type": "string", "title": "Version" }, + "release_notes_url": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Release Notes Url" + }, "api_path": { "type": "string", "title": "Api Path" @@ -3970,7 +3997,7 @@ "title": "AgentResponse", "description": "Response model for agent endpoints - values provided by Agent.registration_info" }, - "Body_server_update_agent_supervaizer_agents_competitor_summary_parameters_post": { + "Body_server_update_agent_api_supervaizer_agents_competitor_summary_parameters_post": { "properties": { "onboarding_status": { "anyOf": [ @@ -3996,7 +4023,7 @@ } }, "type": "object", - "title": "Body_server_update_agent_supervaizer_agents_competitor_summary_parameters_post" + "title": "Body_server_update_agent_api_supervaizer_agents_competitor_summary_parameters_post" }, "CaseNode": { "properties": { @@ -4125,7 +4152,7 @@ "type": "string", "format": "date-time", "title": "Timestamp", - "default": "2026-04-09T00:25:26.894055" + "default": "2026-05-15T20:25:32.352375" }, "status_code": { "type": "integer", @@ -4285,6 +4312,12 @@ "type": "array", "title": "Case Ids", "default": [] + }, + "metadata": { + "additionalProperties": true, + "type": "object", + "title": "Metadata", + "description": "Agent-provided domain metadata (e.g. campaign context)" } }, "type": "object", @@ -4466,6 +4499,35 @@ ], "title": "JobResponse" }, + "RegistrationRefreshRequest": { + "properties": { + "reason": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Reason" + }, + "requested_at": { + "anyOf": [ + { + "type": "string" + }, + { + "type": "null" + } + ], + "title": "Requested At" + } + }, + "type": "object", + "title": "RegistrationRefreshRequest", + "description": "Request model for re-sending the server registration event." + }, "ValidationError": { "properties": { "loc": { @@ -4506,13 +4568,6 @@ ], "title": "ValidationError" } - }, - "securitySchemes": { - "APIKeyHeader": { - "type": "apiKey", - "in": "header", - "name": "X-API-Key" - } } } } diff --git a/docs/model_reference/model_core.md b/docs/model_reference/model_core.md index 68b82d4..218af9c 100644 --- a/docs/model_reference/model_core.md +++ b/docs/model_reference/model_core.md @@ -1,6 +1,10 @@ # Model Reference Core -**Version:** 0.13.0 + +> **Created:** 2025-08-09 +> **Updated:** 2026-05-16 + +**Version:** 0.20.1 ### `account.Account` @@ -116,6 +120,7 @@ _No additional fields beyond parent class._ | `maintainer` | `str` | `None` | Maintainer of the integration | | `editor` | `str` | `None` | Editor (usually a company) | | `version` | `str` | '' | Version string | +| `release_notes_url` | `str` | `None` | URL for release notes matching this agent version | | `description` | `str` | '' | Description of what the agent does | | `tags` | `list[str]` | `None` | Tags for categorizing the agent | | `methods` | `AgentMethods` | `None` | Methods supported by this agent | @@ -127,8 +132,9 @@ _No additional fields beyond parent class._ | `max_execution_time` | `int` | 3600 | Maximum execution time in seconds, defaults to 1 hour | | `supervaize_instructions_template_path` | `str` | `None` | Optional path to a custom template file for supervaize_instructions.html page | | `instructions_path` | `str` | 'supervaize_instructions.html' | Path where the supervaize instructions page is served (relative to agent path) | -| `custom_routes` | `Any` | `None` | Optional FastAPI APIRouter; mounted at `/api/agents/{slug}/...` on the API surface | -| `dynamic_choices_callback` | `Any` | `None` | Callable that returns dynamic choices for method fields. Signature: (method_name: str, context: dict) -> dict[str, list[tuple[str, str]]] | +| `custom_routes` | `Any` | `None` | Optional FastAPI APIRouter; mounted on the API app at /api/agents/{slug}/... | +| `data_resources` | `list[data_resource.DataResource]` | — | Data resources this agent exposes for Studio CRUD access | +| `supervaizer_v2_registration` | `SupervaizerV2AgentRegistrationContract` | `None` | Optional Supervaizer v2 registration contract for A2A/A2UI Studio integrations | ### `agent.AgentMethod` @@ -185,6 +191,7 @@ Attributes: | `fields` | `typing.List[supervaizer.agent.AgentMethodField]` | `None` | A list of field specifications for generating forms/UI, following the django.forms.fields definition | | `description` | `str` | `None` | Optional description of what the method does | | `is_async` | `bool` | False | Whether the method is asynchronous | +| `timeout` | `int` | 600 | Maximum automatic job duration in seconds. Use None for jobs that must run until Studio stops them manually. | | `nodes` | `CaseNodes` | `None` | The definition of the Case Nodes (=steps) for this method | #### Example @@ -242,7 +249,6 @@ field definitions for consistency. | `default` | `Any` | `None` | Default value for the field - displayed in the UI | | `widget` | `str` | `None` | UI widget to use (e.g. RadioSelect, TextInput) - as a django widget name | | `required` | `bool` | False | Whether field is required for form submission | -| `dynamic_choices` | `str` | `None` | Key name for dynamic choices resolved at runtime via Agent.dynamic_choices_callback. Mutually exclusive with 'choices'. | #### Examples @@ -440,4 +446,4 @@ public_url: full url (including scheme and port) to use for outbound connections ``` -*Uploaded on 2026-04-09 00:25:26* +*Uploaded on 2026-05-15 20:25:31* diff --git a/docs/model_reference/model_extra.md b/docs/model_reference/model_extra.md index be0810c..f673691 100644 --- a/docs/model_reference/model_extra.md +++ b/docs/model_reference/model_extra.md @@ -1,6 +1,10 @@ # Model Reference extra -**Version:** 0.13.0 + +> **Created:** 2025-08-08 +> **Updated:** 2026-05-16 + +**Version:** 0.20.1 ### `common.SvBaseModel` @@ -68,7 +72,6 @@ A base class for creating Pydantic models. | `job_start` | `AgentMethod` | **required** | | | `job_stop` | `AgentMethod` | `None` | | | `job_status` | `AgentMethod` | `None` | | -| `job_poll` | `AgentMethod` | `None` | | | `human_answer` | `AgentMethod` | `None` | | | `chat` | `AgentMethod` | `None` | | | `custom` | `dict[str, supervaizer.agent.AgentMethod]` | `None` | | @@ -86,6 +89,7 @@ Response model for agent endpoints - values provided by Agent.registration_info | `maintainer` | `str` | `None` | | | `editor` | `str` | `None` | | | `version` | `str` | **required** | | +| `release_notes_url` | `str` | `None` | | | `api_path` | `str` | **required** | | | `description` | `str` | **required** | | | `tags` | `list[str]` | `None` | | @@ -106,6 +110,48 @@ Response model for agent endpoints - values provided by Agent.registration_info |---|---|---|---| | `nodes` | `List[case.CaseNode]` | [] | | +### `data_resource.DataResource` + +**Inherits from:** [`common.SvBaseModel`](#commonsvbasemodel) + +Declares a named data resource the agent exposes for Studio CRUD access. + +The agent provides callback functions for each operation. The SDK generates +the corresponding FastAPI routes automatically. + +Example:: + + contacts_resource = DataResource( + name="contacts", + display_name="Contacts", + fields=[ + DataResourceField(name="id", editable=Editable.NEVER, visible_on=["list", "detail"]), + DataResourceField(name="email", field_type=FieldType.EMAIL, required=True), + ], + on_list=lambda: repo.list_all(), + on_get=lambda item_id: repo.get(item_id), + on_create=lambda data: repo.create(data), + on_update=lambda item_id, data: repo.update(item_id, data), + on_delete=lambda item_id: repo.delete(item_id), + ) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `name` | `str` | **required** | URL-safe resource identifier, e.g. 'contacts'. Lowercase letters, digits, underscores, and hyphens only; must start with a letter or digit. | +| `display_name` | `str` | '' | | +| `description` | `str` | '' | | +| `fields` | `list[data_resource.DataResourceField]` | — | | +| `read_only` | `bool` | False | | +| `importable` | `bool` | False | Enables CSV bulk import route | +| `on_list` | `typing.Callable[..., list[dict[str, typing.Any]]]` | `None` | | +| `on_get` | `typing.Callable[..., dict[str, typing.Any] | None]` | `None` | | +| `on_create` | `typing.Callable[..., dict[str, typing.Any]]` | `None` | | +| `on_update` | `typing.Callable[..., dict[str, typing.Any] | None]` | `None` | | +| `on_delete` | `typing.Callable[..., bool]` | `None` | | +| `on_import` | `typing.Callable[..., dict[str, typing.Any]]` | `None` | | + ### `job.Job` **Inherits from:** [`job.AbstractJob`](#jobabstractjob) @@ -164,6 +210,23 @@ _No additional fields beyond parent class._ _No additional fields beyond parent class._ +### `contracts.SupervaizerV2AgentRegistrationContract` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `supervaizer_contract_version` | `Literal[2]` | 2 | | +| `agent` | `V2AgentIdentity` | **required** | | +| `versions` | `V2ProtocolVersions` | **required** | | +| `a2a` | `V2A2AController` | **required** | | +| `capabilities` | `V2AgentCapabilities` | — | | +| `job_policy` | `V2JobPolicy` | — | | +| `resources` | `list[contracts.V2ResourceDefinition]` | — | | +| `datasets` | `list[contracts.V2DatasetDefinition]` | — | | + ### `case.Case` **Inherits from:** [`case.CaseAbstractModel`](#casecaseabstractmodel) @@ -188,6 +251,7 @@ _No additional fields beyond parent class._ | `total_cost` | `float` | 0.0 | | | `final_delivery` | `typing.Dict[str, typing.Any]` | `None` | | | `finished_at` | `datetime` | `None` | | +| `metadata` | `Dict[str, Any]` | — | Agent-provided domain metadata (e.g. contact context) | ### `case.CaseNode` @@ -222,12 +286,687 @@ Returns: | `name` | `str` | `None` | | | `payload` | `typing.Dict[str, typing.Any]` | `None` | | | `is_final` | `bool` | False | | +| `upsert` | `bool` | False | | | `error` | `str` | `None` | | | `scheduled_at` | `datetime` | `None` | | | `scheduled_method` | `str` | `None` | | | `scheduled_params` | `typing.Dict[str, typing.Any]` | `None` | | | `scheduled_status` | `str` | `None` | | +### `contracts.AgentMethodContract` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `name` | `str` | **required** | | +| `method` | `str` | **required** | | +| `params` | `dict[str, typing.Any]` | `None` | | +| `fields` | `list[supervaizer.contracts.AgentMethodFieldContract | dict[str, typing.Any]]` | `None` | | +| `description` | `str` | `None` | | +| `is_async` | `bool` | False | | +| `timeout` | `int` | 600 | | +| `nodes` | `dict[str, typing.Any]` | `None` | | + +### `contracts.AgentMethodFieldContract` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `name` | `str` | **required** | | +| `type` | `str` | `None` | | +| `field_type` | `str` | 'CharField' | | +| `description` | `str` | `None` | | +| `choices` | `list[typing.Any]` | `None` | | +| `default` | `Any` | `None` | | +| `widget` | `str` | `None` | | +| `required` | `bool` | False | | + +### `contracts.AgentMethodsContract` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `job_start` | `AgentMethodContract` | **required** | | +| `job_stop` | `AgentMethodContract` | `None` | | +| `job_status` | `AgentMethodContract` | `None` | | +| `human_answer` | `AgentMethodContract` | `None` | | +| `chat` | `AgentMethodContract` | `None` | | +| `custom` | `dict[str, supervaizer.contracts.AgentMethodContract]` | `None` | | + +### `contracts.AgentRegistrationContract` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +Minimal schema for agent registration payloads consumed by Studio. + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `id` | `str` | `None` | | +| `slug` | `str` | **required** | | +| `name` | `str` | **required** | | +| `api_path` | `str` | **required** | | +| `release_notes_url` | `str` | `None` | | +| `methods` | `AgentMethodsContract` \| `dict[str, typing.Any]` | — | | +| `parameters_setup` | `list[dict[str, Any]]` | — | | +| `data_resources` | `list[contracts.DataResourceContract | dict[str, Any]]` | — | | + +### `contracts.CaseUpdateEvent` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `name` | `str` | **required** | | +| `payload` | `dict[str, Any]` | — | | +| `cost` | `float` | 0.0 | | +| `index` | `int` | `None` | | +| `is_final` | `bool` | False | | + +### `contracts.CaseUpdateRequest` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `answer` | `dict[str, Any]` | **required** | | +| `message` | `str` | `None` | | + +### `contracts.ContractModel` + +Base class for SDK-owned wire contract models. + +_No fields found._ + +### `contracts.ControllerContract` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +Canonical controller surface advertised by a Supervaizer server. + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `controller_contract_version` | `str` | '1.0' | | +| `api_base_path` | `str` | '/api' | | +| `endpoints` | `dict[str, str]` | — | | + +### `contracts.DataResourceContextContract` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `workspace_id` | `str` | `None` | | +| `workspace_slug` | `str` | `None` | | +| `mission_id` | `str` | `None` | | +| `agent_slug` | `str` | `None` | | +| `request_id` | `str` | `None` | | + +### `contracts.DataResourceContract` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `name` | `str` | **required** | | +| `display_name` | `str` | **required** | | +| `description` | `str` | '' | | +| `fields` | `list[contracts.DataResourceFieldContract]` | — | | +| `read_only` | `bool` | False | | +| `importable` | `bool` | False | | +| `operations` | `dict[str, bool]` | — | | + +### `contracts.DataResourceFieldContract` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `name` | `str` | **required** | | +| `field_type` | `str` | 'string' | | +| `label` | `str` | `None` | | +| `required` | `bool` | False | | +| `editable` | `str` | 'always' | | +| `visible_on` | `list[str]` | — | | +| `description` | `str` | `None` | | +| `related_resource` | `str` | `None` | | +| `sensitive` | `bool` | False | | +| `display_label` | `str` | `None` | | + +### `contracts.DataResourceListResponse` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +Structured response shape for DataResource list operations. + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `items` | `list[dict[str, Any]]` | — | | + +### `contracts.JobStartRequest` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `job_context` | `dict[str, Any]` | **required** | | +| `job_fields` | `dict[str, Any]` | — | | +| `encrypted_agent_parameters` | `str` | `None` | | + +### `contracts.ServerRegistrationContract` + +**Inherits from:** [`contracts.ControllerContract`](#contractscontrollercontract) + +Minimal schema for server.register details. + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `server_id` | `str` | **required** | | +| `url` | `str` | **required** | | +| `uri` | `str` | **required** | | +| `api_version` | `str` | **required** | | +| `environment` | `str` | `None` | | +| `agents` | `list[contracts.AgentRegistrationContract]` | — | | + +### `contracts.V2A2AController` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `agent_card_url` | `str` | **required** | | +| `controller_url` | `str` | **required** | | +| `transport` | `V2A2ATransport` | — | | +| `external_interop` | `V2A2AExternalInterop` | — | | + +### `contracts.V2A2AExternalInterop` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `inbound_tasks` | `bool` | False | | +| `outbound_delegation` | `bool` | False | | + +### `contracts.V2A2ATransport` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `json_rpc` | `bool` | True | | +| `sse` | `bool` | True | | +| `push_notifications` | `bool` | False | | + +### `contracts.V2ActionRequest` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `request_id` | `str` | **required** | | +| `actor` | `V2ActorContext` | **required** | | +| `workspace` | `V2WorkspaceContext` | **required** | | +| `mission_id` | `str` | **required** | | +| `agent_slug` | `str` | **required** | | +| `surface` | `str` | **required** | | +| `action` | `str` | **required** | | +| `input` | `dict[str, Any]` | — | | +| `idempotency_key` | `str` | `None` | | +| `draft_session_id` | `str` | `None` | | +| `job_id` | `str` | `None` | | +| `case_id` | `str` | `None` | | +| `step_id` | `str` | `None` | | + +### `contracts.V2ActionResult` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `status` | `Literal['ok', 'error']` | **required** | | +| `effects` | `list[contracts.V2Effect]` | — | | + +### `contracts.V2ActorContext` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `user_id` | `str` | **required** | | + +### `contracts.V2AgentCapabilities` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `surfaces` | `list[str]` | — | | +| `actions` | `list[str]` | — | | +| `case_lanes` | `list[contracts.V2CaseLaneDefinition]` | — | | +| `artifact_types` | `list[contracts.V2ArtifactTypeDefinition]` | — | | + +### `contracts.V2AgentIdentity` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `id` | `str` | **required** | | +| `slug` | `str` | **required** | | +| `display_name` | `str` | **required** | | + +### `contracts.V2ArtifactRef` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `id` | `str` | **required** | | +| `type` | `str` | **required** | | +| `title` | `str` | `None` | | +| `external_id` | `str` | `None` | | +| `media_type` | `str` | `None` | | + +### `contracts.V2ArtifactTypeDefinition` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `type` | `str` | **required** | | +| `label` | `str` | **required** | | +| `renderer_surface` | `str` | `None` | | + +### `contracts.V2AwaitingFieldDefinition` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `id` | `str` | **required** | | +| `label` | `str` | **required** | | +| `type` | `str` | 'boolean' | | +| `required` | `bool` | False | | + +### `contracts.V2AwaitingState` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `reason` | `str` | **required** | | +| `surface` | `str` | **required** | | +| `action` | `str` | **required** | | +| `fields` | `list[contracts.V2AwaitingFieldDefinition]` | — | | + +### `contracts.V2CaseLaneDefinition` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `id` | `str` | **required** | | +| `label` | `str` | **required** | | +| `default` | `bool` | False | | + +### `contracts.V2CaseSnapshot` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `id` | `str` | **required** | | +| `lane` | `str` | 'work' | | +| `title` | `str` | `None` | | +| `status` | `str` | `None` | | +| `external_id` | `str` | `None` | | +| `steps` | `list[contracts.V2StepSnapshot]` | — | | + +### `contracts.V2DatasetDefinition` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `id` | `str` | **required** | | +| `label` | `str` | **required** | | +| `auto_surface` | `bool` | False | | + +### `contracts.V2Effect` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `type` | `str` | **required** | | + +### `contracts.V2JobPolicy` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `default_timeout_seconds` | `int` | `None` | | +| `offline_start_policy` | `Literal['block']` | 'block' | | +| `offline_running_policy` | `Literal['fail_in_studio']` | 'fail_in_studio' | | +| `sync` | `V2JobSyncPolicy` | `None` | | + +### `contracts.V2JobSnapshot` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `id` | `str` | **required** | | +| `agent_slug` | `str` | **required** | | +| `mission_id` | `str` | **required** | | +| `status` | `str` | **required** | | +| `source` | `V2JobSource` | **required** | | + +### `contracts.V2JobSource` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `type` | `Literal['fresh_start', 'external']` | **required** | | +| `external_ref` | `str` | `None` | | +| `previous_job_id` | `str` | `None` | | +| `target_type` | `str` | `None` | | + +### `contracts.V2JobStateSnapshot` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `job` | `V2JobSnapshot` | **required** | | +| `cases` | `list[contracts.V2CaseSnapshot]` | — | | + +### `contracts.V2JobSyncPolicy` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `action` | `str` | 'job.sync' | | +| `supported_statuses` | `list[str]` | — | | + +### `contracts.V2JobSyncResult` + +**Inherits from:** [`contracts.V2ActionResult`](#contractsv2actionresult) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `external_ref` | `str` | `None` | | +| `external_version` | `str` | `None` | | +| `sync_cursor` | `str` | `None` | | +| `observed_at` | `str` | `None` | | +| `job_state` | `V2JobStateSnapshot` | `None` | | + +### `contracts.V2MountedResourceViewDefinition` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `view` | `str` | **required** | | +| `surface` | `str` | **required** | | + +### `contracts.V2ProtocolVersions` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `a2ui_version` | `str` | **required** | | +| `a2ui_catalog_version` | `str` | **required** | | +| `a2a_version` | `str` | **required** | | +| `ag_ui_version` | `str` | `None` | | + +### `contracts.V2ReplaySafetyMetadata` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `dedupe_keys` | `list[str]` | — | | +| `stable_external_ids_required` | `bool` | True | | +| `strictly_idempotent_response` | `bool` | False | | +| `convergent` | `bool` | True | | + +### `contracts.V2ResourceDefinition` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `id` | `str` | **required** | | +| `label` | `str` | **required** | | +| `auto_surface` | `bool` | False | | +| `operations` | `list[str]` | — | | +| `display` | `V2ResourceDisplayDefinition` | `None` | | +| `fields` | `list[contracts.V2ResourceFieldDefinition]` | — | | +| `mounted_views` | `list[contracts.V2MountedResourceViewDefinition]` | — | | + +### `contracts.V2ResourceDisplayDefinition` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `title_field` | `str` | `None` | | +| `columns` | `list[str]` | — | | +| `search_fields` | `list[str]` | — | | + +### `contracts.V2ResourceFieldDefinition` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `id` | `str` | **required** | | +| `label` | `str` | **required** | | +| `type` | `str` | 'string' | | +| `required` | `bool` | False | | +| `read_only` | `bool` | False | | +| `multiline` | `bool` | False | | +| `options_source` | `V2ResourceFieldOptionsSource` | `None` | | + +### `contracts.V2ResourceFieldOptionsSource` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `type` | `Literal['resource']` | 'resource' | | +| `resource` | `str` | **required** | | +| `value_field` | `str` | 'id' | | +| `label_field` | `str` | `None` | | + +### `contracts.V2StepSnapshot` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `id` | `str` | **required** | | +| `activity` | `Literal['operation', 'delegation']` | **required** | | +| `status` | `str` | **required** | | +| `title` | `str` | `None` | | +| `external_id` | `str` | `None` | | +| `awaiting` | `V2AwaitingState` | `None` | | +| `outputs` | `list[contracts.V2ArtifactRef]` | — | | + +### `contracts.V2SurfaceRequest` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `request_id` | `str` | **required** | | +| `actor` | `V2ActorContext` | **required** | | +| `workspace` | `V2WorkspaceContext` | **required** | | +| `mission_id` | `str` | **required** | | +| `agent_slug` | `str` | **required** | | +| `surface` | `str` | **required** | | +| `input` | `dict[str, Any]` | — | | +| `draft_session_id` | `str` | `None` | | +| `job_id` | `str` | `None` | | +| `case_id` | `str` | `None` | | +| `step_id` | `str` | `None` | | + +### `contracts.V2SurfaceResult` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `surface` | `str` | **required** | | +| `a2ui_version` | `str` | `None` | | +| `a2ui_catalog_version` | `str` | `None` | | +| `document` | `dict[str, Any]` | — | | + +### `contracts.V2WorkspaceContext` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `id` | `str` | **required** | | +| `slug` | `str` | `None` | | + +### `data_resource.DataResourceContext` + +**Inherits from:** [`common.SvBaseModel`](#commonsvbasemodel) + +Studio request context passed to DataResource callbacks. + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `workspace_id` | `str` | `None` | | +| `workspace_slug` | `str` | `None` | | +| `mission_id` | `str` | `None` | | +| `agent_slug` | `str` | **required** | | +| `request_id` | `str` | `None` | | + +### `data_resource.DataResourceField` + +**Inherits from:** [`common.SvBaseModel`](#commonsvbasemodel) + +Describes a single field in a DataResource for Studio rendering. + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `name` | `str` | **required** | Column/attribute name | +| `field_type` | `` | `string` | One of: string, integer, boolean, date, datetime, text, email, url | +| `label` | `str` | `None` | Human-readable label; defaults to name.title() | +| `required` | `bool` | False | Required on create form | +| `editable` | `` | `always` | | +| `visible_on` | `list[str]` | — | Views that render this field: list, detail, create, edit | +| `description` | `str` | `None` | Help text shown in Studio | +| `related_resource` | `str` | `None` | Name of another DataResource this field FK-references | +| `sensitive` | `bool` | False | True when Studio should mask this field for non-manager users | + ### `deploy.drivers.base.DeploymentPlan` Deployment plan containing all actions to be taken. @@ -420,6 +1159,7 @@ _No additional fields beyond parent class._ | `created_at` | `datetime` | `None` | | | `agent_parameters` | `list[dict[str, typing.Any]]` | `None` | | | `case_ids` | `list[str]` | [] | | +| `metadata` | `dict[str, Any]` | — | Agent-provided domain metadata (e.g. campaign context) | ### `job.JobInstructions` @@ -436,6 +1176,44 @@ _No additional fields beyond parent class._ | `stop_on_error` | `bool` | True | | | `job_start_time` | `float` | `None` | | +### `protocol.a2a.controller.JsonRpcError` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `code` | `int` | **required** | | +| `message` | `str` | **required** | | +| `data` | `dict[str, typing.Any]` | `None` | | + +### `protocol.a2a.controller.JsonRpcRequest` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `jsonrpc` | `Literal['2.0']` | '2.0' | | +| `id` | `str` \| `int` | `None` | | +| `method` | `str` | **required** | | +| `params` | `dict[str, Any]` | — | | + +### `protocol.a2a.controller.JsonRpcResponse` + +**Inherits from:** [`contracts.ContractModel`](#contractscontractmodel) + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `jsonrpc` | `Literal['2.0']` | '2.0' | | +| `id` | `str` \| `int` | `None` | | +| `result` | `dict[str, typing.Any]` | `None` | | +| `error` | `JsonRpcError` | `None` | | + ### `routes.CaseUpdateRequest` **Inherits from:** [`common.SvBaseModel`](#commonsvbasemodel) @@ -446,7 +1224,7 @@ Request model for updating a case with answer to a question. | Field | Type | Default | Description | |---|---|---|---| -| `answer` | `Dict[str, Any]` | **required** | | +| `answer` | `dict[str, Any]` | **required** | | | `message` | `str` | `None` | | ### `server_utils.ErrorResponse` @@ -458,9 +1236,22 @@ Standard error response model | `error` | `str` | **required** | | | `error_type` | `` | **required** | | | `detail` | `str` | `None` | | -| `timestamp` | `datetime` | datetime.datetime(2026, 4, 9, 0, 25, 25, 819185) | | +| `timestamp` | `datetime` | datetime.datetime(2026, 5, 15, 20, 25, 31, 892520) | | | `status_code` | `int` | **required** | | +### `routes.RegistrationRefreshRequest` + +**Inherits from:** [`common.SvBaseModel`](#commonsvbasemodel) + +Request model for re-sending the server registration event. + +#### Model Fields + +| Field | Type | Default | Description | +|---|---|---|---| +| `reason` | `str` | `None` | | +| `requested_at` | `str` | `None` | | + ### `server.ServerInfo` Complete server information for storage. @@ -490,4 +1281,4 @@ A base class for creating Pydantic models. | `details` | `Dict[str, Any]` | **required** | | -*Uploaded on 2026-04-09 00:25:26* +*Uploaded on 2026-05-15 20:25:31* diff --git a/docs/rfc/001-cloud-deployment-cli.md b/docs/rfc/2025_10_001-cloud-deployment-cli.md similarity index 98% rename from docs/rfc/001-cloud-deployment-cli.md rename to docs/rfc/2025_10_001-cloud-deployment-cli.md index 36f42b7..defe233 100644 --- a/docs/rfc/001-cloud-deployment-cli.md +++ b/docs/rfc/2025_10_001-cloud-deployment-cli.md @@ -1,5 +1,9 @@ # RFC-001: Cloud Deployment CLI + +> **Created:** 2025-10-06 +> **Updated:** 2026-03-23 + **Status:** Revised Draft (v1 – Fully Automated) ## Abstract @@ -81,7 +85,7 @@ Set for all platforms: - `SUPERVAIZER_PORT` = `--port` - `SV_LOG_LEVEL=INFO` (default) - `SUPERVAIZER_API_KEY` – stored in provider secret store (generated if `--generate-api-key`) -- `ADMIN_ALLOWED_IPS` (optional) – comma-separated IPv4/IPv6 addresses and/or CIDR ranges allowed to access the `/admin` web UI; if unset or empty, all IPs are allowed (see `docs/ADMIN_README.md`). Uses the first hop in `X-Forwarded-For` when present. +- `ADMIN_ALLOWED_IPS` (optional) – comma-separated IPv4/IPv6 addresses and/or CIDR ranges allowed to access the `/admin` web UI; if unset or empty, all IPs are allowed (see `../2025_08_ADMIN_README.md`). Uses the first hop in `X-Forwarded-For` when present. - **RSA** (choose one): - `SV_RSA_PRIVATE_KEY` (secret value), or - `SV_RSA_PRIVATE_KEY_PATH` (if platform supports volumes) @@ -406,7 +410,7 @@ All deployment artifacts are stored under `.deployment/` directory (added to `.g - ✅ Error handling and cleanup on failure 4. **Local Testing Documentation** ✅ - - ✅ Created comprehensive LOCAL_TESTING.md guide + - ✅ Created comprehensive 2025_10_LOCAL_TESTING.md guide - ✅ Added usage examples and troubleshooting - ✅ Documented environment variables and configuration - ✅ Provided cleanup and debugging instructions diff --git a/docs/rfc/002-async-http-client.md b/docs/rfc/2026_04_002-async-http-client.md similarity index 99% rename from docs/rfc/002-async-http-client.md rename to docs/rfc/2026_04_002-async-http-client.md index 9f0f8cd..0b6139a 100644 --- a/docs/rfc/002-async-http-client.md +++ b/docs/rfc/2026_04_002-async-http-client.md @@ -1,5 +1,9 @@ # RFC-002: Async HTTP Client for `account_service.send_event` + +> **Created:** 2026-04-27 +> **Updated:** 2026-04-27 + **Status:** Proposed **Date:** 2026-04-27 **Affects:** `supervaizer` SDK (published PyPI package) diff --git a/docs/superpowers/plans/2026-03-16-manage-hello-world.md b/docs/superpowers/plans/2026_03_2026-03-16-manage-hello-world.md similarity index 99% rename from docs/superpowers/plans/2026-03-16-manage-hello-world.md rename to docs/superpowers/plans/2026_03_2026-03-16-manage-hello-world.md index 2421c42..2b20730 100644 --- a/docs/superpowers/plans/2026-03-16-manage-hello-world.md +++ b/docs/superpowers/plans/2026_03_2026-03-16-manage-hello-world.md @@ -1,5 +1,9 @@ # Manage Hello World in Local Mode — Implementation Plan + +> **Created:** 2026-03-16 +> **Updated:** 2026-03-16 + > **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Make `supervaizer start --local` run user agents alongside the Hello World agent, with the ability to disable Hello World via env var. @@ -8,7 +12,7 @@ **Tech Stack:** Python, Typer (CLI), FastAPI (Server), pytest -**Spec:** `docs/superpowers/specs/2026-03-16-manage-hello-world-design.md` +**Spec:** `docs/superpowers/specs/2026_03_2026-03-16-manage-hello-world-design.md` --- diff --git a/docs/superpowers/plans/2026-04-08-dynamic-choices.md b/docs/superpowers/plans/2026_04_2026-04-08-dynamic-choices.md similarity index 99% rename from docs/superpowers/plans/2026-04-08-dynamic-choices.md rename to docs/superpowers/plans/2026_04_2026-04-08-dynamic-choices.md index 4ab473b..8c3fd6f 100644 --- a/docs/superpowers/plans/2026-04-08-dynamic-choices.md +++ b/docs/superpowers/plans/2026_04_2026-04-08-dynamic-choices.md @@ -1,5 +1,9 @@ # Dynamic Choices for AgentMethodField — Implementation Plan + +> **Created:** 2026-04-09 +> **Updated:** 2026-04-09 + > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Allow AgentMethodField to declare dynamic choices that are resolved at runtime via a callback on the Agent, exposed through a new API endpoint that Supervaize Studio calls when rendering job-start forms. diff --git a/docs/superpowers/specs/2026-03-16-manage-hello-world-design.md b/docs/superpowers/specs/2026_03_2026-03-16-manage-hello-world-design.md similarity index 98% rename from docs/superpowers/specs/2026-03-16-manage-hello-world-design.md rename to docs/superpowers/specs/2026_03_2026-03-16-manage-hello-world-design.md index 0f1ecba..3df79df 100644 --- a/docs/superpowers/specs/2026-03-16-manage-hello-world-design.md +++ b/docs/superpowers/specs/2026_03_2026-03-16-manage-hello-world-design.md @@ -1,5 +1,9 @@ # Design: `--local` Mode with User Agents + Hello World + +> **Created:** 2026-03-16 +> **Updated:** 2026-03-16 + ## Problem `supervaizer start --local` currently ignores `supervaizer_control.py` entirely and runs a separate code path with only the built-in Hello World agent. Users with existing agent setups cannot see their agents alongside Hello World in local mode. diff --git a/src/supervaizer/__init__.py b/src/supervaizer/__init__.py index 32a0677..19c2875 100644 --- a/src/supervaizer/__init__.py +++ b/src/supervaizer/__init__.py @@ -65,6 +65,19 @@ "TelemetryCategory": ("supervaizer.telemetry", "TelemetryCategory"), "TelemetrySeverity": ("supervaizer.telemetry", "TelemetrySeverity"), "TelemetryType": ("supervaizer.telemetry", "TelemetryType"), + "API_VERSION": ("supervaizer.contracts", "API_VERSION"), + "SUPERVAIZER_V2_A2A_VERSION": ( + "supervaizer.contracts", + "SUPERVAIZER_V2_A2A_VERSION", + ), + "SUPERVAIZER_V2_A2UI_VERSION": ( + "supervaizer.contracts", + "SUPERVAIZER_V2_A2UI_VERSION", + ), + "SUPERVAIZER_V2_CONTRACT_VERSION": ( + "supervaizer.contracts", + "SUPERVAIZER_V2_CONTRACT_VERSION", + ), "AgentMethodContract": ("supervaizer.contracts", "AgentMethodContract"), "AgentMethodsContract": ("supervaizer.contracts", "AgentMethodsContract"), "AgentRegistrationContract": ("supervaizer.contracts", "AgentRegistrationContract"), @@ -72,18 +85,99 @@ "ControllerEndpoint": ("supervaizer.contracts", "ControllerEndpoint"), "DataResourceContract": ("supervaizer.contracts", "DataResourceContract"), "DataResourceFieldContract": ("supervaizer.contracts", "DataResourceFieldContract"), - "DynamicChoicesRequest": ("supervaizer.contracts", "DynamicChoicesRequest"), - "DynamicChoicesResponse": ("supervaizer.contracts", "DynamicChoicesResponse"), "EventType": ("supervaizer.contracts", "EventType"), "JobStartRequest": ("supervaizer.contracts", "JobStartRequest"), "ServerRegistrationContract": ( "supervaizer.contracts", "ServerRegistrationContract", ), + "SupervaizerV2AgentRegistrationContract": ( + "supervaizer.contracts", + "SupervaizerV2AgentRegistrationContract", + ), + "V2A2AController": ("supervaizer.contracts", "V2A2AController"), + "V2A2AExternalInterop": ("supervaizer.contracts", "V2A2AExternalInterop"), + "V2A2ATransport": ("supervaizer.contracts", "V2A2ATransport"), + "V2ActionRequest": ("supervaizer.contracts", "V2ActionRequest"), + "V2ActionResult": ("supervaizer.contracts", "V2ActionResult"), + "V2A2UIResourceImportColumn": ( + "supervaizer.contracts", + "V2A2UIResourceImportColumn", + ), + "V2A2UIResourceImportDocument": ( + "supervaizer.contracts", + "V2A2UIResourceImportDocument", + ), + "V2A2UISubmitDefinition": ("supervaizer.contracts", "V2A2UISubmitDefinition"), + "V2AgentCapabilities": ("supervaizer.contracts", "V2AgentCapabilities"), + "V2AgentIdentity": ("supervaizer.contracts", "V2AgentIdentity"), + "V2ArtifactRef": ("supervaizer.contracts", "V2ArtifactRef"), + "V2ArtifactTypeDefinition": ( + "supervaizer.contracts", + "V2ArtifactTypeDefinition", + ), + "V2AwaitingFieldDefinition": ( + "supervaizer.contracts", + "V2AwaitingFieldDefinition", + ), + "V2AwaitingState": ("supervaizer.contracts", "V2AwaitingState"), + "V2CaseLaneDefinition": ("supervaizer.contracts", "V2CaseLaneDefinition"), + "V2CaseSnapshot": ("supervaizer.contracts", "V2CaseSnapshot"), + "V2DashboardDefinition": ("supervaizer.contracts", "V2DashboardDefinition"), + "V2DashboardWidgetDataRef": ( + "supervaizer.contracts", + "V2DashboardWidgetDataRef", + ), + "V2DashboardWidgetDefinition": ( + "supervaizer.contracts", + "V2DashboardWidgetDefinition", + ), + "V2DashboardWidgetVisualization": ( + "supervaizer.contracts", + "V2DashboardWidgetVisualization", + ), + "V2DatasetDefinition": ("supervaizer.contracts", "V2DatasetDefinition"), + "V2Effect": ("supervaizer.contracts", "V2Effect"), + "V2JobPolicy": ("supervaizer.contracts", "V2JobPolicy"), + "V2JobSyncPolicy": ("supervaizer.contracts", "V2JobSyncPolicy"), + "V2JobSnapshot": ("supervaizer.contracts", "V2JobSnapshot"), + "V2JobSource": ("supervaizer.contracts", "V2JobSource"), + "V2JobStateSnapshot": ("supervaizer.contracts", "V2JobStateSnapshot"), + "V2JobSyncResult": ("supervaizer.contracts", "V2JobSyncResult"), + "V2MountedResourceViewDefinition": ( + "supervaizer.contracts", + "V2MountedResourceViewDefinition", + ), + "V2ProtocolVersions": ("supervaizer.contracts", "V2ProtocolVersions"), + "V2ReplaySafetyMetadata": ( + "supervaizer.contracts", + "V2ReplaySafetyMetadata", + ), + "V2ResourceDefinition": ("supervaizer.contracts", "V2ResourceDefinition"), + "V2ResourceDisplayDefinition": ( + "supervaizer.contracts", + "V2ResourceDisplayDefinition", + ), + "V2ResourceFieldDefinition": ( + "supervaizer.contracts", + "V2ResourceFieldDefinition", + ), + "V2ResourceFieldOptionsSource": ( + "supervaizer.contracts", + "V2ResourceFieldOptionsSource", + ), + "V2StepSnapshot": ("supervaizer.contracts", "V2StepSnapshot"), + "V2SurfaceRequest": ("supervaizer.contracts", "V2SurfaceRequest"), + "V2SurfaceResult": ("supervaizer.contracts", "V2SurfaceResult"), + "V2WorkspaceContext": ("supervaizer.contracts", "V2WorkspaceContext"), "build_data_resource_context_headers": ( "supervaizer.contracts", "build_data_resource_context_headers", ), + "build_v2_agent_registration": ( + "supervaizer.contracts", + "build_v2_agent_registration", + ), "controller_contract_info": ("supervaizer.contracts", "controller_contract_info"), "resolve_controller_endpoint": ( "supervaizer.contracts", diff --git a/src/supervaizer/__version__.py b/src/supervaizer/__version__.py index 2729d51..39ba7ce 100644 --- a/src/supervaizer/__version__.py +++ b/src/supervaizer/__version__.py @@ -4,13 +4,6 @@ # If a copy of the MPL was not distributed with this file, you can obtain one at # https://mozilla.org/MPL/2.0/. -# Copyright (c) 2024-2025 Alain Prasquier - Supervaize.com. All rights reserved. -# -# This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. -# If a copy of the MPL was not distributed with this file, you can obtain one at -# https://mozilla.org/MPL/2.0/. - VERSION = "0.20.1" -API_VERSION = "v1" -TELEMETRY_VERSION = "v1" +__version__ = VERSION diff --git a/src/supervaizer/access/__init__.py b/src/supervaizer/access/__init__.py index b487348..43e953f 100644 --- a/src/supervaizer/access/__init__.py +++ b/src/supervaizer/access/__init__.py @@ -4,7 +4,7 @@ # If a copy of the MPL was not distributed with this file, you can obtain one at # https://mozilla.org/MPL/2.0/. -# Copyright (c) 2024-2025 Alain Prasquier - Supervaize.com. All rights reserved. +# Copyright (c) 2024-2026 Alain Prasquier - Supervaize.com. All rights reserved. # # This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. # If a copy of the MPL was not distributed with this file, you can obtain one at diff --git a/src/supervaizer/access/api_auth.py b/src/supervaizer/access/api_auth.py index af1ad47..58c0309 100644 --- a/src/supervaizer/access/api_auth.py +++ b/src/supervaizer/access/api_auth.py @@ -4,7 +4,7 @@ # If a copy of the MPL was not distributed with this file, you can obtain one at # https://mozilla.org/MPL/2.0/. -# Copyright (c) 2024-2025 Alain Prasquier - Supervaize.com. All rights reserved. +# Copyright (c) 2024-2026 Alain Prasquier - Supervaize.com. All rights reserved. # # This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. # If a copy of the MPL was not distributed with this file, you can obtain one at diff --git a/src/supervaizer/access/client_ip.py b/src/supervaizer/access/client_ip.py index 4dd3b9c..28a38a7 100644 --- a/src/supervaizer/access/client_ip.py +++ b/src/supervaizer/access/client_ip.py @@ -4,7 +4,7 @@ # If a copy of the MPL was not distributed with this file, you can obtain one at # https://mozilla.org/MPL/2.0/. -# Copyright (c) 2024-2025 Alain Prasquier - Supervaize.com. All rights reserved. +# Copyright (c) 2024-2026 Alain Prasquier - Supervaize.com. All rights reserved. # # This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. # If a copy of the MPL was not distributed with this file, you can obtain one at diff --git a/src/supervaizer/access/tailscale.py b/src/supervaizer/access/tailscale.py index 48ecd3f..9ec855d 100644 --- a/src/supervaizer/access/tailscale.py +++ b/src/supervaizer/access/tailscale.py @@ -4,7 +4,7 @@ # If a copy of the MPL was not distributed with this file, you can obtain one at # https://mozilla.org/MPL/2.0/. -# Copyright (c) 2024-2025 Alain Prasquier - Supervaize.com. All rights reserved. +# Copyright (c) 2024-2026 Alain Prasquier - Supervaize.com. All rights reserved. # # This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. # If a copy of the MPL was not distributed with this file, you can obtain one at diff --git a/src/supervaizer/account.py b/src/supervaizer/account.py index 0d49078..4afe77f 100644 --- a/src/supervaizer/account.py +++ b/src/supervaizer/account.py @@ -4,14 +4,14 @@ # If a copy of the MPL was not distributed with this file, you can obtain one at # https://mozilla.org/MPL/2.0/. -# Copyright (c) 2024-2025 Alain Prasquier - Supervaize.com. All rights reserved. +# Copyright (c) 2024-2026 Alain Prasquier - Supervaize.com. All rights reserved. # # This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. # If a copy of the MPL was not distributed with this file, you can obtain one at # https://mozilla.org/MPL/2.0/. -from typing import TYPE_CHECKING, Any, ClassVar, Dict, Optional, Union, cast +from typing import TYPE_CHECKING, Any, ClassVar, Union, cast import httpx from pydantic import ConfigDict, Field, field_validator @@ -118,7 +118,7 @@ def api_url_w_v1(self) -> str: return f"{self.api_url}/w/{self.workspace_id}/api/v1" @property - def api_headers(self) -> Dict[str, str]: + def api_headers(self) -> dict[str, str]: """Headers for the Supervaize Control API. Tested in tests/test_account.py """ @@ -243,7 +243,7 @@ def _create_api_result( message: str, detail: Any = None, url: str = "", - exception: Optional[Exception] = None, + exception: Exception | None = None, ) -> ApiResult: if success: return ApiSuccess(message=message, detail=detail) diff --git a/src/supervaizer/account_service.py b/src/supervaizer/account_service.py index 7bda2ba..7939fd6 100644 --- a/src/supervaizer/account_service.py +++ b/src/supervaizer/account_service.py @@ -4,7 +4,7 @@ # If a copy of the MPL was not distributed with this file, you can obtain one at # https://mozilla.org/MPL/2.0/. -# Copyright (c) 2024-2025 Alain Prasquier - Supervaize.com. All rights reserved. +# Copyright (c) 2024-2026 Alain Prasquier - Supervaize.com. All rights reserved. # # This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. # If a copy of the MPL was not distributed with this file, you can obtain one at diff --git a/src/supervaizer/admin/ip_allowlist.py b/src/supervaizer/admin/ip_allowlist.py index f3d4af1..6f6b81c 100644 --- a/src/supervaizer/admin/ip_allowlist.py +++ b/src/supervaizer/admin/ip_allowlist.py @@ -4,7 +4,7 @@ # If a copy of the MPL was not distributed with this file, you can obtain one at # https://mozilla.org/MPL/2.0/. -# Copyright (c) 2024-2025 Alain Prasquier - Supervaize.com. All rights reserved. +# Copyright (c) 2024-2026 Alain Prasquier - Supervaize.com. All rights reserved. # # This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. # If a copy of the MPL was not distributed with this file, you can obtain one at diff --git a/src/supervaizer/admin/routes.py b/src/supervaizer/admin/routes.py index 0e052fd..7382e09 100644 --- a/src/supervaizer/admin/routes.py +++ b/src/supervaizer/admin/routes.py @@ -4,7 +4,7 @@ # If a copy of the MPL was not distributed with this file, you can obtain one at # https://mozilla.org/MPL/2.0/. -# Copyright (c) 2024-2025 Alain Prasquier - Supervaize.com. All rights reserved. +# Copyright (c) 2024-2026 Alain Prasquier - Supervaize.com. All rights reserved. # # This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. # If a copy of the MPL was not distributed with this file, you can obtain one at @@ -31,8 +31,9 @@ from pydantic import BaseModel from sse_starlette.sse import EventSourceResponse -from supervaizer.__version__ import API_VERSION, VERSION +from supervaizer.__version__ import VERSION from supervaizer.common import log +from supervaizer.contracts import API_VERSION from supervaizer.lifecycle import EntityStatus from supervaizer.storage import ( StorageManager, diff --git a/src/supervaizer/admin/static/js/workbench-form.js b/src/supervaizer/admin/static/js/workbench-form.js index 028088e..43c875a 100644 --- a/src/supervaizer/admin/static/js/workbench-form.js +++ b/src/supervaizer/admin/static/js/workbench-form.js @@ -122,35 +122,6 @@ class WorkbenchForm { } } - async pollJob() { - if (!this.activeJobId) return; - const btn = document.getElementById('btn-poll'); - if (btn) { - btn.disabled = true; - btn.classList.add('opacity-50'); - } - try { - const response = await fetch(`${this.basePath}/jobs/${this.activeJobId}/poll`, { - method: 'POST', - headers: { 'X-API-Key': this.getApiKey() }, - }); - const result = await response.json(); - if (!response.ok) { - this.onError(result.detail || 'Poll failed'); - } else { - this.onError(''); - this.refreshMonitor(true); - } - } catch (e) { - this.onError(`Network error: ${e.message}`); - } finally { - if (btn) { - btn.disabled = false; - btn.classList.remove('opacity-50'); - } - } - } - async executeStepNow(caseId, stepIndex) { if (!this.activeJobId) return; try { @@ -298,18 +269,15 @@ class WorkbenchForm { await this._postAnswer(caseId, { action: 'confirm' }); } - /** Show/hide Stop, Poll, and Status buttons based on active job. */ + /** Show/hide Stop and Status buttons based on active job. */ _updateButtons(terminal) { const stop = document.getElementById('btn-stop'); const status = document.getElementById('btn-status'); - const poll = document.getElementById('btn-poll'); if (this.activeJobId && !terminal) { if (stop) stop.classList.remove('hidden'); if (status) status.classList.remove('hidden'); - if (poll) poll.classList.remove('hidden'); } else { if (stop) stop.classList.add('hidden'); - if (poll) poll.classList.add('hidden'); if (status) status.classList.remove('hidden'); } } diff --git a/src/supervaizer/admin/templates/workbench.html b/src/supervaizer/admin/templates/workbench.html index 3e898f6..4227124 100644 --- a/src/supervaizer/admin/templates/workbench.html +++ b/src/supervaizer/admin/templates/workbench.html @@ -160,21 +160,6 @@

Jo Start Job - {# Poll button — visible only when agent has job_poll #} - {% if has_poll %} - - {% endif %} - {# Stop button #}