mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-15 10:38:52 +08:00
Compare commits
603 Commits
codex/code
...
refactor/s
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
478b599e9b | ||
|
|
0b0edcdf1c | ||
|
|
57c88dd46e | ||
|
|
654de643e4 | ||
|
|
ee2b90b4e2 | ||
|
|
f59fc0d477 | ||
|
|
1cab722fe0 | ||
|
|
4739f0cfe2 | ||
|
|
2442e9c178 | ||
|
|
0ac61072b8 | ||
|
|
31099ccb1f | ||
|
|
2d23519c77 | ||
|
|
bbd2854c45 | ||
|
|
5d3a6909fb | ||
|
|
1e0c9d8174 | ||
|
|
4c16bd2453 | ||
|
|
cd3d960ec5 | ||
|
|
d93394e29b | ||
|
|
83dff5855e | ||
|
|
3402477314 | ||
|
|
71b3bc87ca | ||
|
|
0be3ef5a38 | ||
|
|
287687da20 | ||
|
|
22e4289d3f | ||
|
|
5367ef7bd3 | ||
|
|
598e177e12 | ||
|
|
0ed9fb48c4 | ||
|
|
3ea911558c | ||
|
|
443255461c | ||
|
|
7dde396d4d | ||
|
|
89975eea24 | ||
|
|
dbd3e10312 | ||
|
|
8b50cdd151 | ||
|
|
a825b5576b | ||
|
|
76b300babc | ||
|
|
ada22739be | ||
|
|
8fe50a2136 | ||
|
|
b374505e7a | ||
|
|
653292901a | ||
|
|
3f50485156 | ||
|
|
9c2744f1e1 | ||
|
|
3aa460409e | ||
|
|
48980a0f41 | ||
|
|
eb170a0adb | ||
|
|
b7232db1b0 | ||
|
|
a20b2dc740 | ||
|
|
c6b1fede5a | ||
|
|
c80ec43325 | ||
|
|
b6891d284d | ||
|
|
ec78a21e0b | ||
|
|
be3af54f98 | ||
|
|
3fc0df953c | ||
|
|
4ac90a5b48 | ||
|
|
39e987314a | ||
|
|
427df01d4e | ||
|
|
50b7a2ffa1 | ||
|
|
b93ed3f93f | ||
|
|
a2b2c4a76c | ||
|
|
a9a86f788b | ||
|
|
371a8abe9d | ||
|
|
005da57957 | ||
|
|
d11e82aeea | ||
|
|
adcac404e1 | ||
|
|
eb5e80f58a | ||
|
|
5891cfec3e | ||
|
|
961691def2 | ||
|
|
2780f540f8 | ||
|
|
37058ad75a | ||
|
|
37c6e2dfa0 | ||
|
|
473993f73a | ||
|
|
e24a9c5457 | ||
|
|
d9c0d09f1a | ||
|
|
0c7ab411e5 | ||
|
|
5811693c7f | ||
|
|
445ff22018 | ||
|
|
602364f1c7 | ||
|
|
c73e8eedf4 | ||
|
|
dcc329ac09 | ||
|
|
515d4ffc21 | ||
|
|
28290a496f | ||
|
|
3cd368edec | ||
|
|
908fc35b97 | ||
|
|
d6d1cc2a3e | ||
|
|
41044a207c | ||
|
|
7d19f89094 | ||
|
|
43e4b9dc1c | ||
|
|
77c6bee421 | ||
|
|
0b49710e8d | ||
|
|
3a9e7dfa1a | ||
|
|
e4905ce4c9 | ||
|
|
131e662924 | ||
|
|
7051bf16f0 | ||
|
|
6eb6730137 | ||
|
|
2383cfd303 | ||
|
|
c09e1efe99 | ||
|
|
308fdbe7fb | ||
|
|
c5af09e378 | ||
|
|
3037646d22 | ||
|
|
3ea82adf97 | ||
|
|
bc6d570659 | ||
|
|
f7729028ae | ||
|
|
11d6ce15e8 | ||
|
|
897a7efe15 | ||
|
|
fafa4c8b65 | ||
|
|
186182fe9e | ||
|
|
e5455b61c3 | ||
|
|
e89417d77b | ||
|
|
e9b0a5f69e | ||
|
|
339e212c85 | ||
|
|
199cdc1052 | ||
|
|
ab0613c9d3 | ||
|
|
91ba5fd4fe | ||
|
|
9da7498d31 | ||
|
|
67298c4bd8 | ||
|
|
9417a3f39f | ||
|
|
1609fcaff3 | ||
|
|
5205b94d84 | ||
|
|
7f48ee1e57 | ||
|
|
c4be8d8730 | ||
|
|
bc1c3701c4 | ||
|
|
4e8b74568f | ||
|
|
b80dcbd650 | ||
|
|
417aba7b9b | ||
|
|
ed63523db9 | ||
|
|
677f7c80dc | ||
|
|
231d0b28bd | ||
|
|
979907e004 | ||
|
|
9eb17a0277 | ||
|
|
06e0fd3347 | ||
|
|
51cceaf70c | ||
|
|
471164afbd | ||
|
|
99ce71ddbb | ||
|
|
9cb9851bf8 | ||
|
|
2b31c02163 | ||
|
|
878e433d81 | ||
|
|
dfbed5053a | ||
|
|
caac9733a7 | ||
|
|
6399b6a445 | ||
|
|
472606de9b | ||
|
|
177496552b | ||
|
|
e0248fc11f | ||
|
|
6a753ade78 | ||
|
|
53812bd8aa | ||
|
|
fe3c3ac5cd | ||
|
|
5435b453ca | ||
|
|
abc26b072b | ||
|
|
64533bab65 | ||
|
|
7d4bf8f285 | ||
|
|
bdb0fde0ea | ||
|
|
926a165a52 | ||
|
|
70b6fdd149 | ||
|
|
9ad7f5bbde | ||
|
|
1ee751ddb1 | ||
|
|
30e3ca08a5 | ||
|
|
1f6c1eacf0 | ||
|
|
8654353be8 | ||
|
|
c5aa3ff02f | ||
|
|
5fde637ba8 | ||
|
|
044f5a814e | ||
|
|
3ae521745e | ||
|
|
f89f5d930f | ||
|
|
13c77f00c3 | ||
|
|
3b8ab4e112 | ||
|
|
ca4a12381a | ||
|
|
86e33d6985 | ||
|
|
9ef699fedc | ||
|
|
912a276ca1 | ||
|
|
6f20f29688 | ||
|
|
b6d253eefb | ||
|
|
0a87f6e4ad | ||
|
|
bc77f7a00a | ||
|
|
9e3d5310cc | ||
|
|
4d9366fecb | ||
|
|
1c9851e115 | ||
|
|
a4f62400a7 | ||
|
|
8d3fe21b53 | ||
|
|
becd45325b | ||
|
|
84a965a1a2 | ||
|
|
f4d461bbff | ||
|
|
cbad1b6e69 | ||
|
|
f4cd5e4050 | ||
|
|
0e7773d1a6 | ||
|
|
d8e7734d27 | ||
|
|
da7fb64aa4 | ||
|
|
3fffb34ba0 | ||
|
|
0dd67e2f25 | ||
|
|
4df27b9626 | ||
|
|
e708a872a1 | ||
|
|
2dacc6da28 | ||
|
|
9660e42fe2 | ||
|
|
522da25932 | ||
|
|
d44621b544 | ||
|
|
6fe0539992 | ||
|
|
283238fd77 | ||
|
|
5568ecc7aa | ||
|
|
743d5378d2 | ||
|
|
63a3676d3c | ||
|
|
2a39c217c8 | ||
|
|
a2fc4ca7ad | ||
|
|
8eeaa45729 | ||
|
|
4d13055ca5 | ||
|
|
bfceffa2f7 | ||
|
|
031583e8f5 | ||
|
|
2ccbc673df | ||
|
|
11b5728faa | ||
|
|
4decdf6245 | ||
|
|
ac0fb976c8 | ||
|
|
1de9f99ea8 | ||
|
|
60f8e18372 | ||
|
|
e52b4bce01 | ||
|
|
f93a558892 | ||
|
|
5ba3505fed | ||
|
|
18e7d28b21 | ||
|
|
02ca283716 | ||
|
|
4f0e3cb621 | ||
|
|
73a69d9e64 | ||
|
|
b1911a7cd3 | ||
|
|
450642a897 | ||
|
|
f7a1903bfc | ||
|
|
61cf22f147 | ||
|
|
55505776fb | ||
|
|
3c91928bae | ||
|
|
6ac7564918 | ||
|
|
23e1aac9b2 | ||
|
|
c65af78853 | ||
|
|
4155ac1c0d | ||
|
|
cfe5544b30 | ||
|
|
d7b901a1e7 | ||
|
|
5225a8c644 | ||
|
|
fc50f949d4 | ||
|
|
f6b40861f7 | ||
|
|
f491d420f7 | ||
|
|
ef0882e17e | ||
|
|
697bafa9c9 | ||
|
|
77761f4a3e | ||
|
|
0e2694ff47 | ||
|
|
5eb71927b7 | ||
|
|
cbd8049b9f | ||
|
|
19f22b5924 | ||
|
|
05634708e0 | ||
|
|
536c00991f | ||
|
|
c94c43d3bb | ||
|
|
8a99c0d17a | ||
|
|
30e1556cda | ||
|
|
ec15f90a55 | ||
|
|
3da34a4673 | ||
|
|
f91ddefbfb | ||
|
|
84385898ec | ||
|
|
6c7642b532 | ||
|
|
9988a37d37 | ||
|
|
37b33d11ce | ||
|
|
7086e34533 | ||
|
|
20fbb8bd14 | ||
|
|
8e90a1cad9 | ||
|
|
7e3ebb8e10 | ||
|
|
06b2bf1c0a | ||
|
|
d649548a7a | ||
|
|
5adc681238 | ||
|
|
53e8dc6a54 | ||
|
|
2d0a0c5e43 | ||
|
|
b668ffe7ca | ||
|
|
6736936cbc | ||
|
|
8539e0283a | ||
|
|
ef88f0f949 | ||
|
|
816c692035 | ||
|
|
c635e560d0 | ||
|
|
ccb59d989b | ||
|
|
642f85dc5b | ||
|
|
53300a5c1a | ||
|
|
b51610a1c3 | ||
|
|
5269924ff8 | ||
|
|
62fa5692cb | ||
|
|
2d4369d176 | ||
|
|
99e8cf22a8 | ||
|
|
e780a6b7ba | ||
|
|
313554059c | ||
|
|
77b334a984 | ||
|
|
ab67a198c1 | ||
|
|
9ef5a9afdc | ||
|
|
c39fbdb698 | ||
|
|
d33d6bfafa | ||
|
|
2209f71a78 | ||
|
|
f13a615036 | ||
|
|
5660b67062 | ||
|
|
1d21646e96 | ||
|
|
55d4456751 | ||
|
|
a80d9f00f1 | ||
|
|
22d635080d | ||
|
|
d5be702f86 | ||
|
|
3d66d203d0 | ||
|
|
a918e93421 | ||
|
|
56eadf36d0 | ||
|
|
912f663173 | ||
|
|
f44af7eebf | ||
|
|
65fe2b7e91 | ||
|
|
941e04e9f3 | ||
|
|
f327073fb3 | ||
|
|
41e5acbb6c | ||
|
|
2333d47a1e | ||
|
|
c9e481ac48 | ||
|
|
462e315953 | ||
|
|
6b14df7792 | ||
|
|
e449392c4f | ||
|
|
326db58229 | ||
|
|
3caf4facec | ||
|
|
c9a97f54e0 | ||
|
|
85506c36a0 | ||
|
|
a176b8ec2f | ||
|
|
2b726457d8 | ||
|
|
6464f8d1d9 | ||
|
|
a17c7a56da | ||
|
|
98a1aa491f | ||
|
|
25b87b111d | ||
|
|
f823123aa5 | ||
|
|
d717ff71bf | ||
|
|
840192caa9 | ||
|
|
61ef6b12dd | ||
|
|
660a6dec7f | ||
|
|
e49ef86945 | ||
|
|
d2f69ecc3b | ||
|
|
a89abcb1e9 | ||
|
|
8bf7bc5b5c | ||
|
|
4e2ef87c31 | ||
|
|
ec58491f75 | ||
|
|
0840fea50d | ||
|
|
cf60e83118 | ||
|
|
7ad2ebb515 | ||
|
|
3c41e1722f | ||
|
|
dd5b70bcc4 | ||
|
|
30c0422a8e | ||
|
|
6d43200248 | ||
|
|
be3153cabb | ||
|
|
56995069f1 | ||
|
|
2238e0ce76 | ||
|
|
38a463fe93 | ||
|
|
e1f462b352 | ||
|
|
ccd635fdb9 | ||
|
|
27dce6c6bb | ||
|
|
9c08d8cd35 | ||
|
|
dc5b3ecc4c | ||
|
|
95f66a34e7 | ||
|
|
1695ee2f43 | ||
|
|
801520b0f0 | ||
|
|
8ba79d72b4 | ||
|
|
5876ba6152 | ||
|
|
5b895f2592 | ||
|
|
fb61363763 | ||
|
|
07e0af44b3 | ||
|
|
059d5405fe | ||
|
|
cd37dbd4e5 | ||
|
|
3e8d06a6be | ||
|
|
2f07e4e6c0 | ||
|
|
15fb3314de | ||
|
|
5a019e7725 | ||
|
|
aea31934d4 | ||
|
|
8ec7e80cb2 | ||
|
|
6c3533d8c4 | ||
|
|
9c313a7826 | ||
|
|
368a719879 | ||
|
|
ec7e3eaf64 | ||
|
|
8bcdab8933 | ||
|
|
c2f0d811e7 | ||
|
|
8f3d3a549d | ||
|
|
d389a52494 | ||
|
|
346b14a51a | ||
|
|
ffa2da8478 | ||
|
|
61a768be75 | ||
|
|
3d8a77a113 | ||
|
|
a6a358f1a6 | ||
|
|
131dc4eaeb | ||
|
|
022fd55bad | ||
|
|
d9820e4098 | ||
|
|
a4ebdc9aa1 | ||
|
|
cf2461f7f6 | ||
|
|
f5f829db79 | ||
|
|
a06daab97e | ||
|
|
09f094057a | ||
|
|
9def042fab | ||
|
|
f6adea5757 | ||
|
|
78f4a5c05f | ||
|
|
731a7af9c5 | ||
|
|
ffa4342a6a | ||
|
|
550a134cf9 | ||
|
|
1b43e84d0d | ||
|
|
31f0635f4f | ||
|
|
1c65e2e7c1 | ||
|
|
b6f3fe7938 | ||
|
|
d65b3a68aa | ||
|
|
e2b54fecd8 | ||
|
|
b8067d073a | ||
|
|
e420c001d0 | ||
|
|
44b6b79a66 | ||
|
|
3ef2935ac9 | ||
|
|
fced29de17 | ||
|
|
4f074c3235 | ||
|
|
5df00520cb | ||
|
|
b2c85bc0a2 | ||
|
|
5e2e78a75a | ||
|
|
2196f107da | ||
|
|
ff56a2d7b3 | ||
|
|
24cff8a3bc | ||
|
|
b495ac2abb | ||
|
|
3f2585424d | ||
|
|
9d1a3007d9 | ||
|
|
b5c163dffa | ||
|
|
ee0cf9e5bb | ||
|
|
37fdfa0e0b | ||
|
|
d550b804b8 | ||
|
|
05988500bc | ||
|
|
b01290cf64 | ||
|
|
117f6fb254 | ||
|
|
c363816fea | ||
|
|
aeed31cdb1 | ||
|
|
58c8c022c5 | ||
|
|
2cfae61743 | ||
|
|
c6b4daf426 | ||
|
|
348fabe04d | ||
|
|
6c83e8e7e4 | ||
|
|
817b6259c4 | ||
|
|
959af0fa5b | ||
|
|
669b26a3dc | ||
|
|
67c139fc36 | ||
|
|
8b6829e1bc | ||
|
|
86e6fbcf52 | ||
|
|
9b4b3aa348 | ||
|
|
51ab2c0d79 | ||
|
|
bdd9c70787 | ||
|
|
1ff95ff3e6 | ||
|
|
7c5b55c5ff | ||
|
|
b0d6076208 | ||
|
|
4385e57dce | ||
|
|
eb45c1c623 | ||
|
|
adf981de89 | ||
|
|
023a101b91 | ||
|
|
8b92aca27f | ||
|
|
b13fb788b5 | ||
|
|
87c0ee7685 | ||
|
|
eef32e94c7 | ||
|
|
1350efcfd8 | ||
|
|
e7ef051149 | ||
|
|
2b5ddf8f2a | ||
|
|
6f655573d3 | ||
|
|
8aabf45ddb | ||
|
|
4d4748e807 | ||
|
|
439c09668e | ||
|
|
54bbe87cd5 | ||
|
|
6804b7cb71 | ||
|
|
63470e99f0 | ||
|
|
90b0f7bd85 | ||
|
|
d92b3b5cc2 | ||
|
|
4d0668a546 | ||
|
|
2c0f79d53a | ||
|
|
5374c7a8a2 | ||
|
|
35ce103378 | ||
|
|
029c17de41 | ||
|
|
6b41a0692f | ||
|
|
da5d1a6215 | ||
|
|
f72762ae8f | ||
|
|
0185d0d2ac | ||
|
|
82fe55acac | ||
|
|
28eb4cfa12 | ||
|
|
a9cbec912e | ||
|
|
095bc6d4b4 | ||
|
|
b72853a742 | ||
|
|
4f784b5d47 | ||
|
|
ff2a99b22e | ||
|
|
de1dfab03e | ||
|
|
7b699fddac | ||
|
|
7854f547ce | ||
|
|
e64d713e41 | ||
|
|
8348af99e8 | ||
|
|
b1958256fd | ||
|
|
65fc5d1c5d | ||
|
|
b19584b25e | ||
|
|
069ea7942d | ||
|
|
5d75f64369 | ||
|
|
7666d71fab | ||
|
|
25affd6584 | ||
|
|
d8db7f561e | ||
|
|
26ef325219 | ||
|
|
86311b0e00 | ||
|
|
b09cab4ebd | ||
|
|
7d71c5d0c6 | ||
|
|
b13529767b | ||
|
|
cc42367f3f | ||
|
|
915f88a0a3 | ||
|
|
cec50aa047 | ||
|
|
fc90f0f15c | ||
|
|
0d4828497e | ||
|
|
aae0d54752 | ||
|
|
650027106b | ||
|
|
99ffd714ce | ||
|
|
0f8ea1d3d9 | ||
|
|
8d8f5a59e2 | ||
|
|
fcf2852f0f | ||
|
|
7054aa562e | ||
|
|
dad8cfaf74 | ||
|
|
5f4fc7512e | ||
|
|
530351e394 | ||
|
|
f52355ce5f | ||
|
|
9b605846bb | ||
|
|
26bf8f0dc8 | ||
|
|
3fbd2432b6 | ||
|
|
f90b8cffc7 | ||
|
|
1ac037d948 | ||
|
|
45c4f1edd4 | ||
|
|
be76841143 | ||
|
|
89e64f70c1 | ||
|
|
e35db953eb | ||
|
|
032945a5cd | ||
|
|
f61a5bc797 | ||
|
|
0915b72bcf | ||
|
|
7840fdbada | ||
|
|
4abde61366 | ||
|
|
4291e32777 | ||
|
|
453f40d5bf | ||
|
|
470fc879e8 | ||
|
|
311c1a05eb | ||
|
|
7c3d7fc6e3 | ||
|
|
94df665cdc | ||
|
|
7c1484d637 | ||
|
|
be2c43ee3e | ||
|
|
5aa2bd7921 | ||
|
|
0a7ecd5428 | ||
|
|
5db2cd6c00 | ||
|
|
81505ada18 | ||
|
|
8edeba0de3 | ||
|
|
beb42b12c9 | ||
|
|
42b320ad65 | ||
|
|
bba8015688 | ||
|
|
05e31bbedd | ||
|
|
c806a736af | ||
|
|
ceb179f84d | ||
|
|
72a2cc0acb | ||
|
|
cd07d013ba | ||
|
|
afa6d0cd18 | ||
|
|
aa0d6e1bca | ||
|
|
17e75f8641 | ||
|
|
d69ee6777d | ||
|
|
344aff383b | ||
|
|
56f46a2581 | ||
|
|
62abfd3dcb | ||
|
|
c536bd6af1 | ||
|
|
fcdc25ba64 | ||
|
|
9090f6b1c4 | ||
|
|
0d604f160d | ||
|
|
b352cb2d8e | ||
|
|
b9933b2ec1 | ||
|
|
f848a6f7f7 | ||
|
|
72eff6b2e9 | ||
|
|
56fc17be78 | ||
|
|
3c3e39684e | ||
|
|
25dfe9294f | ||
|
|
622404fcec | ||
|
|
bda02f4be8 | ||
|
|
58de6f91dc | ||
|
|
c0a5f15dc8 | ||
|
|
21b5f601b6 | ||
|
|
2e21158d04 | ||
|
|
16b510807b | ||
|
|
07c1245db4 | ||
|
|
d13c8b03c9 | ||
|
|
7b3104fe4c | ||
|
|
8fa4c4ff4e | ||
|
|
67ddc1a3e1 | ||
|
|
a17487bc9f | ||
|
|
f613f32b22 | ||
|
|
03415bb696 | ||
|
|
723b5085d9 | ||
|
|
28ffcf88bd | ||
|
|
7de025eacd | ||
|
|
1659b26151 | ||
|
|
c88178d9b6 | ||
|
|
117af11a6f | ||
|
|
b5bae67aad | ||
|
|
0fdc51f35d | ||
|
|
a1c6882777 | ||
|
|
59c84f8e5c | ||
|
|
d115fb4cf9 | ||
|
|
e9dee8dfe1 | ||
|
|
9f30af5a96 | ||
|
|
29b32050c1 | ||
|
|
815ffb3bb2 | ||
|
|
440e737c67 | ||
|
|
784fbcfd16 | ||
|
|
584fa3215c | ||
|
|
dc4f3b57cf | ||
|
|
985b41e136 | ||
|
|
51d0ef80c2 | ||
|
|
f870beac85 | ||
|
|
75de853c37 | ||
|
|
b3b962a051 | ||
|
|
6f3f4f7420 | ||
|
|
acb0e9c155 | ||
|
|
be1c4f3ee1 | ||
|
|
deb48a96fb | ||
|
|
086df266cc | ||
|
|
730aa406ef | ||
|
|
1a4eb0b5e7 | ||
|
|
4be8a58a7d | ||
|
|
a341ae27ec | ||
|
|
18f94fc83a | ||
|
|
aada44fca5 |
@@ -100,6 +100,10 @@ Format first if formatting can change line locations. Then it is OK to run tests
|
||||
scripts/autoreview --parallel-tests "<focused test command>"
|
||||
```
|
||||
|
||||
On Windows, the default `--parallel-tests` shell preserves the platform `cmd.exe`
|
||||
semantics used by Python `shell=True`. Use `--parallel-tests-shell powershell`
|
||||
or `--parallel-tests-shell pwsh` when the focused test command is PowerShell-specific.
|
||||
|
||||
Tradeoff: tests may force code changes that stale the review. If tests or review lead to code edits, rerun the affected tests and rerun review until no accepted/actionable findings remain. Once that rerun exits cleanly, stop; do not spend another long review cycle on redundant confirmation.
|
||||
|
||||
## Review Panels
|
||||
@@ -144,6 +148,22 @@ OpenClaw repo-local helper:
|
||||
.agents/skills/autoreview/scripts/autoreview --help
|
||||
```
|
||||
|
||||
On native Windows, invoke the extensionless Python helper through Python:
|
||||
|
||||
```powershell
|
||||
python .agents\skills\autoreview\scripts\autoreview --help
|
||||
```
|
||||
|
||||
The smoke harness has thin shell wrappers over a shared Python implementation:
|
||||
|
||||
```bash
|
||||
.agents/skills/autoreview/scripts/test-review-harness --fixture benign --engine codex
|
||||
```
|
||||
|
||||
```powershell
|
||||
.agents\skills\autoreview\scripts\test-review-harness.ps1 -Fixture benign -Engine codex
|
||||
```
|
||||
|
||||
`agent-scripts` checkout helper:
|
||||
|
||||
```bash
|
||||
@@ -169,10 +189,11 @@ The helper:
|
||||
- otherwise uses current PR base if `gh pr view` works
|
||||
- otherwise uses `origin/main` for non-main branches
|
||||
- supports `--engine codex`, `claude`, `droid`, and `copilot`; default is `AUTOREVIEW_ENGINE` or `codex`; Codex should remain the default when nothing is set
|
||||
- resolves bare `git`, `gh`, reviewer, and PowerShell shell commands from absolute `PATH` entries only, never from the reviewed checkout; explicit relative `--*-bin` paths are resolved from the reviewed repository root
|
||||
- use `--mode commit --commit <ref>` for already-committed work, especially clean `main` after landing
|
||||
- should be left in `--mode auto` or forced to `--mode branch` for PR/branch work; do not force `--mode local` after committing
|
||||
- writes only to stdout unless `--output`, `--json-output`, or live streamed engine stderr is set
|
||||
- supports `--dry-run`, `--parallel-tests`, `--prompt`, `--prompt-file`, `--dataset`, `--no-tools`, `--no-web-search`, and commit refs
|
||||
- supports `--dry-run`, `--parallel-tests`, `--parallel-tests-shell`, `--prompt`, `--prompt-file`, `--dataset`, `--no-tools`, `--no-web-search`, and commit refs
|
||||
- supports `--stream-engine-output` or `AUTOREVIEW_STREAM_ENGINE_OUTPUT=1` for live engine text while preserving structured validation; Codex and Claude hide tool/file event details, emit compact activity summaries, and report usage at turn completion
|
||||
- supports opt-in review panels with `--panel` / `--reviewers`, plus per-engine `--model` and `--thinking`
|
||||
- allows read-only tools and web search by default where the selected CLI supports them; forbids nested review in the prompt; Codex is run through `codex exec` with read-only sandbox and structured output
|
||||
|
||||
@@ -214,12 +214,17 @@ def run_with_stream(
|
||||
|
||||
|
||||
def git(repo: Path, *args: str, check: bool = True) -> str:
|
||||
return run(["git", *args], repo, check=check).stdout
|
||||
return run([resolve_command("git", repo), *args], repo, check=check).stdout
|
||||
|
||||
|
||||
def repo_root() -> Path:
|
||||
start = Path.cwd().resolve()
|
||||
unsafe_root = discover_repo_root(start) or start
|
||||
git_bin = find_command("git", unsafe_root)
|
||||
if not git_bin:
|
||||
raise SystemExit("git executable not found. Install Git or add it to PATH.")
|
||||
result = subprocess.run(
|
||||
["git", "rev-parse", "--show-toplevel"],
|
||||
[git_bin, "rev-parse", "--show-toplevel"],
|
||||
text=True,
|
||||
stdout=subprocess.PIPE,
|
||||
stderr=subprocess.PIPE,
|
||||
@@ -229,6 +234,16 @@ def repo_root() -> Path:
|
||||
return Path(result.stdout.strip()).resolve()
|
||||
|
||||
|
||||
def discover_repo_root(start: Path) -> Path | None:
|
||||
current = start
|
||||
while True:
|
||||
if (current / ".git").exists():
|
||||
return current
|
||||
if current.parent == current:
|
||||
return None
|
||||
current = current.parent
|
||||
|
||||
|
||||
def current_branch(repo: Path) -> str:
|
||||
return git(repo, "branch", "--show-current", check=False).strip() or "detached"
|
||||
|
||||
@@ -250,17 +265,70 @@ def choose_target(repo: Path, mode: str, base_ref: str | None) -> tuple[str, str
|
||||
|
||||
|
||||
def detect_pr_base(repo: Path) -> str | None:
|
||||
if not shutil_which("gh"):
|
||||
gh_bin = find_command("gh", repo)
|
||||
if not gh_bin:
|
||||
return None
|
||||
result = run(["gh", "pr", "view", "--json", "baseRefName", "--jq", ".baseRefName"], repo, check=False)
|
||||
result = run([gh_bin, "pr", "view", "--json", "baseRefName", "--jq", ".baseRefName"], repo, check=False)
|
||||
base = result.stdout.strip()
|
||||
return f"origin/{base}" if result.returncode == 0 and base else None
|
||||
|
||||
|
||||
def shutil_which(name: str) -> str | None:
|
||||
def resolve_command(name: str, repo: Path) -> str:
|
||||
resolved = find_command(name, repo)
|
||||
if resolved:
|
||||
return resolved
|
||||
raise SystemExit(f"executable not found: {name}. Install it or pass an explicit trusted path when supported.")
|
||||
|
||||
|
||||
def find_command(name: str, repo: Path) -> str | None:
|
||||
command = Path(name)
|
||||
if has_directory_component(name, command):
|
||||
base = command if command.is_absolute() else repo / command
|
||||
return first_executable_candidate(base)
|
||||
for part in os.environ.get("PATH", "").split(os.pathsep):
|
||||
candidate = Path(part) / name
|
||||
if candidate.exists() and os.access(candidate, os.X_OK):
|
||||
if not part or part == ".":
|
||||
continue
|
||||
path_part = Path(part)
|
||||
if not path_part.is_absolute():
|
||||
continue
|
||||
try:
|
||||
resolved_part = path_part.resolve()
|
||||
resolved_repo = repo.resolve()
|
||||
except OSError:
|
||||
continue
|
||||
if is_within(resolved_part, resolved_repo):
|
||||
continue
|
||||
found = first_executable_candidate(resolved_part / name, reject_root=resolved_repo)
|
||||
if found:
|
||||
return found
|
||||
return None
|
||||
|
||||
|
||||
def is_within(path: Path, root: Path) -> bool:
|
||||
return path == root or path.is_relative_to(root)
|
||||
|
||||
|
||||
def has_directory_component(name: str, command: Path) -> bool:
|
||||
separators = [separator for separator in (os.sep, os.altsep) if separator]
|
||||
return command.is_absolute() or bool(command.drive) or any(separator in name for separator in separators)
|
||||
|
||||
|
||||
def first_executable_candidate(path: Path, *, reject_root: Path | None = None) -> str | None:
|
||||
if os.name == "nt" and not path.suffix:
|
||||
extensions = [ext for ext in os.environ.get("PATHEXT", ".COM;.EXE;.BAT;.CMD").split(";") if ext]
|
||||
candidates = [path.with_suffix(ext.lower()) for ext in extensions]
|
||||
candidates.extend(path.with_suffix(ext.upper()) for ext in extensions)
|
||||
candidates.append(path)
|
||||
else:
|
||||
candidates = [path]
|
||||
for candidate in candidates:
|
||||
if candidate.is_file() and os.access(candidate, os.X_OK):
|
||||
if reject_root is not None:
|
||||
try:
|
||||
if is_within(candidate.resolve(), reject_root):
|
||||
continue
|
||||
except OSError:
|
||||
continue
|
||||
return str(candidate)
|
||||
return None
|
||||
|
||||
@@ -419,7 +487,7 @@ def run_codex(args: argparse.Namespace, repo: Path, prompt: str) -> str:
|
||||
raise SystemExit("--no-tools is not supported by the Codex engine; use --engine claude --no-tools for a no-tools run")
|
||||
schema_path = write_json_temp(SCHEMA)
|
||||
output_path = Path(tempfile.NamedTemporaryFile("w", suffix=".json", delete=False).name)
|
||||
cmd = [args.codex_bin, "--ask-for-approval", "never"]
|
||||
cmd = [resolve_command(args.codex_bin, repo), "--ask-for-approval", "never"]
|
||||
if args.web_search:
|
||||
cmd.append("--search")
|
||||
if args.model:
|
||||
@@ -463,7 +531,7 @@ def run_codex(args: argparse.Namespace, repo: Path, prompt: str) -> str:
|
||||
|
||||
def run_claude(args: argparse.Namespace, repo: Path, prompt: str) -> str:
|
||||
cmd = [
|
||||
args.claude_bin,
|
||||
resolve_command(args.claude_bin, repo),
|
||||
"--print",
|
||||
"--no-session-persistence",
|
||||
"--output-format",
|
||||
@@ -500,7 +568,7 @@ def run_droid(args: argparse.Namespace, repo: Path, prompt: str) -> str:
|
||||
prompt_path = Path(tempfile.NamedTemporaryFile("w", suffix=".txt", delete=False).name)
|
||||
prompt_path.write_text(prompt)
|
||||
cmd = [
|
||||
args.droid_bin,
|
||||
resolve_command(args.droid_bin, repo),
|
||||
"exec",
|
||||
"--cwd",
|
||||
str(repo),
|
||||
@@ -530,7 +598,7 @@ def run_copilot(args: argparse.Namespace, repo: Path, prompt: str) -> str:
|
||||
prompt_path.write_text(prompt)
|
||||
os.chmod(prompt_path, 0o600)
|
||||
cmd = [
|
||||
args.copilot_bin,
|
||||
resolve_command(args.copilot_bin, repo),
|
||||
"-C",
|
||||
tempdir,
|
||||
"-p",
|
||||
@@ -877,9 +945,23 @@ def print_report(report: dict[str, Any], *, label: str = "autoreview") -> None:
|
||||
print(report["overall_explanation"])
|
||||
|
||||
|
||||
def start_parallel_tests(command: str, repo: Path) -> tuple[subprocess.Popen, float]:
|
||||
def start_parallel_tests(command: str, repo: Path, shell_kind: str) -> tuple[subprocess.Popen, float]:
|
||||
print(f"tests: {command}")
|
||||
return subprocess.Popen(command, cwd=repo, shell=True), time.time()
|
||||
if shell_kind == "default" or shell_kind == "cmd":
|
||||
return subprocess.Popen(command, cwd=repo, shell=True), time.time()
|
||||
if shell_kind == "powershell":
|
||||
powershell = resolve_command("powershell", repo)
|
||||
return subprocess.Popen(
|
||||
[powershell, "-NoProfile", "-ExecutionPolicy", "Bypass", "-Command", command],
|
||||
cwd=repo,
|
||||
), time.time()
|
||||
if shell_kind == "pwsh":
|
||||
pwsh = resolve_command("pwsh", repo)
|
||||
return subprocess.Popen(
|
||||
[pwsh, "-NoProfile", "-Command", command],
|
||||
cwd=repo,
|
||||
), time.time()
|
||||
raise SystemExit(f"invalid --parallel-tests-shell/AUTOREVIEW_PARALLEL_TESTS_SHELL: {shell_kind}")
|
||||
|
||||
|
||||
def finish_parallel_tests(proc: subprocess.Popen, started: float) -> int:
|
||||
@@ -924,6 +1006,12 @@ def parse_args() -> argparse.Namespace:
|
||||
help="Stream review engine output while preserving buffered output for validation. Codex output is filtered to hide tool/file chatter.",
|
||||
)
|
||||
parser.add_argument("--parallel-tests", help="Run a test command concurrently with review; failure fails the helper.")
|
||||
parser.add_argument(
|
||||
"--parallel-tests-shell",
|
||||
choices=["default", "cmd", "powershell", "pwsh"],
|
||||
default=os.environ.get("AUTOREVIEW_PARALLEL_TESTS_SHELL", "default"),
|
||||
help="Shell for --parallel-tests. Default preserves Python shell=True platform behavior; use powershell or pwsh for PowerShell-specific commands.",
|
||||
)
|
||||
parser.add_argument("--require-finding", action="append", default=[], help="Require finding text to contain this substring.")
|
||||
parser.add_argument("--expect-findings", action="store_true", help="Treat findings as success; for harness acceptance tests.")
|
||||
parser.add_argument("--dry-run", action="store_true")
|
||||
@@ -1129,7 +1217,7 @@ def main() -> int:
|
||||
|
||||
tests_proc: tuple[subprocess.Popen, float] | None = None
|
||||
if args.parallel_tests:
|
||||
tests_proc = start_parallel_tests(args.parallel_tests, repo)
|
||||
tests_proc = start_parallel_tests(args.parallel_tests, repo, args.parallel_tests_shell)
|
||||
try:
|
||||
if len(reviewers) == 1:
|
||||
report = run_reviewer(reviewers[0], repo, prompt, changed_paths, args.require_finding)
|
||||
|
||||
@@ -1,176 +1,16 @@
|
||||
#!/usr/bin/env bash
|
||||
set -euo pipefail
|
||||
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
Usage: test-review-harness [--fixture malicious|benign] [--engine codex|claude|droid|copilot]...
|
||||
|
||||
Creates a temporary git repo with either a deliberately unsafe patch or a
|
||||
security-sensitive-but-safe patch, then verifies each selected engine through
|
||||
autoreview.
|
||||
Default engines: codex, claude.
|
||||
EOF
|
||||
}
|
||||
|
||||
engines=()
|
||||
fixture=malicious
|
||||
while [[ $# -gt 0 ]]; do
|
||||
case "$1" in
|
||||
--fixture)
|
||||
fixture=${2:-}
|
||||
shift 2
|
||||
;;
|
||||
--engine)
|
||||
engines+=("${2:-}")
|
||||
shift 2
|
||||
;;
|
||||
-h|--help)
|
||||
usage
|
||||
exit 0
|
||||
;;
|
||||
*)
|
||||
usage >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
done
|
||||
|
||||
case "$fixture" in
|
||||
malicious|benign) ;;
|
||||
*)
|
||||
usage >&2
|
||||
exit 2
|
||||
;;
|
||||
esac
|
||||
|
||||
if [[ ${#engines[@]} -eq 0 ]]; then
|
||||
engines=(codex claude)
|
||||
fi
|
||||
|
||||
script_dir=$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)
|
||||
repo=$(mktemp -d "${TMPDIR:-/tmp}/autoreview-fixture.XXXXXX")
|
||||
trap 'rm -rf "$repo"' EXIT
|
||||
harness="$script_dir/test-review-harness.py"
|
||||
|
||||
cd "$repo"
|
||||
git init --quiet
|
||||
git config user.name "Review Fixture"
|
||||
git config user.email "review-fixture@example.com"
|
||||
|
||||
if [[ "$fixture" == malicious ]]; then
|
||||
cat > app.js <<'EOF'
|
||||
export function uploadPath(name) {
|
||||
return `uploads/${name.replaceAll("/", "")}`;
|
||||
}
|
||||
|
||||
export function publicUser(user) {
|
||||
return { id: user.id, name: user.name };
|
||||
}
|
||||
EOF
|
||||
else
|
||||
cat > app.js <<'EOF'
|
||||
import path from "node:path";
|
||||
|
||||
const uploadsRoot = path.resolve("uploads");
|
||||
|
||||
function safeChildPath(root, name) {
|
||||
if (name.includes("/") || name.includes("\\") || name.includes("\0")) {
|
||||
throw new Error("invalid child name");
|
||||
}
|
||||
const resolved = path.resolve(root, name);
|
||||
if (!resolved.startsWith(root + path.sep)) throw new Error("path escaped root");
|
||||
return resolved;
|
||||
}
|
||||
|
||||
export function uploadPath(name) {
|
||||
return safeChildPath(uploadsRoot, name);
|
||||
}
|
||||
|
||||
export function publicUser(user) {
|
||||
return { id: user.id, name: user.name };
|
||||
}
|
||||
EOF
|
||||
if command -v python3 >/dev/null 2>&1; then
|
||||
exec python3 "$harness" "$@"
|
||||
fi
|
||||
|
||||
git add app.js
|
||||
git commit --quiet -m "initial safe version"
|
||||
|
||||
if [[ "$fixture" == malicious ]]; then
|
||||
cat > app.js <<'EOF'
|
||||
import { execSync } from "node:child_process";
|
||||
|
||||
export function uploadPath(name) {
|
||||
return `uploads/${name}`;
|
||||
}
|
||||
|
||||
export function deleteUpload(name) {
|
||||
return execSync(`rm -rf uploads/${name}`);
|
||||
}
|
||||
|
||||
export function publicUser(user) {
|
||||
return { id: user.id, name: user.name, password: user.password };
|
||||
}
|
||||
EOF
|
||||
else
|
||||
cat > app.js <<'EOF'
|
||||
import { execFile } from "node:child_process";
|
||||
import path from "node:path";
|
||||
import { promisify } from "node:util";
|
||||
|
||||
const uploadsRoot = path.resolve("uploads");
|
||||
const reposRoot = path.resolve("repos");
|
||||
const execFileAsync = promisify(execFile);
|
||||
|
||||
function safeChildPath(root, name) {
|
||||
if (name.includes("/") || name.includes("\\") || name.includes("\0")) {
|
||||
throw new Error("invalid child name");
|
||||
}
|
||||
const resolved = path.resolve(root, name);
|
||||
if (!resolved.startsWith(root + path.sep)) throw new Error("path escaped root");
|
||||
return resolved;
|
||||
}
|
||||
|
||||
function repoChildPath(root, name) {
|
||||
if (!/^[A-Za-z0-9._-]+$/.test(name)) throw new Error("invalid repo name");
|
||||
return safeChildPath(root, name);
|
||||
}
|
||||
|
||||
export function uploadPath(name) {
|
||||
return safeChildPath(uploadsRoot, name);
|
||||
}
|
||||
|
||||
export async function repoStatus(repoName) {
|
||||
const { stdout } = await execFileAsync("git", ["status", "--short"], {
|
||||
cwd: repoChildPath(reposRoot, repoName),
|
||||
encoding: "utf8",
|
||||
maxBuffer: 16 * 1024 * 1024,
|
||||
});
|
||||
return stdout;
|
||||
}
|
||||
|
||||
export function publicUser(user) {
|
||||
return { id: user.id, name: user.name };
|
||||
}
|
||||
|
||||
export function accountSettingsForOwner(user, requesterId) {
|
||||
if (String(requesterId) !== String(user.id)) throw new Error("forbidden");
|
||||
return { id: user.id, hasPassword: Boolean(user.passwordHash) };
|
||||
}
|
||||
EOF
|
||||
if command -v python >/dev/null 2>&1; then
|
||||
exec python "$harness" "$@"
|
||||
fi
|
||||
|
||||
for engine in "${engines[@]}"; do
|
||||
echo "== $engine =="
|
||||
if [[ "$fixture" == malicious ]]; then
|
||||
"$script_dir/autoreview" \
|
||||
--mode local \
|
||||
--engine "$engine" \
|
||||
--prompt "This is an acceptance test fixture. The changed app.js patch contains real security bugs. Review normally and report only actionable defects from the patch." \
|
||||
--require-finding "command" \
|
||||
--expect-findings
|
||||
else
|
||||
"$script_dir/autoreview" \
|
||||
--mode local \
|
||||
--engine "$engine" \
|
||||
--prompt "Security calibration fixture: this patch intentionally uses filesystem paths, async execFile, and owner-gated password-adjacent state safely. Do not flag legitimate shell/filesystem/auth-adjacent functionality unless there is a concrete exploitable risk in the diff."
|
||||
fi
|
||||
done
|
||||
echo "Python 3 is required to run test-review-harness." >&2
|
||||
exit 127
|
||||
|
||||
45
.agents/skills/autoreview/scripts/test-review-harness.ps1
Normal file
45
.agents/skills/autoreview/scripts/test-review-harness.ps1
Normal file
@@ -0,0 +1,45 @@
|
||||
[CmdletBinding()]
|
||||
param(
|
||||
[ValidateSet('malicious', 'benign')]
|
||||
[string] $Fixture,
|
||||
|
||||
[ValidateSet('codex', 'claude', 'droid', 'copilot')]
|
||||
[string[]] $Engine,
|
||||
|
||||
[Alias('h')]
|
||||
[switch] $Help
|
||||
)
|
||||
|
||||
$ErrorActionPreference = 'Stop'
|
||||
|
||||
$Harness = Join-Path $PSScriptRoot 'test-review-harness.py'
|
||||
$ForwardedArgs = @()
|
||||
|
||||
if ($Help) {
|
||||
$ForwardedArgs += '--help'
|
||||
}
|
||||
|
||||
if ($PSBoundParameters.ContainsKey('Fixture')) {
|
||||
$ForwardedArgs += @('--fixture', $Fixture)
|
||||
}
|
||||
|
||||
if ($PSBoundParameters.ContainsKey('Engine')) {
|
||||
foreach ($SelectedEngine in $Engine) {
|
||||
$ForwardedArgs += @('--engine', $SelectedEngine)
|
||||
}
|
||||
}
|
||||
|
||||
$PyLauncher = Get-Command py -ErrorAction SilentlyContinue
|
||||
if ($null -ne $PyLauncher) {
|
||||
& $PyLauncher.Source -3 $Harness @ForwardedArgs
|
||||
exit $LASTEXITCODE
|
||||
}
|
||||
|
||||
$Python = Get-Command python -ErrorAction SilentlyContinue
|
||||
if ($null -ne $Python) {
|
||||
& $Python.Source $Harness @ForwardedArgs
|
||||
exit $LASTEXITCODE
|
||||
}
|
||||
|
||||
Write-Error 'Python 3 is required to run test-review-harness.'
|
||||
exit 127
|
||||
199
.agents/skills/autoreview/scripts/test-review-harness.py
Normal file
199
.agents/skills/autoreview/scripts/test-review-harness.py
Normal file
@@ -0,0 +1,199 @@
|
||||
#!/usr/bin/env python3
|
||||
from __future__ import annotations
|
||||
|
||||
import argparse
|
||||
import os
|
||||
import shutil
|
||||
import stat
|
||||
import subprocess
|
||||
import sys
|
||||
import tempfile
|
||||
from collections.abc import Callable
|
||||
from pathlib import Path
|
||||
|
||||
|
||||
ENGINES = ("codex", "claude", "droid", "copilot")
|
||||
DEFAULT_ENGINES = ("codex", "claude")
|
||||
|
||||
MALICIOUS_INITIAL = """export function uploadPath(name) {
|
||||
return `uploads/${name.replaceAll("/", "")}`;
|
||||
}
|
||||
|
||||
export function publicUser(user) {
|
||||
return { id: user.id, name: user.name };
|
||||
}
|
||||
"""
|
||||
|
||||
BENIGN_INITIAL = r"""import path from "node:path";
|
||||
|
||||
const uploadsRoot = path.resolve("uploads");
|
||||
|
||||
function safeChildPath(root, name) {
|
||||
if (name.includes("/") || name.includes("\\") || name.includes("\0")) {
|
||||
throw new Error("invalid child name");
|
||||
}
|
||||
const resolved = path.resolve(root, name);
|
||||
if (!resolved.startsWith(root + path.sep)) throw new Error("path escaped root");
|
||||
return resolved;
|
||||
}
|
||||
|
||||
export function uploadPath(name) {
|
||||
return safeChildPath(uploadsRoot, name);
|
||||
}
|
||||
|
||||
export function publicUser(user) {
|
||||
return { id: user.id, name: user.name };
|
||||
}
|
||||
"""
|
||||
|
||||
MALICIOUS_CHANGED = """import { execSync } from "node:child_process";
|
||||
|
||||
export function uploadPath(name) {
|
||||
return `uploads/${name}`;
|
||||
}
|
||||
|
||||
export function deleteUpload(name) {
|
||||
return execSync(`rm -rf uploads/${name}`);
|
||||
}
|
||||
|
||||
export function publicUser(user) {
|
||||
return { id: user.id, name: user.name, password: user.password };
|
||||
}
|
||||
"""
|
||||
|
||||
BENIGN_CHANGED = r"""import { execFile } from "node:child_process";
|
||||
import path from "node:path";
|
||||
import { promisify } from "node:util";
|
||||
|
||||
const uploadsRoot = path.resolve("uploads");
|
||||
const reposRoot = path.resolve("repos");
|
||||
const execFileAsync = promisify(execFile);
|
||||
|
||||
function safeChildPath(root, name) {
|
||||
if (name.includes("/") || name.includes("\\") || name.includes("\0")) {
|
||||
throw new Error("invalid child name");
|
||||
}
|
||||
const resolved = path.resolve(root, name);
|
||||
if (!resolved.startsWith(root + path.sep)) throw new Error("path escaped root");
|
||||
return resolved;
|
||||
}
|
||||
|
||||
function repoChildPath(root, name) {
|
||||
if (!/^[A-Za-z0-9._-]+$/.test(name)) throw new Error("invalid repo name");
|
||||
return safeChildPath(root, name);
|
||||
}
|
||||
|
||||
export function uploadPath(name) {
|
||||
return safeChildPath(uploadsRoot, name);
|
||||
}
|
||||
|
||||
export async function repoProbe(repoName) {
|
||||
const { stdout } = await execFileAsync(process.execPath, ["--version"], {
|
||||
cwd: repoChildPath(reposRoot, repoName),
|
||||
encoding: "utf8",
|
||||
maxBuffer: 16 * 1024 * 1024,
|
||||
});
|
||||
return stdout;
|
||||
}
|
||||
|
||||
export function publicUser(user) {
|
||||
return { id: user.id, name: user.name };
|
||||
}
|
||||
|
||||
export function accountSettingsForOwner(user, requesterId) {
|
||||
if (String(requesterId) !== String(user.id)) throw new Error("forbidden");
|
||||
return { id: user.id, hasPassword: Boolean(user.passwordHash) };
|
||||
}
|
||||
"""
|
||||
|
||||
MALICIOUS_PROMPT = "This is an acceptance test fixture. The changed app.js patch contains real security bugs. Review normally and report only actionable defects from the patch."
|
||||
BENIGN_PROMPT = "Security calibration fixture: this patch intentionally uses filesystem paths, async execFile, and owner-gated password-adjacent state safely. Do not flag legitimate shell/filesystem/auth-adjacent functionality unless there is a concrete exploitable risk in the diff."
|
||||
|
||||
|
||||
def parse_args(argv: list[str]) -> argparse.Namespace:
|
||||
parser = argparse.ArgumentParser(
|
||||
prog="test-review-harness",
|
||||
description=(
|
||||
"Creates a temporary git repo with either a deliberately unsafe patch "
|
||||
"or a security-sensitive-but-safe patch, then verifies each selected "
|
||||
"engine through autoreview."
|
||||
),
|
||||
epilog="Default engines: codex, claude.",
|
||||
)
|
||||
parser.add_argument("--fixture", choices=("malicious", "benign"), default="malicious")
|
||||
parser.add_argument("--engine", action="append", choices=ENGINES, dest="engines")
|
||||
return parser.parse_args(argv)
|
||||
|
||||
|
||||
def write_fixture_file(repo: Path, content: str) -> None:
|
||||
with (repo / "app.js").open("w", encoding="utf-8", newline="\n") as handle:
|
||||
handle.write(content)
|
||||
|
||||
|
||||
def run(command: list[str], cwd: Path) -> None:
|
||||
subprocess.run(command, cwd=cwd, check=True)
|
||||
|
||||
|
||||
def create_fixture_repo(repo: Path, fixture: str) -> None:
|
||||
run(["git", "init", "--quiet"], repo)
|
||||
run(["git", "config", "user.name", "Review Fixture"], repo)
|
||||
run(["git", "config", "user.email", "review-fixture@example.com"], repo)
|
||||
|
||||
write_fixture_file(repo, MALICIOUS_INITIAL if fixture == "malicious" else BENIGN_INITIAL)
|
||||
run(["git", "add", "app.js"], repo)
|
||||
run(["git", "commit", "--quiet", "-m", "initial safe version"], repo)
|
||||
write_fixture_file(repo, MALICIOUS_CHANGED if fixture == "malicious" else BENIGN_CHANGED)
|
||||
|
||||
|
||||
def run_reviews(repo: Path, script_dir: Path, fixture: str, engines: list[str]) -> None:
|
||||
autoreview = script_dir / "autoreview"
|
||||
for engine in engines:
|
||||
print(f"== {engine} ==", flush=True)
|
||||
command = [
|
||||
sys.executable,
|
||||
str(autoreview),
|
||||
"--mode",
|
||||
"local",
|
||||
"--engine",
|
||||
engine,
|
||||
"--prompt",
|
||||
MALICIOUS_PROMPT if fixture == "malicious" else BENIGN_PROMPT,
|
||||
]
|
||||
if fixture == "malicious":
|
||||
command.extend(["--require-finding", "command", "--expect-findings"])
|
||||
run(command, repo)
|
||||
|
||||
|
||||
def cleanup_repo(repo: Path) -> None:
|
||||
def make_writable_and_retry(function: Callable[[str], object], path: str, _exc_info: object) -> None:
|
||||
try:
|
||||
os.chmod(path, stat.S_IREAD | stat.S_IWRITE)
|
||||
function(path)
|
||||
except OSError as exc:
|
||||
print(f"warning: unable to remove temp path {path}: {exc}", file=sys.stderr)
|
||||
|
||||
if not repo.exists():
|
||||
return
|
||||
try:
|
||||
shutil.rmtree(repo, onerror=make_writable_and_retry)
|
||||
except OSError as exc:
|
||||
print(f"warning: unable to remove temp repo {repo}: {exc}", file=sys.stderr)
|
||||
|
||||
|
||||
def main(argv: list[str]) -> int:
|
||||
args = parse_args(argv)
|
||||
script_dir = Path(__file__).resolve().parent
|
||||
engines = args.engines or list(DEFAULT_ENGINES)
|
||||
repo = Path(tempfile.mkdtemp(prefix="autoreview-fixture."))
|
||||
try:
|
||||
create_fixture_repo(repo, args.fixture)
|
||||
run_reviews(repo, script_dir, args.fixture, engines)
|
||||
except subprocess.CalledProcessError as exc:
|
||||
return int(exc.returncode or 1)
|
||||
finally:
|
||||
cleanup_repo(repo)
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main(sys.argv[1:]))
|
||||
@@ -52,17 +52,29 @@ attribution.
|
||||
- keep `#issue`, `(#PR)`, `Fixes #...`, and `Thanks @...`
|
||||
- every human-authored merged PR represented by a user-facing entry needs
|
||||
its PR ref and `Thanks @author`, even when the PR had no linked issue
|
||||
- every human issue reporter for a `Fixes #...` or referenced bug issue
|
||||
represented by a user-facing entry needs `Thanks @reporter` unless the
|
||||
same handle is already thanked in that bullet
|
||||
- every human `Co-authored-by` contributor on represented user-facing work
|
||||
needs `Thanks @handle` when a GitHub handle is known
|
||||
- when grouping multiple PRs/issues in one bullet, include every relevant
|
||||
PR/issue ref and every human contributor handle in that same bullet
|
||||
- multiple `Thanks @...` handles in one bullet are expected; do not drop or
|
||||
collapse contributor credit just because the note is grouped
|
||||
- if one grouped bullet covers both direct commits and PRs, keep all PR refs
|
||||
and thanks, plus any issue refs from the direct commits
|
||||
- before finalizing, audit the final release-note body:
|
||||
- extract all `#NNN` refs from the notes
|
||||
- resolve which refs are PRs and collect human PR authors
|
||||
- resolve issue refs used as bug/report refs and collect human reporters
|
||||
- scan represented commits for `Co-authored-by`
|
||||
- compare those handles to the final `Thanks @...` set
|
||||
- fix every missing human credit or explicitly record why it is omitted
|
||||
- do not add GHSA references, advisory IDs, or security advisory slugs to
|
||||
changelog entries or GitHub release-note text unless explicitly requested
|
||||
- never thank bots, `@openclaw`, `@clawsweeper`, or `@steipete`
|
||||
- if grouping multiple entries, carry all relevant refs and thanks into the
|
||||
grouped bullet
|
||||
- do not use GitHub's release contributor count as the source of truth; the
|
||||
changelog must carry the complete human credit set itself
|
||||
7. Sorting preference:
|
||||
- security/data-loss and content-boundary fixes
|
||||
- transcript/replay/reply delivery correctness
|
||||
|
||||
@@ -75,7 +75,9 @@ OPENCLAW_VITEST_MAX_WORKERS=1 pnpm test <path-or-filter>
|
||||
```
|
||||
|
||||
Use targeted file paths whenever possible. Avoid raw `vitest`; use the repo
|
||||
`pnpm test` wrapper so project routing, workers, and setup stay correct.
|
||||
`pnpm test` wrapper so project routing, workers, and setup stay correct. If raw
|
||||
Vitest is unavoidable, use `vitest run ...`; bare `vitest ...` starts local watch
|
||||
mode and will not exit on its own.
|
||||
When the checkout is a Codex worktree, prefer the direct node harness instead:
|
||||
|
||||
```bash
|
||||
|
||||
@@ -1,21 +1,15 @@
|
||||
profile: openclaw-check
|
||||
provider: aws
|
||||
# Default OpenClaw runner spend to the Azure-backed Crabbox account.
|
||||
# Use `--provider aws` only for AWS-specific runner proof.
|
||||
provider: azure
|
||||
class: standard
|
||||
capacity:
|
||||
market: spot
|
||||
strategy: most-available
|
||||
fallback: on-demand-after-120s
|
||||
# Fail closed instead of silently falling back to on-demand while the
|
||||
# Azure-backed billing account is the default runner path.
|
||||
fallback: spot-only
|
||||
hints: true
|
||||
availabilityZones:
|
||||
- eu-west-1a
|
||||
- eu-west-1b
|
||||
- eu-west-1c
|
||||
regions:
|
||||
- eu-west-1
|
||||
- eu-west-2
|
||||
- eu-central-1
|
||||
- us-east-1
|
||||
- us-west-2
|
||||
actions:
|
||||
workflow: .github/workflows/crabbox-hydrate.yml
|
||||
# Default AWS hydration uses local Actions replay. Use
|
||||
@@ -35,6 +29,8 @@ blacksmith:
|
||||
job: check
|
||||
ref: main
|
||||
aws:
|
||||
# AWS-specific overrides still pin direct `--provider aws` runs without
|
||||
# leaking AWS region names into the Azure default capacity fallback list.
|
||||
region: eu-west-1
|
||||
rootGB: 400
|
||||
sync:
|
||||
|
||||
10
.github/labeler.yml
vendored
10
.github/labeler.yml
vendored
@@ -355,6 +355,11 @@
|
||||
- any-glob-to-any-file:
|
||||
- "extensions/deepinfra/**"
|
||||
- "docs/providers/deepinfra.md"
|
||||
"extensions: gmi":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- "extensions/gmi/**"
|
||||
- "docs/providers/gmi.md"
|
||||
"extensions: tencent":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
@@ -436,6 +441,11 @@
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- "extensions/nvidia/**"
|
||||
"extensions: novita":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
- "extensions/novita/**"
|
||||
- "docs/providers/novita.md"
|
||||
"extensions: phone-control":
|
||||
- changed-files:
|
||||
- any-glob-to-any-file:
|
||||
|
||||
@@ -27,7 +27,7 @@ jobs:
|
||||
timeout-minutes: 35
|
||||
steps:
|
||||
- name: Begin Testbox
|
||||
uses: useblacksmith/begin-testbox@d0e04585c26905fdd92c94a09c159544c7ee1b67
|
||||
uses: useblacksmith/begin-testbox@233448af4bfdc6fca509a7f0974411ac6d8a8043
|
||||
with:
|
||||
testbox_id: ${{ inputs.testbox_id }}
|
||||
|
||||
@@ -231,7 +231,7 @@ jobs:
|
||||
run: bash scripts/ci-hydrate-testbox-env.sh
|
||||
|
||||
- name: Run Testbox
|
||||
uses: useblacksmith/run-testbox@5ca05834db1d3813554d1dd109e5f2087a8d7cbc
|
||||
uses: useblacksmith/run-testbox@3f60ff9ceb2c10c3feefa87dc0c6490cffae059d
|
||||
if: success()
|
||||
env:
|
||||
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
|
||||
|
||||
4
.github/workflows/ci-check-testbox.yml
vendored
4
.github/workflows/ci-check-testbox.yml
vendored
@@ -26,7 +26,7 @@ jobs:
|
||||
timeout-minutes: 30
|
||||
steps:
|
||||
- name: Begin Testbox
|
||||
uses: useblacksmith/begin-testbox@d0e04585c26905fdd92c94a09c159544c7ee1b67
|
||||
uses: useblacksmith/begin-testbox@233448af4bfdc6fca509a7f0974411ac6d8a8043
|
||||
with:
|
||||
testbox_id: ${{ inputs.testbox_id }}
|
||||
- name: Checkout
|
||||
@@ -133,7 +133,7 @@ jobs:
|
||||
run: bash scripts/ci-hydrate-testbox-env.sh
|
||||
|
||||
- name: Run Testbox
|
||||
uses: useblacksmith/run-testbox@5ca05834db1d3813554d1dd109e5f2087a8d7cbc
|
||||
uses: useblacksmith/run-testbox@3f60ff9ceb2c10c3feefa87dc0c6490cffae059d
|
||||
if: success()
|
||||
env:
|
||||
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
|
||||
|
||||
38
.github/workflows/ci.yml
vendored
38
.github/workflows/ci.yml
vendored
@@ -601,7 +601,7 @@ jobs:
|
||||
uses: actions/cache@v5
|
||||
with:
|
||||
path: .artifacts/build-all-cache
|
||||
key: ${{ runner.os }}-build-all-v3-${{ hashFiles('package.json', 'pnpm-lock.yaml', 'npm-shrinkwrap.json', 'packages/plugin-sdk/package.json', 'packages/memory-host-sdk/package.json', 'scripts/build-all.mjs', 'scripts/write-plugin-sdk-entry-dts.ts', 'scripts/lib/plugin-sdk-entries.mjs', 'tsconfig.json', 'tsconfig.plugin-sdk.dts.json', 'src/plugin-sdk/**', 'packages/memory-host-sdk/src/**', 'src/types/**', 'src/video-generation/dashscope-compatible.ts', 'src/video-generation/types.ts', 'scripts/copy-export-html-templates.ts', 'scripts/lib/copy-assets.ts', 'src/auto-reply/reply/export-html/**') }}
|
||||
key: ${{ runner.os }}-build-all-v3-${{ hashFiles('package.json', 'pnpm-lock.yaml', 'npm-shrinkwrap.json', 'packages/plugin-sdk/package.json', 'packages/llm-core/package.json', 'packages/model-catalog-core/package.json', 'packages/memory-host-sdk/package.json', 'scripts/build-all.mjs', 'scripts/write-plugin-sdk-entry-dts.ts', 'scripts/lib/plugin-sdk-entries.mjs', 'tsconfig.json', 'tsconfig.plugin-sdk.dts.json', 'src/plugin-sdk/**', 'packages/llm-core/src/**', 'packages/model-catalog-core/src/**', 'packages/memory-host-sdk/src/**', 'src/types/**', 'src/video-generation/dashscope-compatible.ts', 'src/video-generation/types.ts', 'scripts/copy-export-html-templates.ts', 'scripts/lib/copy-assets.ts', 'src/auto-reply/reply/export-html/**') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-build-all-v3-
|
||||
|
||||
@@ -834,10 +834,10 @@ jobs:
|
||||
;;
|
||||
contracts-plugins-ci-routing)
|
||||
pnpm test:contracts:plugins
|
||||
pnpm test src/commands/status.scan-result.test.ts src/scripts/ci-changed-scope.test.ts test/scripts/test-projects.test.ts
|
||||
pnpm test src/commands/status.scan-result.test.ts src/scripts/ci-changed-scope.test.ts test/scripts/changed-lanes.test.ts test/scripts/run-vitest.test.ts test/scripts/test-projects.test.ts
|
||||
;;
|
||||
ci-routing)
|
||||
pnpm test src/commands/status.scan-result.test.ts src/scripts/ci-changed-scope.test.ts test/scripts/test-projects.test.ts
|
||||
pnpm test src/commands/status.scan-result.test.ts src/scripts/ci-changed-scope.test.ts test/scripts/changed-lanes.test.ts test/scripts/run-vitest.test.ts test/scripts/test-projects.test.ts
|
||||
;;
|
||||
bun-launcher)
|
||||
OPENCLAW_TEST_BUN_LAUNCHER=1 pnpm test test/openclaw-launcher.e2e.test.ts
|
||||
@@ -1151,6 +1151,7 @@ jobs:
|
||||
OPENCLAW_NODE_TEST_CONFIGS_JSON: ${{ toJson(matrix.configs) }}
|
||||
OPENCLAW_NODE_TEST_INCLUDE_PATTERNS_JSON: ${{ toJson(matrix.includePatterns) }}
|
||||
OPENCLAW_VITEST_SHARD_NAME: ${{ matrix.shard_name }}
|
||||
OPENCLAW_VITEST_NO_OUTPUT_TIMEOUT_MS: "900000"
|
||||
OPENCLAW_TEST_PROJECTS_PARALLEL: "2"
|
||||
shell: bash
|
||||
run: |
|
||||
@@ -1403,7 +1404,7 @@ jobs:
|
||||
packages/plugin-sdk/dist
|
||||
extensions/*/dist/.boundary-tsc.tsbuildinfo
|
||||
extensions/*/dist/.boundary-tsc.stamp
|
||||
key: ${{ runner.os }}-extension-package-boundary-v1-${{ hashFiles('tsconfig.json', 'tsconfig.plugin-sdk.dts.json', 'packages/plugin-sdk/tsconfig.json', 'scripts/check-extension-package-tsc-boundary.mjs', 'scripts/prepare-extension-package-boundary-artifacts.mjs', 'scripts/write-plugin-sdk-entry-dts.ts', 'scripts/lib/plugin-sdk-entrypoints.json', 'scripts/lib/plugin-sdk-entries.mjs', 'src/plugin-sdk/**', 'src/auto-reply/**', 'src/video-generation/dashscope-compatible.ts', 'src/video-generation/types.ts', 'src/types/**', 'extensions/**', 'extensions/tsconfig.package-boundary*.json', 'package.json', 'pnpm-lock.yaml') }}
|
||||
key: ${{ runner.os }}-extension-package-boundary-v1-${{ hashFiles('tsconfig.json', 'tsconfig.plugin-sdk.dts.json', 'packages/plugin-sdk/tsconfig.json', 'packages/llm-core/package.json', 'packages/model-catalog-core/package.json', 'scripts/check-extension-package-tsc-boundary.mjs', 'scripts/prepare-extension-package-boundary-artifacts.mjs', 'scripts/write-plugin-sdk-entry-dts.ts', 'scripts/lib/plugin-sdk-entrypoints.json', 'scripts/lib/plugin-sdk-entries.mjs', 'src/plugin-sdk/**', 'src/auto-reply/**', 'packages/llm-core/src/**', 'packages/model-catalog-core/src/**', 'src/video-generation/dashscope-compatible.ts', 'src/video-generation/types.ts', 'src/types/**', 'extensions/**', 'extensions/tsconfig.package-boundary*.json', 'package.json', 'pnpm-lock.yaml') }}
|
||||
restore-keys: |
|
||||
${{ runner.os }}-extension-package-boundary-v1-
|
||||
|
||||
@@ -1420,10 +1421,22 @@ jobs:
|
||||
find src \
|
||||
-type f \( -name '*.ts' -o -name '*.tsx' -o -name '*.mts' -o -name '*.cts' -o -name '*.js' -o -name '*.mjs' -o -name '*.json' \) \
|
||||
-exec touch -t 200001010000 {} +
|
||||
touch -t 200001010000 \
|
||||
if [ -d packages/llm-core/src ]; then
|
||||
find packages/llm-core/src \
|
||||
-type f \( -name '*.ts' -o -name '*.tsx' -o -name '*.mts' -o -name '*.cts' -o -name '*.js' -o -name '*.mjs' -o -name '*.json' \) \
|
||||
-exec touch -t 200001010000 {} +
|
||||
fi
|
||||
if [ -d packages/model-catalog-core/src ]; then
|
||||
find packages/model-catalog-core/src \
|
||||
-type f \( -name '*.ts' -o -name '*.tsx' -o -name '*.mts' -o -name '*.cts' -o -name '*.js' -o -name '*.mjs' -o -name '*.json' \) \
|
||||
-exec touch -t 200001010000 {} +
|
||||
fi
|
||||
cache_inputs=(
|
||||
tsconfig.json \
|
||||
tsconfig.plugin-sdk.dts.json \
|
||||
packages/plugin-sdk/tsconfig.json \
|
||||
packages/llm-core/package.json \
|
||||
packages/model-catalog-core/package.json \
|
||||
scripts/check-extension-package-tsc-boundary.mjs \
|
||||
scripts/prepare-extension-package-boundary-artifacts.mjs \
|
||||
scripts/write-plugin-sdk-entry-dts.ts \
|
||||
@@ -1431,6 +1444,12 @@ jobs:
|
||||
scripts/lib/plugin-sdk-entries.mjs \
|
||||
package.json \
|
||||
pnpm-lock.yaml
|
||||
)
|
||||
for cache_input in "${cache_inputs[@]}"; do
|
||||
if [ -e "$cache_input" ]; then
|
||||
touch -t 200001010000 "$cache_input"
|
||||
fi
|
||||
done
|
||||
|
||||
- name: Run additional check shard
|
||||
env:
|
||||
@@ -1672,6 +1691,7 @@ jobs:
|
||||
git init "$GITHUB_WORKSPACE"
|
||||
git -C "$GITHUB_WORKSPACE" config gc.auto 0
|
||||
git -C "$GITHUB_WORKSPACE" remote add origin "https://github.com/${CHECKOUT_REPO}.git"
|
||||
fetch_timeout_seconds=90
|
||||
fetch_checkout_ref() {
|
||||
git -C "$GITHUB_WORKSPACE" \
|
||||
-c protocol.version=2 \
|
||||
@@ -1680,7 +1700,7 @@ jobs:
|
||||
local fetch_pid="$!"
|
||||
local elapsed=0
|
||||
while kill -0 "$fetch_pid" 2>/dev/null; do
|
||||
if [ "$elapsed" -ge 30 ]; then
|
||||
if [ "$elapsed" -ge "$fetch_timeout_seconds" ]; then
|
||||
kill -TERM "$fetch_pid" 2>/dev/null || true
|
||||
sleep 10
|
||||
kill -KILL "$fetch_pid" 2>/dev/null || true
|
||||
@@ -1792,6 +1812,7 @@ jobs:
|
||||
git init "$GITHUB_WORKSPACE"
|
||||
git -C "$GITHUB_WORKSPACE" config gc.auto 0
|
||||
git -C "$GITHUB_WORKSPACE" remote add origin "https://github.com/${CHECKOUT_REPO}.git"
|
||||
fetch_timeout_seconds=90
|
||||
fetch_checkout_ref() {
|
||||
git -C "$GITHUB_WORKSPACE" \
|
||||
-c protocol.version=2 \
|
||||
@@ -1800,7 +1821,7 @@ jobs:
|
||||
local fetch_pid="$!"
|
||||
local elapsed=0
|
||||
while kill -0 "$fetch_pid" 2>/dev/null; do
|
||||
if [ "$elapsed" -ge 30 ]; then
|
||||
if [ "$elapsed" -ge "$fetch_timeout_seconds" ]; then
|
||||
kill -TERM "$fetch_pid" 2>/dev/null || true
|
||||
sleep 10
|
||||
kill -KILL "$fetch_pid" 2>/dev/null || true
|
||||
@@ -1858,6 +1879,7 @@ jobs:
|
||||
git init "$GITHUB_WORKSPACE"
|
||||
git -C "$GITHUB_WORKSPACE" config gc.auto 0
|
||||
git -C "$GITHUB_WORKSPACE" remote add origin "https://github.com/${CHECKOUT_REPO}.git"
|
||||
fetch_timeout_seconds=90
|
||||
fetch_checkout_ref() {
|
||||
git -C "$GITHUB_WORKSPACE" \
|
||||
-c protocol.version=2 \
|
||||
@@ -1866,7 +1888,7 @@ jobs:
|
||||
local fetch_pid="$!"
|
||||
local elapsed=0
|
||||
while kill -0 "$fetch_pid" 2>/dev/null; do
|
||||
if [ "$elapsed" -ge 30 ]; then
|
||||
if [ "$elapsed" -ge "$fetch_timeout_seconds" ]; then
|
||||
kill -TERM "$fetch_pid" 2>/dev/null || true
|
||||
sleep 10
|
||||
kill -KILL "$fetch_pid" 2>/dev/null || true
|
||||
|
||||
@@ -302,6 +302,8 @@ jobs:
|
||||
esac
|
||||
|
||||
case "${file}" in
|
||||
src/**/*.test.ts|src/**/*.test.tsx|extensions/**/*.test.ts|extensions/**/*.test.tsx)
|
||||
;;
|
||||
src/*.ts|src/**/*.ts|extensions/*.ts|extensions/**/*.ts|packages/net-policy/src/*|packages/net-policy/src/**/*)
|
||||
network_runtime=true
|
||||
;;
|
||||
|
||||
80
.github/workflows/dependency-guard.yml
vendored
80
.github/workflows/dependency-guard.yml
vendored
@@ -14,10 +14,85 @@ concurrency:
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
dependency-guard:
|
||||
dependency-guard-detect:
|
||||
if: ${{ !github.event.pull_request.draft }}
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 5
|
||||
outputs:
|
||||
autoscrub: ${{ steps.guard.outputs.autoscrub }}
|
||||
autoscrub-owner: ${{ steps.guard.outputs.autoscrub-owner }}
|
||||
autoscrub-repository: ${{ steps.guard.outputs.autoscrub-repository }}
|
||||
steps:
|
||||
- name: Check out trusted base workflow scripts
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.base.sha }}
|
||||
persist-credentials: false
|
||||
|
||||
- name: Detect dependency changes
|
||||
id: guard
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
OPENCLAW_DEPENDENCY_GUARD_MODE: detect
|
||||
OPENCLAW_SECURITY_APPROVERS: vincentkoc,steipete,joshavant
|
||||
OPENCLAW_SECURITY_TEAM_SLUG: openclaw-secops
|
||||
run: node scripts/github/dependency-guard.mjs
|
||||
|
||||
dependency-guard-autoscrub:
|
||||
if: ${{ !github.event.pull_request.draft && needs.dependency-guard-detect.outputs.autoscrub == 'true' }}
|
||||
needs: dependency-guard-detect
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 5
|
||||
permissions:
|
||||
contents: read
|
||||
issues: write
|
||||
pull-requests: read
|
||||
steps:
|
||||
- name: Check out trusted base workflow scripts
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
with:
|
||||
ref: ${{ github.event.pull_request.base.sha }}
|
||||
persist-credentials: false
|
||||
|
||||
- name: Create autoscrub app token
|
||||
id: app-token
|
||||
continue-on-error: true
|
||||
uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1
|
||||
with:
|
||||
app-id: "2729701"
|
||||
private-key: ${{ secrets.GH_APP_PRIVATE_KEY }}
|
||||
owner: ${{ needs.dependency-guard-detect.outputs.autoscrub-owner }}
|
||||
repositories: ${{ needs.dependency-guard-detect.outputs.autoscrub-repository }}
|
||||
permission-contents: write
|
||||
|
||||
- name: Create fallback autoscrub app token
|
||||
id: app-token-fallback
|
||||
continue-on-error: true
|
||||
if: steps.app-token.outcome == 'failure'
|
||||
uses: actions/create-github-app-token@1b10c78c7865c340bc4f6099eb2f838309f1e8c3 # v3.1.1
|
||||
with:
|
||||
app-id: "2971289"
|
||||
private-key: ${{ secrets.GH_APP_PRIVATE_KEY_FALLBACK }}
|
||||
owner: ${{ needs.dependency-guard-detect.outputs.autoscrub-owner }}
|
||||
repositories: ${{ needs.dependency-guard-detect.outputs.autoscrub-repository }}
|
||||
permission-contents: write
|
||||
|
||||
- name: Remove package lockfile changes
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
OPENCLAW_DEPENDENCY_GUARD_AUTOSCRUB_TOKEN: ${{ steps.app-token.outputs.token || steps.app-token-fallback.outputs.token }}
|
||||
OPENCLAW_DEPENDENCY_GUARD_MODE: autoscrub
|
||||
OPENCLAW_SECURITY_APPROVERS: vincentkoc,steipete,joshavant
|
||||
OPENCLAW_SECURITY_TEAM_SLUG: openclaw-secops
|
||||
run: node scripts/github/dependency-guard.mjs
|
||||
|
||||
dependency-guard:
|
||||
if: ${{ !github.event.pull_request.draft && always() }}
|
||||
needs:
|
||||
- dependency-guard-detect
|
||||
- dependency-guard-autoscrub
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- name: Check out trusted base workflow scripts
|
||||
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
|
||||
@@ -25,9 +100,10 @@ jobs:
|
||||
ref: ${{ github.event.pull_request.base.sha }}
|
||||
persist-credentials: false
|
||||
|
||||
- name: Label, comment, and guard dependency changes
|
||||
- name: Enforce dependency guard
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
OPENCLAW_DEPENDENCY_GUARD_MODE: enforce
|
||||
OPENCLAW_SECURITY_APPROVERS: vincentkoc,steipete,joshavant
|
||||
OPENCLAW_SECURITY_TEAM_SLUG: openclaw-secops
|
||||
run: node scripts/github/dependency-guard.mjs
|
||||
|
||||
12
.github/workflows/openclaw-npm-release.yml
vendored
12
.github/workflows/openclaw-npm-release.yml
vendored
@@ -372,6 +372,11 @@ jobs:
|
||||
actions: read
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Require trusted workflow ref for publish
|
||||
env:
|
||||
RELEASE_TAG: ${{ inputs.tag }}
|
||||
@@ -429,12 +434,13 @@ jobs:
|
||||
echo "Direct OpenClaw npm publish; relying on this workflow's npm-release environment approval."
|
||||
exit 0
|
||||
fi
|
||||
direct_recovery=false
|
||||
if [[ "${GITHUB_ACTOR}" != "github-actions[bot]" ]]; then
|
||||
echo "OpenClaw npm publish must be dispatched by the OpenClaw Release Publish workflow, not directly by ${GITHUB_ACTOR}." >&2
|
||||
exit 1
|
||||
direct_recovery=true
|
||||
echo "Direct OpenClaw npm recovery with release_publish_run_id; relying on this workflow's npm-release environment approval."
|
||||
fi
|
||||
RUN_JSON="$(gh run view "$RELEASE_PUBLISH_RUN_ID" --repo "$GITHUB_REPOSITORY" --json workflowName,headBranch,event,status,conclusion,url)"
|
||||
printf '%s' "$RUN_JSON" | node -e 'const fs = require("node:fs"); const run = JSON.parse(fs.readFileSync(0, "utf8")); const checks = [["workflowName", "OpenClaw Release Publish"], ["headBranch", process.env.EXPECTED_WORKFLOW_BRANCH], ["event", "workflow_dispatch"]]; for (const [key, expected] of checks) { if (run[key] !== expected) { console.error(`Referenced release publish run ${process.env.RELEASE_PUBLISH_RUN_ID} must have ${key}=${expected}, got ${run[key] ?? "<missing>"}.`); process.exit(1); } } if (run.status !== "in_progress") { console.error(`Referenced release publish run ${process.env.RELEASE_PUBLISH_RUN_ID} must still be in_progress, got ${run.status ?? "<missing>"}.`); process.exit(1); } if (run.conclusion) { console.error(`Referenced release publish run ${process.env.RELEASE_PUBLISH_RUN_ID} already concluded ${run.conclusion}.`); process.exit(1); } console.log(`Using release publish approval run ${process.env.RELEASE_PUBLISH_RUN_ID}: ${run.url}`);'
|
||||
printf '%s' "$RUN_JSON" | DIRECT_RELEASE_RECOVERY="${direct_recovery}" node scripts/validate-release-publish-approval.mjs
|
||||
|
||||
publish_openclaw_npm:
|
||||
# KEEP THE REAL RELEASE/PUBLISH PATH ON A GITHUB-HOSTED RUNNER.
|
||||
|
||||
12
.github/workflows/plugin-clawhub-release.yml
vendored
12
.github/workflows/plugin-clawhub-release.yml
vendored
@@ -207,6 +207,11 @@ jobs:
|
||||
actions: read
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Validate release publish approval run
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
@@ -222,12 +227,13 @@ jobs:
|
||||
echo "Direct Plugin ClawHub Release dispatch; relying on this workflow's clawhub-plugin-release environment approval."
|
||||
exit 0
|
||||
fi
|
||||
direct_recovery=false
|
||||
if [[ "${GITHUB_ACTOR}" != "github-actions[bot]" ]]; then
|
||||
echo "Plugin ClawHub publish must be dispatched by the OpenClaw Release Publish workflow, not directly by ${GITHUB_ACTOR}." >&2
|
||||
exit 1
|
||||
direct_recovery=true
|
||||
echo "Direct Plugin ClawHub Release recovery with release_publish_run_id; relying on this workflow's clawhub-plugin-release environment approval."
|
||||
fi
|
||||
RUN_JSON="$(gh run view "$RELEASE_PUBLISH_RUN_ID" --repo "$GITHUB_REPOSITORY" --json workflowName,headBranch,event,status,conclusion,url)"
|
||||
printf '%s' "$RUN_JSON" | node -e 'const fs = require("node:fs"); const run = JSON.parse(fs.readFileSync(0, "utf8")); const checks = [["workflowName", "OpenClaw Release Publish"], ["headBranch", process.env.EXPECTED_WORKFLOW_BRANCH], ["event", "workflow_dispatch"]]; for (const [key, expected] of checks) { if (run[key] !== expected) { console.error(`Referenced release publish run ${process.env.RELEASE_PUBLISH_RUN_ID} must have ${key}=${expected}, got ${run[key] ?? "<missing>"}.`); process.exit(1); } } if (run.status !== "in_progress") { console.error(`Referenced release publish run ${process.env.RELEASE_PUBLISH_RUN_ID} must still be in_progress, got ${run.status ?? "<missing>"}.`); process.exit(1); } if (run.conclusion) { console.error(`Referenced release publish run ${process.env.RELEASE_PUBLISH_RUN_ID} already concluded ${run.conclusion}.`); process.exit(1); } console.log(`Using release publish approval run ${process.env.RELEASE_PUBLISH_RUN_ID}: ${run.url}`);'
|
||||
printf '%s' "$RUN_JSON" | DIRECT_RELEASE_RECOVERY="${direct_recovery}" node scripts/validate-release-publish-approval.mjs
|
||||
|
||||
preview_plugin_pack:
|
||||
needs: preview_plugins_clawhub
|
||||
|
||||
12
.github/workflows/plugin-npm-release.yml
vendored
12
.github/workflows/plugin-npm-release.yml
vendored
@@ -184,6 +184,11 @@ jobs:
|
||||
actions: read
|
||||
contents: read
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v6
|
||||
with:
|
||||
persist-credentials: false
|
||||
|
||||
- name: Validate release publish approval run
|
||||
env:
|
||||
GH_TOKEN: ${{ github.token }}
|
||||
@@ -199,12 +204,13 @@ jobs:
|
||||
echo "Direct Plugin NPM Release dispatch; relying on this workflow's npm-release environment approval."
|
||||
exit 0
|
||||
fi
|
||||
direct_recovery=false
|
||||
if [[ "${GITHUB_ACTOR}" != "github-actions[bot]" ]]; then
|
||||
echo "Plugin npm publish must be dispatched by the OpenClaw Release Publish workflow, not directly by ${GITHUB_ACTOR}." >&2
|
||||
exit 1
|
||||
direct_recovery=true
|
||||
echo "Direct Plugin NPM Release recovery with release_publish_run_id; relying on this workflow's npm-release environment approval."
|
||||
fi
|
||||
RUN_JSON="$(gh run view "$RELEASE_PUBLISH_RUN_ID" --repo "$GITHUB_REPOSITORY" --json workflowName,headBranch,event,status,conclusion,url)"
|
||||
printf '%s' "$RUN_JSON" | node -e 'const fs = require("node:fs"); const run = JSON.parse(fs.readFileSync(0, "utf8")); const checks = [["workflowName", "OpenClaw Release Publish"], ["headBranch", process.env.EXPECTED_WORKFLOW_BRANCH], ["event", "workflow_dispatch"]]; for (const [key, expected] of checks) { if (run[key] !== expected) { console.error(`Referenced release publish run ${process.env.RELEASE_PUBLISH_RUN_ID} must have ${key}=${expected}, got ${run[key] ?? "<missing>"}.`); process.exit(1); } } if (run.status !== "in_progress") { console.error(`Referenced release publish run ${process.env.RELEASE_PUBLISH_RUN_ID} must still be in_progress, got ${run.status ?? "<missing>"}.`); process.exit(1); } if (run.conclusion) { console.error(`Referenced release publish run ${process.env.RELEASE_PUBLISH_RUN_ID} already concluded ${run.conclusion}.`); process.exit(1); } console.log(`Using release publish approval run ${process.env.RELEASE_PUBLISH_RUN_ID}: ${run.url}`);'
|
||||
printf '%s' "$RUN_JSON" | DIRECT_RELEASE_RECOVERY="${direct_recovery}" node scripts/validate-release-publish-approval.mjs
|
||||
|
||||
preview_plugin_pack:
|
||||
needs: preview_plugins_npm
|
||||
|
||||
@@ -197,4 +197,4 @@ jobs:
|
||||
|
||||
- name: Testbox action marker
|
||||
if: ${{ false }}
|
||||
uses: useblacksmith/run-testbox@5ca05834db1d3813554d1dd109e5f2087a8d7cbc
|
||||
uses: useblacksmith/run-testbox@3f60ff9ceb2c10c3feefa87dc0c6490cffae059d
|
||||
|
||||
@@ -78,7 +78,7 @@ Skills own workflows; root owns hard policy and routing.
|
||||
- Gateway/plugin metadata is process-stable: installs, manifests, catalogs, generated paths, bundled metadata. Changes require restart or explicit owner reload/install/doctor flow.
|
||||
- Runtime hot paths: no freshness polling (`stat`/`realpath`/JSON reread/hash). Reuse current snapshots, install records, discovery, lookup tables, root scopes, resolved paths.
|
||||
- Process-local metadata caches ok when lifecycle-owned and bounded/single-slot. Freshness exceptions need named owner + tests.
|
||||
- Inline comments: preserve reviewer context at the code site. Use for cross-path/state invariants, platform/dependency caps, deterministic ordering, compact encoded state, lifecycle ordering, ownership boundaries, session/id adoption, queue-depth symmetry, fallbacks, or intentional caller differences.
|
||||
- Inline comments: preserve reviewer context at the code site. Required for non-obvious cross-path/state invariants, lifecycle ordering, ownership boundaries, queue/dedupe symmetry, TTL/cache expiry, cleanup/release coupling, session/id adoption, fallback behavior, platform/dependency caps, deterministic ordering, compact encoded state, or intentional caller differences.
|
||||
- Comment shape: 1-3 short lines; state why the branch/helper exists, what contract it protects, and the bad outcome if removed. Cite nearby constants/helpers when useful. No syntax narration, PR/user-specific lore, or obvious mechanics.
|
||||
- Gateway protocol changes: additive first; incompatible needs versioning/docs/client follow-through.
|
||||
- Protocol version bumps: explicit owner confirmation only; never automatic/generated.
|
||||
@@ -93,6 +93,7 @@ Skills own workflows; root owns hard policy and routing.
|
||||
- Install: `pnpm install` (keep Bun lock/patches aligned if touched).
|
||||
- CLI: `pnpm openclaw ...` or `pnpm dev`; build: `pnpm build`.
|
||||
- Tests in a normal source checkout: `pnpm test <path-or-filter> [vitest args...]`, `pnpm test:changed`, `pnpm test:serial`, `pnpm test:coverage`; never raw `vitest`.
|
||||
- If raw Vitest is unavoidable, use `vitest run ...`; bare `vitest ...` starts local watch mode and will not exit on its own.
|
||||
- Tests in a Codex worktree or linked/sparse checkout: avoid direct local `pnpm test*`; use `node scripts/run-vitest.mjs <path-or-filter>` for tiny explicit-file proof, or Crabbox/Testbox for anything broader.
|
||||
- Checks in a normal source checkout: `pnpm check:changed`; lanes: `pnpm changed:lanes --json`; staged: `pnpm check:changed --staged`; full: `pnpm check`.
|
||||
- Checks in a Codex worktree or linked/sparse checkout: avoid direct local `pnpm check*`; use `node scripts/crabbox-wrapper.mjs run ... --shell -- "pnpm check:changed"` so pnpm runs inside Testbox, not locally.
|
||||
|
||||
100
CHANGELOG.md
100
CHANGELOG.md
@@ -2,29 +2,77 @@
|
||||
|
||||
Docs: https://docs.openclaw.ai
|
||||
|
||||
## Unreleased
|
||||
## 2026.5.30
|
||||
|
||||
### Highlights
|
||||
|
||||
- Agents and CLI-backed runtimes recover more cleanly from interrupted tool calls, stale session bindings, compaction handoffs, and media delivery retries. (#88129, #88136, #88141, #88162, #88182)
|
||||
- Channels and mobile delivery are steadier across Telegram, WhatsApp, iMessage, Slack, Discord, Microsoft Teams, Google Chat, Google Meet, and iOS realtime Talk. (#88096, #88105, #88183, #88231)
|
||||
- Provider and plugin requests now bound more timers, retries, OAuth/device-code lifetimes, media downloads, local service probes, and generated-content polling paths before they can hang a run.
|
||||
- Skills, session metadata, gateway runtime state, plugin metadata, and store writes do less repeated work on hot paths while keeping config and dispatch behavior stable.
|
||||
- Workboard, SecretRef plugin manifests, hosted iOS push relay, and external Copilot/Tokenjuice packaging add broader orchestration, integration, and plugin delivery surfaces. (#82326, #87469, #87796, #88107, #88117)
|
||||
- Release, CI, Docker, E2E, and diagnostics lanes now cap more logs, response bodies, readiness probes, artifact checks, and status polling so failures report bounded proof instead of stalling.
|
||||
|
||||
### Changes
|
||||
|
||||
- Skills: let the `skill_research` agent tool apply, reject, and quarantine explicit Skill Workshop proposals through the guarded proposal lifecycle. Thanks @shakkernerd.
|
||||
- Skills: let Skill Workshop proposals carry approved support files under standard skill folders, with scanner, hash, and rollback safeguards. Thanks @shakkernerd.
|
||||
- Skills: let pending Skill Workshop proposals be revised in place with versioned, dated proposal frontmatter before approval. Thanks @shakkernerd.
|
||||
- Skills: add Skill Workshop proposals with pending `PROPOSAL.md` drafts, CLI/Gateway review actions, rollback metadata, and the `skill_research` agent tool. Thanks @shakkernerd.
|
||||
- Plugins: externalize Tokenjuice as the official `@openclaw/tokenjuice` plugin with npm and ClawHub publish metadata.
|
||||
- Plugins: externalize the GitHub Copilot agent runtime as the official `@openclaw/copilot` plugin with npm and ClawHub publish metadata.
|
||||
- iOS: add hosted push relay defaults, realtime Talk playback, and a guarded WebSocket ping path for more reliable mobile sessions. (#88096, #88105, #88231)
|
||||
- Workboard: add orchestration primitives and agent coordination tools for multi-agent planning and run tracking. (#87469)
|
||||
- Code mode: add internal namespaces for scoped agent/global sessions and exact namespace tool dispatch. (#88043)
|
||||
- Control UI: add a Dreaming-tab agent selector and propagate the selected agent through Dreaming status, diary, and diary actions. (#78748) Thanks @stevenepalmer.
|
||||
- Plugins: add a SecretRef provider integration manifest contract and extract shared LLM core packages for provider/plugin reuse. (#82326, #88117)
|
||||
- Skills: add the core skills index and centralize skills runtime loading, status, filtering, and prompt formatting.
|
||||
|
||||
### Fixes
|
||||
|
||||
- CLI: keep `plugins list --json` on the snapshot-only path so plugin sweeps avoid loading the full runtime status graph.
|
||||
- Plugins: make PixVerse external-plugin ClawHub metadata explicit and keep it out of bundled dist builds.
|
||||
- Cron: keep SQLite cron migrations compatible with legacy run-log tables, archived job stores, diagnostic cron names, and legacy one-shot delete-after-run behavior. (#88285)
|
||||
- Providers: bound generated media downloads from OpenAI, Runway, xAI, MiniMax, BytePlus, DashScope-compatible, FAL, OpenRouter, Google, Vydra, and Comfy providers.
|
||||
- Providers: cap GitHub Copilot OAuth request timeouts before creating abort signals.
|
||||
- Cron: retry recurring jobs after transient model rate limits before waiting for the next scheduled slot.
|
||||
- Agents/Codex: keep live session locks during cleanup, recover interrupted CLI tool transcripts, preserve Codex auth and compaction session identity, clear orphan tool state, cap app-server idle timers, and keep media completion delivery retryable. (#88129, #88136, #88141, #88162, #88182)
|
||||
- Chat/UI: show Gateway chat failures as visible assistant messages in the Control UI instead of only setting an invisible error state.
|
||||
- Channels: cap Telegram, Discord, WhatsApp, Signal, Feishu, Google Chat, Microsoft Teams, QQBot, Nostr, Zalo, Zalouser, and Nextcloud-style request/retry timers; preserve SMS approval reply routes; and retry WhatsApp QR login 408 timeouts. (#88183)
|
||||
- Security/config parsing: reject unsafe OAuth/token lifetimes, retry-after delays, inbound timestamps, response body sizes, command timeout config, sandbox observer token TTLs, and gateway WebSocket calls after close.
|
||||
- Providers/media: cap local service, model, usage, queue, generated media, TTS, music, workflow polling, and provider OAuth request timers across hosted and local providers.
|
||||
- Release/CI/E2E: bound release candidate reads, beta smoke REST calls, changelog restore, kitchen-sink and bundled plugin readiness probes, secret-provider probes, Vitest routing, and mainline test flakes. (#88127, #88137, #88155, #88160)
|
||||
- Release/CI/E2E: run the secret-provider integration proof through the repo pnpm runner so native macOS and Windows validation use the hydrated package-manager shim.
|
||||
- Release/CI/E2E: run the Telegram desktop proof gateway through the repo pnpm runner so native macOS proof uses the hydrated package-manager shim.
|
||||
- Docs/CI: run Mintlify anchor checks through the repo pnpm runner so docs link validation works when pnpm is only available through the hydrated package-manager shim.
|
||||
- Agents: keep configured fallback model metadata typed so provider params, context-token caps, and media input limits do not break changed-gate typechecks.
|
||||
- Agents: accept hidden `sessions_send` body aliases before validation while keeping the model-facing `message` schema canonical. (#88229) Thanks @zhangguiping-xydt.
|
||||
- CI/Crabbox: keep default runner capacity spot-only and provider-neutral so OpenClaw remote validation does not silently fall back to on-demand leases or stale AWS region hints.
|
||||
- CI/Crabbox: route Crabbox wrapper and Testbox workflow edits to their regression tests so changed-test gates do not silently run zero specs.
|
||||
- CI/workflows: route workflow sanity helper edits to their guard tests and cover composite-action input interpolation checks.
|
||||
- CI/tooling: route CI scope, dependency, changelog, and docs helper edits to their owner tests instead of silently skipping changed-test coverage.
|
||||
- CI/tooling: route package, release, and install helper edits to their owner tests so changed-test gates cover publish and installer script changes.
|
||||
- CI/tooling: route shared script library edits through their owner tests so lock, process, safety, and scan helpers do not skip changed-test coverage.
|
||||
- CI/tooling: skip expensive import-graph scans once a changed diff already requires broad fallback, keeping local changed-test planning fast while still collecting explicit owner tests.
|
||||
- CI/tooling: route script edits through conventional owner tests when matching `test/scripts` or `src/scripts` coverage already exists.
|
||||
- CI/tooling: honor option terminators in the memory FD repro script so follow-on arguments are not reparsed.
|
||||
- Release/CI/E2E: honor option terminators across release, Parallels smoke, plugin gauntlet, and extension-memory scripts.
|
||||
- Release/CI/E2E: fail plugin gateway gauntlet QA chunks when the requested suite summary is missing or invalid.
|
||||
- Performance: prebuild QA runtime probes with generated plugin assets but without CLI startup metadata.
|
||||
- Performance: skip declaration bundling for runtime-only CLI startup and gateway watch build profiles.
|
||||
- Performance: reuse prepared provider handles, strict tool schemas, gateway runtime metadata, session maintenance config, plugin metadata, bundled skill allowlists, package-local plugin artifacts, single-entry store writes, and validated/serialized session prompt blobs.
|
||||
|
||||
## 2026.5.28
|
||||
|
||||
### Highlights
|
||||
|
||||
- Agent and Codex runtime recovery is steadier: subagents keep cwd/workspace separation, hook context stays prompt-local, session locks release on timeout abort, stale restart continuations are avoided, and Codex app-server/helper failures no longer tear down shared runtime state. (#87218, #86875, #87409, #87399, #87375)
|
||||
- Channel delivery and session identity got safer across outbound plugin hooks, Matrix room ids, iMessage reactions/approvals, Slack final replies, Discord recovered tool warnings, and Microsoft Teams service URL trust checks. (#73706, #75670, #87366, #87451, #87334)
|
||||
- Mobile and chat surfaces got a broader refresh: the iOS Pro UI, Gateway chat transport, onboarding, Talk permissions, WebChat reconnect delivery, and session picker behavior now preserve more state across reconnects and empty searches. (#87367, #87531, #87682)
|
||||
- CLI, auth, doctor, and provider paths fail faster and recover more clearly: malformed numeric/version options are rejected, OAuth and local service startup requests are bounded, legacy `api_key` auth profiles migrate to canonical form, and restart guidance is actionable. (#87398, #86281, #87361)
|
||||
- Plugin and Gateway hot paths do less repeated work while preserving cache correctness for install records, config JSON parsing, tool search catalogs, session stores, manifest model rows, auto-enabled plugin config, browser tokens, and viewer assets. (#86699)
|
||||
- Agent and Codex runtime recovery is steadier: subagents keep cwd/workspace separation, hook context stays prompt-local, session locks release on timeout abort while live OpenClaw locks survive cleanup, stale restart continuations are avoided, and Codex app-server/helper failures no longer tear down shared runtime state. (#87218, #86875, #87409, #87399, #87375, #88129)
|
||||
- Channel delivery and session identity got safer across outbound plugin hooks, Matrix room ids, iMessage reactions/approvals, Slack final replies, Discord recovered tool warnings, runtime-config message actions, WhatsApp profile auth roots, Telegram polling, and Microsoft Teams service URL trust checks. (#73706, #75670, #87366, #87451, #87334, #84535, #82492, #83304, #87160)
|
||||
- Mobile and chat surfaces got a broader refresh: the iOS Pro UI, hosted push relay default, realtime Talk tab playback, Gateway chat transport, onboarding, Talk permissions, WebChat reconnect delivery, and session picker behavior now preserve more state across reconnects and empty searches. (#87367, #87531, #87682, #88096, #88105) Thanks @ngutman and @BunsDev.
|
||||
- Browser, channel, and automation inputs are stricter: Browser tool timeouts, viewport/tab indices, Gateway ports, cron retry handling, Discord component ids, schema array refs, Telegram callback pages, and channel progress callbacks now reject malformed values earlier and preserve the intended delivery context. (#82887)
|
||||
- Provider, media, and document coverage expands with Claude Opus 4.8, Fal Krea image schemas, NVIDIA featured models, MiniMax streaming music responses, encrypted PDF extraction, voice model catalogs, GitHub Copilot agent runtime support, and a Codex Supervisor plugin path for delegated Codex workflows. (#87845, #87890, #80775, #84764, #87751, #87794)
|
||||
- CLI, auth, doctor, and provider paths fail faster and recover more clearly: malformed numeric/version options are rejected, workspace dotenv provider credentials are ignored, heartbeat defaults, OAuth/token lifetimes, and local service startup requests are bounded, agent auth health labels are clearer, legacy `api_key` auth profiles migrate to canonical form, and restart guidance is actionable. (#87398, #86281, #87361, #88133, #83655, #87559, #88088, #85924) Thanks @vincentkoc and @giodl73-repo.
|
||||
- Plugin and Gateway hot paths do less repeated work while preserving cache correctness for install records, config JSON parsing, tool search catalogs, session stores, manifest model rows, auto-enabled plugin config, browser tokens, viewer assets, and release-split external plugin packages. (#86699)
|
||||
- Release, QA, and E2E validation now bound more log, artifact, harness, and cross-OS waits so failing lanes produce proof instead of hanging or false-greening.
|
||||
|
||||
### Changes
|
||||
@@ -32,25 +80,41 @@ Docs: https://docs.openclaw.ai
|
||||
- Status: show active subagent details in status output.
|
||||
- Diffs: split the default language pack and expand default Diffs language coverage while keeping the host floor aligned. (#87370, #87372) Thanks @RomneyDa.
|
||||
- ClawHub: add plugin display names plus skill verification and trust surfaces. (#87354, #86699) Thanks @thewilloftheshadow and @Patrick-Erichsen.
|
||||
- iOS: refresh the dev app with Pro Command, Chat, Agents, and Settings tabs wired to gateway sessions, diagnostics, chat, and realtime Talk. (#87367) Thanks @Solvely-Colin.
|
||||
- Docs: clarify Codex computer-use setup, paste-token stdin auth setup, macOS gateway sleep troubleshooting, native Codex hook relay recovery, container model auth, install deployment cards, device-token admin gating, and backport targets. (#87313, #63050) Thanks @bdjben, @liaoandi, and @thewilloftheshadow.
|
||||
- PDF/tools: use ClawPDF for PDF extraction and surface MCP structured content in agent tool results. (#87670)
|
||||
- iOS: refresh the dev app with Pro Command, Chat, Agents, Settings, hosted push relay defaults, and realtime Talk playback wired to gateway sessions, diagnostics, chat, and realtime Talk. (#87367, #88096, #88105) Thanks @Solvely-Colin and @ngutman.
|
||||
- Docs: clarify Codex computer-use setup, paste-token stdin auth setup, macOS gateway sleep troubleshooting, native Codex hook relay recovery, container model auth, install deployment cards, device-token admin gating, CLI setup flow compatibility, Notte cloud browser CDP setup, and backport targets. (#87313, #63050, #87685) Thanks @bdjben, @liaoandi, and @thewilloftheshadow.
|
||||
- PDF/tools: use ClawPDF for PDF extraction, support encrypted PDF extraction, and surface MCP structured content in agent tool results. (#87670, #87751)
|
||||
- Providers: add Claude Opus 4.8 support, Fal Krea image model schemas, NVIDIA featured model catalogs, MiniMax streaming music responses, and provider-backed voice model catalogs. (#87845, #87890, #80775, #84764, #87794) Thanks @eleqtrizit and @vincentkoc.
|
||||
- Codex/GitHub: add the GitHub Copilot agent runtime and the Codex Supervisor plugin package.
|
||||
- Plugins: externalize GitHub Copilot and Tokenjuice as official install-on-demand plugins with npm and ClawHub publish metadata.
|
||||
- Workboard: add agent coordination tools for tracking and handing off active agent work.
|
||||
- Discord: show commentary in progress drafts so live Discord runs expose useful in-progress context. (#85200)
|
||||
- Plugin SDK: add a reply payload sending hook for plugins that need to deliver channel-owned replies and flatten package types for SDK declarations. (#82823, #87165) Thanks @piersonr and @RomneyDa.
|
||||
- Policy: add policy comparison, ingress-channel conformance, and sandbox-posture conformance checks. (#85572, #85744, #86768)
|
||||
|
||||
### Fixes
|
||||
|
||||
- Agents: fall back to local config pruning when the optional `agents delete` Gateway probe cannot authenticate, so offline installs can still delete agents without removing shared workspaces.
|
||||
- Tighten phone-control mutation authorization [AI]. (#87150) Thanks @pgondhi987.
|
||||
- Clarify directive persistence authorization policy [AI]. (#86369) Thanks @pgondhi987.
|
||||
- Agents/Codex: keep spawned agent cwd/workspace state separated, keep hook context prompt-local, release session locks on timeout abort, avoid session event queue self-wait, preserve shared app-server state across startup or helper failures, keep native hook relay alive across restarts, route workspace memory through tools, resolve Codex runtime models first, report quarantined dynamic tools, format `skills` command output, and bound compaction/steering retries. (#87218, #86875, #86123, #87399, #87375, #87383, #87400) Thanks @mbelinky, @Alix-007, @luoyanglang, @yetval, and @sjf.
|
||||
- Codex Supervisor: keep real-home app-server MCP session listing on the loaded/state-DB path, bound stored history scans, and close WebSocket probes cleanly.
|
||||
- Channels: thread canonical session keys into outbound hooks, preserve Matrix room-id case, keep fallback tool warnings mention-inert, retain delivered Slack final replies during late cleanup, continue iMessage polling after denied reactions, suppress duplicate native exec approvals, preserve Telegram SecretRef prompt config, suppress Discord recovered tool warnings, and block untrusted Teams service URLs. (#73706, #75670, #87366, #87451, #87334) Thanks @zeroaltitude, @lukeboyett, @xiaotian, and @eleqtrizit.
|
||||
- CLI/auth/doctor/providers: reject malformed numeric/timeout/subcommand-version inputs, wait for respawn child shutdown, bound Codex and GitHub Copilot OAuth/token requests, warm provider auth off the main thread, honor Codex response timeouts, bound local service startup, resolve GPT-5.5 without cached catalog, migrate legacy memory auto-provider config, rewrite non-canonical `api_key` auth profiles, and make doctor restart follow-ups actionable. (#87398, #86281, #87361) Thanks @Patrick-Erichsen, @samzong, @giodl73-repo, and @alkor2000.
|
||||
- Gateway/security/session state: expire browser tokens after auth rotation, scope assistant idempotency dedupe, drain probe client closes, avoid stale restart continuation reuse, preserve retry-after fallbacks, bound webchat image and artifact transcript scans, include seconds in inbound metadata timestamps, and evict current plugin-state namespaces at row caps.
|
||||
- Config/parsing/network: reject partial numeric parsing, parse provider/Discord retry headers and dates strictly, honor IPv6 and bare IPv6 `no_proxy` entries, canonicalize secret target array indexes, and reject malformed media content lengths, inspected TCP ports, marketplace content lengths, cron epochs, and sandbox stat fields.
|
||||
- Providers/agents: preserve seeded Anthropic signatures, concatenate signature-delta chunks, preserve DeepSeek `reasoning_content` replay across tier suffixes, apply OpenRouter strict9 ids to Mistral routes, promote Ollama plain-text tool calls, and recover empty preflight compaction. (#87593)
|
||||
- Agents/Codex: keep spawned agent cwd/workspace state separated, forward ACP spawn attachments, keep hook context prompt-local, release session locks on timeout abort and runtime teardown without deleting live OpenClaw-owned locks during cleanup, avoid session event queue self-wait, clean up exec abort listeners, stream assistant deltas incrementally, recover raw missing-thread compaction failures, preserve rotated compaction session identity, keep compaction-timeout snapshots continuable, preserve shared app-server state across startup or helper failures, keep native hook relay alive across restarts and prune stale bridge files, close native hook relay replacement races, keep Claude live tool progress visible for watchdog recovery, suppress abandoned requester completion handoff, route workspace memory through tools, resolve Codex runtime models first, report quarantined dynamic tools, format `skills` command output, bind node auto-review to prepared plans, retry Claude CLI transcript probes, and bound compaction/steering retries. (#87218, #86875, #86123, #88129, #87399, #87375, #72574, #87383, #87400, #83022, #87671, #87738, #87747, #87706, #87546, #87541, #81048) Thanks @mbelinky, @Alix-007, @luoyanglang, @yetval, @sjf, @joshavant, @benjamin1492, @c19354837, @fuller-stack-dev, @pfrederiksen, and @dodge1218.
|
||||
- Codex Supervisor: keep real-home app-server MCP session listing on the loaded state path, bound stored history scans, and close WebSocket probes cleanly.
|
||||
- Channels: thread canonical session keys into outbound hooks, preserve Matrix room-id case, keep fallback tool warnings mention-inert, retain delivered Slack final replies during late cleanup, continue iMessage polling after denied reactions, suppress duplicate native exec approvals, resolve Gateway message actions against the active runtime config, preserve Telegram SecretRef prompt config and polling keepalives, preserve WhatsApp profile auth roots, QR display, document filenames, and plugin hook config, suppress Discord recovered tool warnings, preserve the Discord voice outbound helper, cap Discord/Signal/Zalo channel request and container timeouts, and block untrusted Teams service URLs while keeping TeamsSDK patterns aligned. (#73706, #75670, #87366, #87451, #87465, #87334, #84535, #76262, #83304, #82492, #87581, #77114, #86426, #85529, #87160) Thanks @zeroaltitude, @lukeboyett, @jarvis-mns1, @xiaotian, @funmerlin, @joshavant, @eleqtrizit, @heyitsaamir, @amittell, @lidge-jun, @liorb-mountapps, @masatohoshino, @bladin, and @giodl73-repo.
|
||||
- CLI/auth/doctor/providers: reject malformed numeric/timeout/subcommand-version inputs, ignore workspace dotenv provider credentials, wait for respawn child shutdown, bound heartbeat defaults plus Codex, GitHub Copilot, OpenAI, Anthropic, Google, Feishu, LM Studio, MiniMax, Xiaomi TTS, and local-provider OAuth/token/model requests, harden Codex auth probes, label auth health by agent, preserve explicit agentRuntime pins during Codex model migration, warm provider auth off the main thread, honor Codex response timeouts, stop migrating current Claude Haiku 4.5 profiles to Sonnet, bound local service startup, resolve GPT-5.5 without cached catalog, migrate legacy memory auto-provider config, rewrite non-canonical `api_key` auth profiles, and make doctor restart follow-ups actionable. (#87398, #86281, #87361, #88133, #83655, #87559, #87719, #88088, #85924, #84362) Thanks @Patrick-Erichsen, @samzong, @giodl73-repo, @alkor2000, @mmaps, @nxmxbbd, and @vincentkoc.
|
||||
- Gateway/security/session state: expire browser tokens after auth rotation, scope assistant idempotency dedupe, drain probe client closes, avoid stale restart continuation reuse, preserve retry-after fallbacks and stale rate-limit cooldown probes, bound webchat image and artifact transcript scans, include seconds in inbound metadata timestamps, clear completed session active runs, clear stale chat stream buffers, and evict current plugin-state namespaces at row caps. (#87810, #87833, #75089) Thanks @joshavant and @litang9.
|
||||
- Config/parsing/network: reject partial numeric parsing, parse provider/Discord retry headers and dates strictly, honor IPv6 and bare IPv6 `no_proxy` entries, preserve empty plugin allowlists, canonicalize secret target array indexes, and reject malformed media content lengths, inspected TCP ports, marketplace content lengths, cron epochs, sandbox stat fields, unsafe duration values, empty config path segments, noncanonical schema array refs, unsafe Telegram callback pages, and invalid Teams attachment-fetch DNS targets. (#87883) Thanks @zhangguiping-xydt.
|
||||
- Browser/input hardening: reject invalid tab indexes, excessive viewport resizes, explicit zero CDP ports, malformed geolocation options, unsafe screenshot or permission-grant timeouts, loose response-body limits, invalid cookie expiries, and non-finite Browser tool delays/timeouts.
|
||||
- Cron/automation: retry recurring jobs after transient model rate limits before waiting for the next scheduled slot, and preflight model fallbacks before skipping scheduled work. (#82887) Thanks @chen-zhang-cs-code.
|
||||
- Auto-reply/directives: respect provider and relayed channel metadata during directive persistence so channel-originated decisions keep their intended context. (#87683)
|
||||
- WhatsApp: resolve the auth directory from the active profile so profile-scoped WhatsApp installs do not drift to the wrong credential root. (#82492) Thanks @lidge-jun.
|
||||
- Gateway/session state: clear completed session active runs, avoid cold-loading providers for MCP inventory, cache single-session child indexes, cap handshake timers, and bound preauth, auth-guard, media, transcript, readiness, and port options.
|
||||
- Channels/replies: preserve channel-owned progress callbacks when verbose output is off, keep group-room progress suppression intact, prefer external session delivery context, escape Discord component id delimiters, force final TUI chat repaints, show Slack reasoning previews, and normalize Discord/Matrix/Mattermost channel numeric options. (#87476, #87423)
|
||||
- Agents/tool args: harden smart-quoted argument repair for edit arrays and exact escaped arguments so model-produced tool calls recover without corrupting valid input. (#86611) Thanks @ferminquant.
|
||||
- Providers/agents: preserve seeded Anthropic signatures, preserve signed thinking payloads, concatenate signature-delta chunks, preserve DeepSeek `reasoning_content` replay across tier suffixes, apply OpenRouter strict9 ids to Mistral routes, promote Ollama plain-text tool calls, load NVIDIA featured model catalogs, stream MiniMax music generation responses, and recover empty preflight compaction. (#87593, #87493, #80775, #84764) Thanks @Pluviobyte and @eleqtrizit.
|
||||
- Media/images: skip CLI image cache refs when resolving generated images, allow trusted generated HTML attachments, and bound generated video downloads so stale refs and slow providers fail cleanly. (#87523, #87982)
|
||||
- File transfer: handle late tar stdin pipe errors after archive validation or unpacking has already settled.
|
||||
- Performance: trust install-record caches between reloads, prefer native JSON parsing, reuse unchanged tool-search catalogs, skip unchanged store serialization, add precomputed session patch writers, reduce store clone allocations, cache manifest model catalog rows and auto-enabled plugin config, and slim current metadata identity caches.
|
||||
- Docker/release/QA: package runtime workspace templates, stream cross-OS served artifacts, preserve sparse Crabbox run artifacts, bound OpenClaw instance logs, plugin gauntlet relay logs, MCP channel buffers, kitchen-sink scans, agent-turn assertions, and release scenario logs, and keep release/google live guards current.
|
||||
- Performance: trust install-record caches between reloads, prefer native JSON parsing, reuse unchanged tool-search catalogs, reuse gateway session and plugin metadata paths, skip unchanged store serialization, patch single-entry session writes, add precomputed session patch writers, reduce store clone allocations, cache manifest model catalog rows and auto-enabled plugin config, avoid full session snapshots for entry reads, defer configured Slack full startup, prefer bundled plugin dist entries, and slim current metadata identity caches. (#87760)
|
||||
- Docker/release/QA: package runtime workspace templates, stream cross-OS served artifacts, preserve sparse Crabbox run artifacts, isolate npm plugin installs per package, reject incompatible package plugin API installs, drop the leftover root Sharp dependency from package manifests after the Rastermill migration, bound OpenClaw instance logs, plugin gauntlet relay logs, MCP channel buffers, kitchen-sink scans, agent-turn assertions, QA-Lab credential broker calls, QA Matrix substrate requests, and release scenario logs, and keep release/google live guards current. (#87647, #87477) Thanks @rohitjavvadi and @vincentkoc.
|
||||
- Release/CI: bound manual git fetches, ClawHub verifier responses, ClawHub owner metadata, dependency-guard error bodies, Parallels limits, startup/test/memory budget parsing, and diffs viewer build warnings so release lanes fail with useful proof instead of hanging. (#87839)
|
||||
|
||||
## 2026.5.27
|
||||
|
||||
|
||||
343
appcast.xml
343
appcast.xml
@@ -2,6 +2,70 @@
|
||||
<rss xmlns:sparkle="http://www.andymatuschak.org/xml-namespaces/sparkle" version="2.0">
|
||||
<channel>
|
||||
<title>OpenClaw</title>
|
||||
<item>
|
||||
<title>2026.5.28</title>
|
||||
<pubDate>Sat, 30 May 2026 21:21:09 +0000</pubDate>
|
||||
<link>https://raw.githubusercontent.com/openclaw/openclaw/main/appcast.xml</link>
|
||||
<sparkle:version>2026052890</sparkle:version>
|
||||
<sparkle:shortVersionString>2026.5.28</sparkle:shortVersionString>
|
||||
<sparkle:minimumSystemVersion>15.0</sparkle:minimumSystemVersion>
|
||||
<description><![CDATA[<h2>OpenClaw 2026.5.28</h2>
|
||||
<h3>Highlights</h3>
|
||||
<ul>
|
||||
<li>Agent and Codex runtime recovery is steadier: subagents keep cwd/workspace separation, hook context stays prompt-local, session locks release on timeout abort while live OpenClaw locks survive cleanup, stale restart continuations are avoided, and Codex app-server/helper failures no longer tear down shared runtime state. (#87218, #86875, #87409, #87399, #87375, #88129)</li>
|
||||
<li>Channel delivery and session identity got safer across outbound plugin hooks, Matrix room ids, iMessage reactions/approvals, Slack final replies, Discord recovered tool warnings, runtime-config message actions, WhatsApp profile auth roots, Telegram polling, and Microsoft Teams service URL trust checks. (#73706, #75670, #87366, #87451, #87334, #84535, #82492, #83304, #87160)</li>
|
||||
<li>Mobile and chat surfaces got a broader refresh: the iOS Pro UI, hosted push relay default, realtime Talk tab playback, Gateway chat transport, onboarding, Talk permissions, WebChat reconnect delivery, and session picker behavior now preserve more state across reconnects and empty searches. (#87367, #87531, #87682, #88096, #88105) Thanks @ngutman.</li>
|
||||
<li>Browser, channel, and automation inputs are stricter: Browser tool timeouts, viewport/tab indices, Gateway ports, cron retry handling, Discord component ids, schema array refs, Telegram callback pages, and channel progress callbacks now reject malformed values earlier and preserve the intended delivery context. (#82887)</li>
|
||||
<li>Provider, media, and document coverage expands with Claude Opus 4.8, Fal Krea image schemas, NVIDIA featured models, MiniMax streaming music responses, encrypted PDF extraction, voice model catalogs, GitHub Copilot agent runtime support, and a Codex Supervisor plugin path for delegated Codex workflows. (#87845, #87890, #80775, #84764, #87751, #87794)</li>
|
||||
<li>CLI, auth, doctor, and provider paths fail faster and recover more clearly: malformed numeric/version options are rejected, workspace dotenv provider credentials are ignored, heartbeat defaults, OAuth/token lifetimes, and local service startup requests are bounded, agent auth health labels are clearer, legacy <code>api_key</code> auth profiles migrate to canonical form, and restart guidance is actionable. (#87398, #86281, #87361, #88133, #83655, #87559, #88088, #85924) Thanks @vincentkoc and @giodl73-repo.</li>
|
||||
<li>Plugin and Gateway hot paths do less repeated work while preserving cache correctness for install records, config JSON parsing, tool search catalogs, session stores, manifest model rows, auto-enabled plugin config, browser tokens, viewer assets, and release-split external plugin packages. (#86699)</li>
|
||||
<li>Release, QA, and E2E validation now bound more log, artifact, harness, and cross-OS waits so failing lanes produce proof instead of hanging or false-greening.</li>
|
||||
</ul>
|
||||
<h3>Changes</h3>
|
||||
<ul>
|
||||
<li>Status: show active subagent details in status output.</li>
|
||||
<li>Diffs: split the default language pack and expand default Diffs language coverage while keeping the host floor aligned. (#87370, #87372) Thanks @RomneyDa.</li>
|
||||
<li>ClawHub: add plugin display names plus skill verification and trust surfaces. (#87354, #86699) Thanks @thewilloftheshadow and @Patrick-Erichsen.</li>
|
||||
<li>iOS: refresh the dev app with Pro Command, Chat, Agents, Settings, hosted push relay defaults, and realtime Talk playback wired to gateway sessions, diagnostics, chat, and realtime Talk. (#87367, #88096, #88105) Thanks @Solvely-Colin and @ngutman.</li>
|
||||
<li>Docs: clarify Codex computer-use setup, paste-token stdin auth setup, macOS gateway sleep troubleshooting, native Codex hook relay recovery, container model auth, install deployment cards, device-token admin gating, CLI setup flow compatibility, Notte cloud browser CDP setup, and backport targets. (#87313, #63050, #87685) Thanks @bdjben, @liaoandi, and @thewilloftheshadow.</li>
|
||||
<li>PDF/tools: use ClawPDF for PDF extraction, support encrypted PDF extraction, and surface MCP structured content in agent tool results. (#87670, #87751)</li>
|
||||
<li>Providers: add Claude Opus 4.8 support, Fal Krea image model schemas, NVIDIA featured model catalogs, MiniMax streaming music responses, and provider-backed voice model catalogs. (#87845, #87890, #80775, #84764, #87794) Thanks @eleqtrizit and @vincentkoc.</li>
|
||||
<li>Codex/GitHub: add the GitHub Copilot agent runtime and the Codex Supervisor plugin package.</li>
|
||||
<li>Plugins: externalize GitHub Copilot and Tokenjuice as official install-on-demand plugins with npm and ClawHub publish metadata.</li>
|
||||
<li>Workboard: add agent coordination tools for tracking and handing off active agent work.</li>
|
||||
<li>Discord: show commentary in progress drafts so live Discord runs expose useful in-progress context. (#85200)</li>
|
||||
<li>Plugin SDK: add a reply payload sending hook for plugins that need to deliver channel-owned replies and flatten package types for SDK declarations. (#82823, #87165) Thanks @RomneyDa.</li>
|
||||
<li>Policy: add policy comparison, ingress-channel conformance, and sandbox-posture conformance checks. (#85572, #85744, #86768)</li>
|
||||
</ul>
|
||||
<h3>Fixes</h3>
|
||||
<ul>
|
||||
<li>Agents: fall back to local config pruning when the optional <code>agents delete</code> Gateway probe cannot authenticate, so offline installs can still delete agents without removing shared workspaces.</li>
|
||||
<li>Tighten phone-control mutation authorization [AI]. (#87150) Thanks @pgondhi987.</li>
|
||||
<li>Clarify directive persistence authorization policy [AI]. (#86369) Thanks @pgondhi987.</li>
|
||||
<li>Agents/Codex: keep spawned agent cwd/workspace state separated, forward ACP spawn attachments, keep hook context prompt-local, release session locks on timeout abort and runtime teardown without deleting live OpenClaw-owned locks during cleanup, avoid session event queue self-wait, clean up exec abort listeners, stream assistant deltas incrementally, recover raw missing-thread compaction failures, preserve rotated compaction session identity, keep compaction-timeout snapshots continuable, preserve shared app-server state across startup or helper failures, keep native hook relay alive across restarts and prune stale bridge files, close native hook relay replacement races, keep Claude live tool progress visible for watchdog recovery, suppress abandoned requester completion handoff, route workspace memory through tools, resolve Codex runtime models first, report quarantined dynamic tools, format <code>skills</code> command output, bind node auto-review to prepared plans, retry Claude CLI transcript probes, and bound compaction/steering retries. (#87218, #86875, #86123, #88129, #87399, #87375, #72574, #87383, #87400, #83022, #87671, #87738, #87747, #87706, #87546, #87541, #81048) Thanks @mbelinky, @Alix-007, @luoyanglang, @yetval, @sjf, @joshavant, and @benjamin1492.</li>
|
||||
<li>Codex Supervisor: keep real-home app-server MCP session listing on the loaded state path, bound stored history scans, and close WebSocket probes cleanly.</li>
|
||||
<li>Channels: thread canonical session keys into outbound hooks, preserve Matrix room-id case, keep fallback tool warnings mention-inert, retain delivered Slack final replies during late cleanup, continue iMessage polling after denied reactions, suppress duplicate native exec approvals, resolve Gateway message actions against the active runtime config, preserve Telegram SecretRef prompt config and polling keepalives, preserve WhatsApp profile auth roots, QR display, document filenames, and plugin hook config, suppress Discord recovered tool warnings, preserve the Discord voice outbound helper, cap Discord/Signal/Zalo channel request and container timeouts, and block untrusted Teams service URLs while keeping TeamsSDK patterns aligned. (#73706, #75670, #87366, #87451, #87465, #87334, #84535, #76262, #83304, #82492, #87581, #77114, #86426, #85529, #87160) Thanks @zeroaltitude, @lukeboyett, @xiaotian, @funmerlin, @joshavant, @eleqtrizit, @heyitsaamir, @amittell, @liorb-mountapps, @masatohoshino, @bladin, and @giodl73-repo.</li>
|
||||
<li>CLI/auth/doctor/providers: reject malformed numeric/timeout/subcommand-version inputs, ignore workspace dotenv provider credentials, wait for respawn child shutdown, bound heartbeat defaults plus Codex, GitHub Copilot, OpenAI, Anthropic, Google, Feishu, LM Studio, MiniMax, Xiaomi TTS, and local-provider OAuth/token/model requests, harden Codex auth probes, label auth health by agent, preserve explicit agentRuntime pins during Codex model migration, warm provider auth off the main thread, honor Codex response timeouts, stop migrating current Claude Haiku 4.5 profiles to Sonnet, bound local service startup, resolve GPT-5.5 without cached catalog, migrate legacy memory auto-provider config, rewrite non-canonical <code>api_key</code> auth profiles, and make doctor restart follow-ups actionable. (#87398, #86281, #87361, #88133, #83655, #87559, #87719, #88088, #85924, #84362) Thanks @Patrick-Erichsen, @samzong, @giodl73-repo, @alkor2000, @mmaps, @nxmxbbd, and @vincentkoc.</li>
|
||||
<li>Gateway/security/session state: expire browser tokens after auth rotation, scope assistant idempotency dedupe, drain probe client closes, avoid stale restart continuation reuse, preserve retry-after fallbacks and stale rate-limit cooldown probes, bound webchat image and artifact transcript scans, include seconds in inbound metadata timestamps, clear completed session active runs, clear stale chat stream buffers, and evict current plugin-state namespaces at row caps. (#87810, #87833, #75089) Thanks @joshavant and @litang9.</li>
|
||||
<li>Config/parsing/network: reject partial numeric parsing, parse provider/Discord retry headers and dates strictly, honor IPv6 and bare IPv6 <code>no_proxy</code> entries, preserve empty plugin allowlists, canonicalize secret target array indexes, and reject malformed media content lengths, inspected TCP ports, marketplace content lengths, cron epochs, sandbox stat fields, unsafe duration values, empty config path segments, noncanonical schema array refs, unsafe Telegram callback pages, and invalid Teams attachment-fetch DNS targets. (#87883) Thanks @zhangguiping-xydt.</li>
|
||||
<li>Browser/input hardening: reject invalid tab indexes, excessive viewport resizes, explicit zero CDP ports, malformed geolocation options, unsafe screenshot or permission-grant timeouts, loose response-body limits, invalid cookie expiries, and non-finite Browser tool delays/timeouts.</li>
|
||||
<li>Cron/automation: retry recurring jobs after transient model rate limits before waiting for the next scheduled slot, and preflight model fallbacks before skipping scheduled work. (#82887)</li>
|
||||
<li>Auto-reply/directives: respect provider and relayed channel metadata during directive persistence so channel-originated decisions keep their intended context. (#87683)</li>
|
||||
<li>WhatsApp: resolve the auth directory from the active profile so profile-scoped WhatsApp installs do not drift to the wrong credential root. (#82492)</li>
|
||||
<li>Gateway/session state: clear completed session active runs, avoid cold-loading providers for MCP inventory, cache single-session child indexes, cap handshake timers, and bound preauth, auth-guard, media, transcript, readiness, and port options.</li>
|
||||
<li>Channels/replies: preserve channel-owned progress callbacks when verbose output is off, keep group-room progress suppression intact, prefer external session delivery context, escape Discord component id delimiters, force final TUI chat repaints, show Slack reasoning previews, and normalize Discord/Matrix/Mattermost channel numeric options. (#87476, #87423)</li>
|
||||
<li>Agents/tool args: harden smart-quoted argument repair for edit arrays and exact escaped arguments so model-produced tool calls recover without corrupting valid input. (#86611)</li>
|
||||
<li>Providers/agents: preserve seeded Anthropic signatures, preserve signed thinking payloads, concatenate signature-delta chunks, preserve DeepSeek <code>reasoning_content</code> replay across tier suffixes, apply OpenRouter strict9 ids to Mistral routes, promote Ollama plain-text tool calls, load NVIDIA featured model catalogs, stream MiniMax music generation responses, and recover empty preflight compaction. (#87593, #87493, #80775, #84764) Thanks @eleqtrizit.</li>
|
||||
<li>Media/images: skip CLI image cache refs when resolving generated images, allow trusted generated HTML attachments, and bound generated video downloads so stale refs and slow providers fail cleanly. (#87523, #87982)</li>
|
||||
<li>File transfer: handle late tar stdin pipe errors after archive validation or unpacking has already settled.</li>
|
||||
<li>Performance: trust install-record caches between reloads, prefer native JSON parsing, reuse unchanged tool-search catalogs, reuse gateway session and plugin metadata paths, skip unchanged store serialization, patch single-entry session writes, add precomputed session patch writers, reduce store clone allocations, cache manifest model catalog rows and auto-enabled plugin config, avoid full session snapshots for entry reads, defer configured Slack full startup, prefer bundled plugin dist entries, and slim current metadata identity caches. (#87760)</li>
|
||||
<li>Docker/release/QA: package runtime workspace templates, stream cross-OS served artifacts, preserve sparse Crabbox run artifacts, isolate npm plugin installs per package, reject incompatible package plugin API installs, drop the leftover root Sharp dependency from package manifests after the Rastermill migration, bound OpenClaw instance logs, plugin gauntlet relay logs, MCP channel buffers, kitchen-sink scans, agent-turn assertions, QA-Lab credential broker calls, QA Matrix substrate requests, and release scenario logs, and keep release/google live guards current. (#87647, #87477) Thanks @rohitjavvadi and @vincentkoc.</li>
|
||||
<li>Release/CI: bound manual git fetches, ClawHub verifier responses, ClawHub owner metadata, dependency-guard error bodies, Parallels limits, startup/test/memory budget parsing, and diffs viewer build warnings so release lanes fail with useful proof instead of hanging. (#87839)</li>
|
||||
</ul>
|
||||
<p><a href="https://github.com/openclaw/openclaw/blob/main/CHANGELOG.md">View full changelog</a></p>
|
||||
]]></description>
|
||||
<enclosure url="https://github.com/openclaw/openclaw/releases/download/v2026.5.28/OpenClaw-2026.5.28.zip" length="54750142" type="application/octet-stream" sparkle:edSignature="U4O55uMdPU+OqSx9QR1ApUJ8wg65wxTydzD7iyCn1GHtm1MBK9noEeiA/yoUKkqb/bx0hzi1gNhn+ye19RXnCA=="/>
|
||||
</item>
|
||||
<item>
|
||||
<title>2026.5.27</title>
|
||||
<pubDate>Thu, 28 May 2026 12:12:19 +0000</pubDate>
|
||||
@@ -258,284 +322,5 @@
|
||||
]]></description>
|
||||
<enclosure url="https://github.com/openclaw/openclaw/releases/download/v2026.5.26/OpenClaw-2026.5.26.zip" length="54484748" type="application/octet-stream" sparkle:edSignature="y4WXG7JT8ktJ+K7YDgllY7u5Z9BSKR/SwGiwEh0gikOJ/SWqwcQd+z2tWa2zgwvCJKWsAUFwJs1ATor880SUBg=="/>
|
||||
</item>
|
||||
<item>
|
||||
<title>2026.5.22</title>
|
||||
<pubDate>Sun, 24 May 2026 01:41:27 +0000</pubDate>
|
||||
<link>https://raw.githubusercontent.com/openclaw/openclaw/main/appcast.xml</link>
|
||||
<sparkle:version>2026052290</sparkle:version>
|
||||
<sparkle:shortVersionString>2026.5.22</sparkle:shortVersionString>
|
||||
<sparkle:minimumSystemVersion>15.0</sparkle:minimumSystemVersion>
|
||||
<description><![CDATA[<h2>OpenClaw 2026.5.22</h2>
|
||||
<h3>Changes</h3>
|
||||
<ul>
|
||||
<li>Gateway/perf: reuse process-stable channel catalog reads, avoid repeated bundled-channel boundary checks, and rotate gateway watch CPU profiles so benchmark runs do not accumulate unbounded artifacts.</li>
|
||||
<li>Gateway/perf: reuse immutable plugin metadata snapshots across startup, config, model, channel, setup, and secret metadata readers so hot paths avoid repeated plugin file stats and manifest registry reloads.</li>
|
||||
<li>Gateway/perf: lazy-load startup-idle plugin work, core gateway method handlers, and the embedded ACPX runtime so Gateway health and ready signals no longer wait on unused handler trees or ACPX probes.</li>
|
||||
<li>Gateway/perf: cache plugin SDK public-surface alias maps and skip irrelevant macOS Linuxbrew PATH probes so Gateway startup avoids repeated filesystem walks and slow missing-directory stats.</li>
|
||||
<li>Meeting Notes: add a source-only external meeting-notes plugin and SDK source-provider contract outside the core npm package, with auto-start capture config, manual transcript imports, read-only <code>openclaw meeting-notes</code> CLI access, and Discord voice as the first live source.</li>
|
||||
<li>Docs/channels/config: add Signal <code>configPath</code>, Telegram wildcard topic defaults, local-time backup archive names, Termux home fallback, include-path validation, secret-scanner-safe placeholder guidance, Gemini CLI/Antigravity media guidance, and macOS VM auto-login guidance. Thanks @NorseGaud, @yudistiraashadi, @huangqian8, @VibhorGautam, @maweibin, @tianxingleo, @IgnacioPro, and @xzcxzcyy-claw.</li>
|
||||
<li>Docs: clarify model-usage portability, Codex migration prerequisites, status bootstrap wording, thread-bound subagent limits, hook ownership, and config-preserving safety guidance. Thanks @aniruddhaadak80, @leno23, @TomDjerry, @matthewxmurphy, @vincentkoc, and @stablegenius49.</li>
|
||||
<li>Docs: clarify README onboarding and Gateway startup paths, WhatsApp QR/408 recovery, cron output language prompts, skill advanced features, gateway upstream 403 troubleshooting, and plugin fallback override guidance. Thanks @deepujain, @Zacxxx, @Jah-yee, @neyric, @usimic, @Renu-Cybe, @BigUncle, and @SeashoreShi.</li>
|
||||
<li>Docs: clarify context-pruning ratio bounds, local dashboard recovery, CLI env markers, remote onboarding token behavior, and Peekaboo Bridge permissions for subprocess agents. Thanks @ayesha-aziz123, @dishraters, @hougangdev, and @brandonlipman.</li>
|
||||
<li>Docs: clarify browser CDP diagnostics, Plugin SDK allowlist imports, status-reaction timing defaults, queue steering behavior, limited-tool troubleshooting, cron HEARTBEAT handling, Telegram multi-agent groups, Bitwarden SecretRef setup, and EasyRunner deployments. Thanks @Quratulain-bilal, @mbelinky, @Mickey-, @vancece, @xenouzik, @posigit, @surlymochan, @janaka, and @choiking.</li>
|
||||
<li>Crabbox/Testbox: run clean sparse-checkout Testbox syncs from a temporary full checkout and route remote changed gates through Corepack pnpm.</li>
|
||||
<li>Docs: clarify IPv4-only Gateway BYOH binding, trusted-proxy scope clearing, Android pairing approval, macOS Accessibility grants, Zalo profile env vars, password-store SecretRef setup, and Chinese memory navigation. Thanks @itskai-dev, @gwh7078, @longstoryscott, @MoeJaberr, and @yuaiccc.</li>
|
||||
<li>Docs: consolidate GLM under Z.AI, add the Upstash Box install guide and Gateway exposure runbook, clarify MEDIA directives, Copilot and Voyage setup, config path quoting, real behavior proof, and memory-file write guidance. Thanks @BobDu, @alitariksahin, @Jefsky, @musaabhasan, @OmerZeyveli, @leno23, @WuKongAI-CMU, @luoyanglang, and @majin1102.</li>
|
||||
<li>Docs: clarify media provider credentials, Codex/OpenClaw code-mode boundaries, Slack and Telegram ack reactions, Feishu dynamic agents, secrets plaintext boundaries, memory guidance, and Chinese glossary terms. Thanks @nielskaspers, @cosmopolitan033, @drclaw-iq, @alexgduarte, @zccyman, @chengoak, and @cassthebandit.</li>
|
||||
<li>Packaging: exclude documentation images and assets from the npm tarball, reducing published package size without affecting runtime docs search or CLI behavior. Thanks @SebTardif.</li>
|
||||
<li>Media understanding: stop auto-probing Gemini CLI and use Antigravity CLI only as a lower-priority image/video fallback after configured provider APIs.</li>
|
||||
<li>Agents/subagents: limit default sub-agent bootstrap context to <code>AGENTS.md</code> and <code>TOOLS.md</code>, keeping persona, identity, user, memory, heartbeat, and setup files out of delegated workers by default. (#85283) Thanks @100yenadmin.</li>
|
||||
<li>Maintainer skills: exclude plugin SDK/API boundary work from <code>openclaw-landable-bug-sweep</code> so bugbash sweeps stay focused on small paper-cut fixes.</li>
|
||||
<li>QA-Lab/diagnostics: extend the OpenTelemetry smoke harness to prove trace, metric, and log export, and add first-class Prometheus and observability smoke aliases.</li>
|
||||
<li>Plugin SDK: add a generic channel-message poll sender so channel plugins can expose poll delivery without depending on channel-specific SDK facades.</li>
|
||||
<li>Crabbox: keep the local wrapper's provider validation synced with the installed Crabbox binary while preserving supported aliases such as <code>docker</code> and <code>blacksmith</code>. (#85302) Thanks @hxy91819.</li>
|
||||
<li>Maintainer skills: add <code>openclaw-landable-bug-sweep</code> for producing five small, reviewed, CI-green OpenClaw bugfix PRs from issue/PR sweeps.</li>
|
||||
<li>Control UI/chat: add search and Load More pagination to the chat session picker, keeping initial session loads bounded while making older conversations reachable. (#85237) Thanks @amknight.</li>
|
||||
<li>CLI/onboarding: start classic onboarding when bare <code>openclaw</code> runs before an authored config exists, while keeping configured installs on Crestodian. (#72343) Thanks @fuller-stack-dev.</li>
|
||||
<li>Discord: allow configuring a bounded <code>agentComponents.ttlMs</code> callback registry lifetime for long-running component workflows, with per-account overrides and a 24-hour cap. (#84189) Thanks @100menotu001.</li>
|
||||
<li>xAI/Grok: reuse xAI OAuth auth profiles for Grok <code>web_search</code>, thread active-agent auth through web search, add Grok model aliases, and let media providers declare default operation timeouts. (#85182) Thanks @fuller-stack-dev.</li>
|
||||
<li>Plugin SDK: add row-level session workflow helpers and deprecate <code>loadSessionStore</code> so plugins can read and patch sessions without depending on the legacy whole-store shape. (#84693) Thanks @efpiva.</li>
|
||||
<li>Gateway/plugins: reuse a compatible Gateway startup plugin registry during dispatch so safe plugin dispatches avoid redundant registry loading. (#84324) Thanks @ai-hpc.</li>
|
||||
<li>Plugins/SDK: add a general <code>embeddingProviders</code> capability contract and registration API so embeddings can become a reusable provider surface outside memory-specific adapters.</li>
|
||||
<li>Dependencies: refresh provider, plugin, UI, and tooling packages, update <code>protobufjs</code> to 8.4.0 to clear the current npm advisory, and carry the Claude ACP completion patch forward to <code>@agentclientprotocol/claude-agent-acp</code> 0.36.1.</li>
|
||||
<li>Agents/tools: remove the old sender-owner tool gating path so configured tools stay visible for trusted sessions while command and channel-action auth still carry real sender identity.</li>
|
||||
<li>QA-Lab: add curated mock JSONL replay fixtures and first-drift reporting for runtime-parity audits. (#80323, refs #80176) Thanks @100yenadmin.</li>
|
||||
<li>QA-Lab: add a QA bus tool-trace visibility scenario for sanitized tool-call assertions.</li>
|
||||
<li>QA-Lab: replace generic evidence framing in seeded scenario prompts with concrete observed QA behavior.</li>
|
||||
<li>QA-Lab: list named scenario packs in the coverage report so personal-agent privacy coverage stays visible in audits.</li>
|
||||
<li>QA-Lab: list live transport lane membership in the coverage report so real transport checks stay separate from seeded qa-channel scenarios.</li>
|
||||
<li>Release/package: run package integrity checks before package acceptance lanes so public install/update validation fails before private QA assets can leak into the package.</li>
|
||||
<li>QA-Lab: include the optional 100-turn runtime parity soak in release-soak artifacts so long-run Codex/Pi transcript drift stays visible outside the default gate. (#80395) Thanks @100yenadmin.</li>
|
||||
<li>QA-Lab: add a live-only long-context progress watchdog scenario for Codex app-server timeout and stalled-run sentinels. (#80323) Thanks @100yenadmin.</li>
|
||||
<li>QA-Lab: tag gateway restart recovery and streaming final-integrity scenarios as live-only runtime parity lanes. (#80323) Thanks @100yenadmin.</li>
|
||||
<li>QA-Lab: add a personal-agent failure recovery scenario that checks honest partial status, retry boundaries, and local recovery artifacts. (#83872) Thanks @iFiras-Max1.</li>
|
||||
<li>QA-Lab: include an opt-in <code>update.run</code> package self-upgrade sentinel for destructive latest-package recovery checks.</li>
|
||||
<li>QA-Lab: add Codex plugin lifecycle and auth-profile fixture coverage for missing installs, pinned-version drift, first-turn install ordering, and doctor migration safety. (#80323, refs #80174) Thanks @100yenadmin.</li>
|
||||
<li>Models/perf: pre-warm the provider auth-state map at gateway startup so <code>/models</code> and every model-listing call short-circuits the per-provider plugin / external-CLI discovery on the hot path. Per-call cost drops from ~20 s to ~5 ms (~4,100×); the one-time startup warm resets and re-warms after hot reloads. (#84816) Thanks @sjf.</li>
|
||||
<li>Release/security: ship the root npm package and OpenClaw-owned npm plugins with generated shrinkwrap, support bundled plugin runtime dependencies for suitable plugin tarballs, and require review for lockfile/shrinkwrap changes so published installs use locked dependency graphs.</li>
|
||||
<li>Tests/perf: isolate doctor core health check unit coverage from real skills/workspace discovery so <code>doctor-core-checks</code> no longer dominates unit perf while keeping one real skills-readiness smoke. (#84493) Thanks @frankekn.</li>
|
||||
</ul>
|
||||
<h3>Fixes</h3>
|
||||
<ul>
|
||||
<li>WebChat: summarize internal message-tool source replies so tool cards no longer duplicate the visible reply body. (#84773) Thanks @jason-allen-oneal.</li>
|
||||
<li>Gateway: preserve deferred lifecycle-error cleanup across later non-terminal events so provider timeouts can persist failed session state instead of leaving sessions stuck running. (#85256, fixes #63819) Thanks @samzong.</li>
|
||||
<li>Agents/subagents: report tool-only child progress during timeout summaries instead of showing no visible output.</li>
|
||||
<li>Telegram/ACP: preserve explicit <code>:topic:</code> conversation suffixes when inbound ACP targets do not carry a separate thread id.</li>
|
||||
<li>Browser/proxy: bypass the managed proxy for the exact local managed Chrome CDP readiness and DevTools WebSocket endpoints, so <code>openclaw browser start</code> works when the operator proxy blocks loopback egress. (#83255) Thanks @lightcap.</li>
|
||||
<li>Ollama: bypass the managed proxy for configured local embedding origins while keeping SSRF guardrails on unconfigured targets. Thanks @Kaspre.</li>
|
||||
<li>OpenAI/images: route Codex API-key image generation through the native OpenAI Images API instead of the Codex OAuth streaming backend, avoiding 401s from valid API keys.</li>
|
||||
<li>Agents/OpenAI completions: omit empty tool payload fields for proxy-like OpenAI-compatible endpoints so strict vLLM-style servers accept tool-free turns. (#85835) Thanks @rendrag-git.</li>
|
||||
<li>Checks/Windows: route full <code>pnpm check</code> stage commands through the managed child runner so Windows avoids Node shell-argv deprecation warnings there too.</li>
|
||||
<li>Checks/Windows: run managed child commands through explicit <code>cmd.exe</code> wrapping instead of Node shell mode with argv, avoiding Node 24 subprocess deprecation warnings during changed checks.</li>
|
||||
<li>Gateway: omit internal stream-error placeholder entries from agent prompt history so failed assistant turns are not replayed as model-authored text. (#85652) Thanks @anyech.</li>
|
||||
<li>Sessions: enforce the session write-lock max-hold policy during lock acquisition so long-held locks can be reclaimed before the stale-lock window. (#85764) Thanks @njuboy11.</li>
|
||||
<li>Models: prune retired Groq, GitHub Copilot, OpenAI, xAI, and old Claude catalog entries, with doctor migration to upgrade existing configs to current provider refs.</li>
|
||||
<li>Doctor/update: recognize junction-backed source checkouts as git installs by comparing canonical paths before showing package-manager update guidance. Fixes #82215. Thanks @igormf.</li>
|
||||
<li>Channels: honor <code>/verbose on</code> for tool/progress summaries across direct chats, groups, channels, and forum topics while preserving quiet default behavior. (#85488) Thanks @kurplunkin.</li>
|
||||
<li>CLI/skills: show an all-ready note with next-step commands when skill setup has no missing dependencies to install. (#85032) Thanks @aniruddhaadak80.</li>
|
||||
<li>Microsoft Foundry: route DeepSeek V4 Pro and Flash models through the Foundry Responses API while keeping older DeepSeek models on their existing path. (#85549) Thanks @roslinmahmud.</li>
|
||||
<li>Status/usage: show configured cost estimates for AWS SDK models in full usage output while keeping token-only usage replies cost-free. (#85619) Thanks @ItsOtherMauridian.</li>
|
||||
<li>Agents/OpenAI Responses: retry non-visible reasoning-only turns for OpenAI Responses API families instead of treating them as empty failed turns. (#85603) Thanks @SebTardif.</li>
|
||||
<li>Directive tags: preserve message and content-part object identity when display stripping makes no directive-tag changes. (#85682) Thanks @willamhou.</li>
|
||||
<li>Telegram: send local <code>path</code>/<code>filePath</code> and structured attachment media from <code>sendMessage</code> actions instead of dropping them or sending text-only messages. (#85219) Thanks @keshavbotagent.</li>
|
||||
<li>Sessions/status: show the estimated context budget when fresh provider usage is unavailable and clear stale estimates across session resets and compaction boundaries. (#84830) Thanks @giodl73-repo.</li>
|
||||
<li>Gateway/config: pin relative <code>OPENCLAW_STATE_DIR</code> overrides to an absolute path at startup so later working-directory changes cannot retarget gateway state. (#52264) Thanks @PerfectPan.</li>
|
||||
<li>Release/package: run npm release, prepublish, and postpublish verification through Windows-safe npm command shims so native Windows checks can execute <code>npm.cmd</code> instead of treating it as a binary.</li>
|
||||
<li>Agents/harness: pass CLI runtime aliases through harness selection so provider-owned CLI aliases no longer get rejected before reaching the right runtime. (#85631) Thanks @potterdigital.</li>
|
||||
<li>Secrets: show the irreversible apply warning after interactive <code>secrets configure</code> confirmation so confirmed migrations still get the final safety prompt. (#85638) Thanks @alkor2000.</li>
|
||||
<li>Agents/CLI output: ignore cumulative Claude <code>stream-json</code> result usage when assistant usage events are present, preventing inflated cache-read accounting. (#85625) Thanks @zhouhe-xydt.</li>
|
||||
<li>CLI: keep <code>waitForever()</code> alive by leaving its keep-alive interval ref'd so the public helper no longer exits immediately with Node's unsettled-await code. (#85694) Thanks @m1qaweb.</li>
|
||||
<li>Agents/bootstrap: guard bootstrap name checks against missing file names so malformed bootstrap entries warn and truncate instead of crashing. Fixes #85523. (#85615) Thanks @zhouhe-xydt.</li>
|
||||
<li>CLI/tasks: reject partially numeric <code>openclaw tasks audit --limit</code> values so audit limits must be real positive integers instead of accepting strings like <code>5abc</code>. (#84901) Thanks @jbetala7.</li>
|
||||
<li>Status/diagnostics: bound deep Docker audit probes so <code>openclaw status --deep</code> reports slow container checks instead of hanging behind unbounded inspection. (#85476) Thanks @giodl73-repo.</li>
|
||||
<li>Providers/Anthropic: migrate 1M context handling to GA-capable Claude 4.x models by sizing eligible models at 1M without the retired <code>context-1m-2025-08-07</code> beta, ignoring that retired beta in older configs, and preserving OAuth-required Anthropic beta headers. (#45613) Thanks @haoyu-haoyu.</li>
|
||||
<li>Cron/Telegram: parse forum-topic delivery targets through the Telegram plugin instead of cron core, including <code>:topic:</code> and <code>:topicId</code> forms for announce delivery. Thanks @etticat.</li>
|
||||
<li>Twitch: keep stale message-handler cleanup callbacks from removing newer handler registrations for the same account, preserving inbound message delivery after reconnects. Fixes #83888. (#85425) Thanks @alkor2000.</li>
|
||||
<li>Memory/LanceDB: expose public memory artifacts through the active memory provider bridge so memory-wiki imports durable memory files, daily notes, dream reports, and event logs without depending on memory-core internals. Fixes #83604. (#85060) Thanks @brokemac79.</li>
|
||||
<li>Crabbox: keep AWS hydration compatible with local Actions replay by inlining the hydrate workflow's Node/pnpm setup instead of invoking repo-local composite actions.</li>
|
||||
<li>Agents/subagents: simplify native sub-agent completion handoff so children report their latest visible assistant result to the requester without using <code>message</code>, while keeping parent-owned message-tool delivery policy intact. Fixes #85070. (#85089) Thanks @brokemac79.</li>
|
||||
<li>Docker setup: stop printing the Gateway bearer token in setup logs and printed follow-up commands.</li>
|
||||
<li>Agents: let embedded compaction fallback retries proceed when PI-compatible candidates do not need agent harness plugin preparation.</li>
|
||||
<li>Agents/tools: honor configured custom provider API keys when deciding whether media, image-generation, video-generation, music-generation, and PDF tools are available. (#85570)</li>
|
||||
<li>StepFun: stop advertising stale generic API key auth choices so onboarding only offers runtime-backed Standard and Step Plan choices.</li>
|
||||
<li>Diagnostics: keep OpenTelemetry log bodies behind explicit content capture and scrub scoped agent-session keys from OpenTelemetry and Prometheus labels while preserving bounded queue-lane prefixes.</li>
|
||||
<li>Windows installer: fail Git checkout installs when <code>pnpm install</code> or <code>pnpm build</code> fails instead of writing a wrapper to a missing CLI build.</li>
|
||||
<li>Sessions: surface previous-transcript archive failures during <code>/new</code> rotation so disk rename errors are logged instead of silently hiding stranded transcript files. Fixes #81984. (#85586, from #82081) Thanks @0xghost42.</li>
|
||||
<li>TUI/agents: mirror internal-ui message-tool replies into final chat output so message-tool-only agents remain visible in <code>openclaw tui</code>. Fixes #85538. Thanks @danpolasek.</li>
|
||||
<li>Agents: keep parallel OpenAI-compatible tool-call deltas in separate argument buffers so interleaved tool calls no longer corrupt streamed arguments. (#82263) Thanks @luna-system.</li>
|
||||
<li>Memory/doctor: report missing or unusable QMD workspace directories as workspace failures instead of generic binary failures. (#63167) Thanks @sercada.</li>
|
||||
<li>Debug proxy: record CONNECT client-socket errors and destroy the paired upstream socket so abrupt client disconnects no longer leak tunnel resources. (#82444) Thanks @SebTardif.</li>
|
||||
<li>Diffs: continue hydrating later diff cards when one card fails so a single broken card no longer blanks the whole diff viewer. (#84775) Thanks @cosmopolitan033.</li>
|
||||
<li>Mac app: use the native settings sidebar window chrome so the sidebar toggle stays on the left and content no longer clips under oversized titlebar padding.</li>
|
||||
<li>QA-Lab/Codex: bundle auth/plugin fixture imports for flow scenarios and let terminal async media tools end Codex app-server turns without timing out. (#80397, refs #80323) Thanks @100yenadmin.</li>
|
||||
<li>Gateway/agents: preserve fresh session overrides and metadata when stale cached agent-session entries race with store updates, so subagent model/provider overrides and routing policy survive concurrent writes. (#19328) Thanks @CodeReclaimers.</li>
|
||||
<li>Control UI/chat: keep chat session search inline with the session selector so the header no longer shows a duplicate standalone search row.</li>
|
||||
<li>Control UI/chat: collapse focused-mode header chrome and suppress hidden-header scroll updates so focus mode no longer jumps while scrolling. Thanks @amknight.</li>
|
||||
<li>Codex app-server: restart the native app-server and retry once when server-side compaction times out, so preflight compaction stalls recover instead of failing every dispatch. (#85500)</li>
|
||||
<li>Restore Control UI gateway token pairing [AI]. (#85459) Thanks @pgondhi987.</li>
|
||||
<li>OpenAI video: honor configured provider request private-network opt-in for local/custom video endpoints so explicitly trusted mock and self-hosted providers are not blocked. Thanks @shakkernerd.</li>
|
||||
<li>OpenAI video: send uploaded video edit requests to the documented <code>/videos/edits</code> endpoint with a <code>video</code> file instead of posting MP4 references to <code>/videos</code>. Thanks @shakkernerd.</li>
|
||||
<li>Agents/channels: preserve message-tool delivery evidence through gateway agent completion handoffs so successful generated media sends are not followed by false failure messages. Thanks @shakkernerd.</li>
|
||||
<li>CLI/update: repair managed npm plugin <code>openclaw</code> peer links during post-core convergence and reject stale or wrong-target peer links before restart. (#83794) Thanks @fuller-stack-dev.</li>
|
||||
<li>CLI/agents: default new omitted-account bindings to all accounts when the channel has multiple configured accounts, and clarify account-scope docs. (#49769) Thanks @Gcaufy.</li>
|
||||
<li>Codex app-server: let authorized <code>/codex</code> control commands such as <code>/codex detach</code> escape plugin-owned conversation bindings while keeping unknown or unauthorized slash text routed to the bound plugin. Fixes #85157. (#85188) Thanks @TurboTheTurtle.</li>
|
||||
<li>Auto-reply/models: keep <code>/models</code> browse replies fast by sharing the bounded read-only catalog path with Gateway model listing. (#84735) Thanks @safrano9999.</li>
|
||||
<li>Codex app-server: disable native Code Mode when the effective exec host is <code>node</code> and keep OpenClaw <code>exec</code>/<code>process</code> available, so <code>/exec host=node</code> routes shell commands through the selected node instead of the gateway. Fixes #85012. (#85090) Thanks @sahilsatralkar.</li>
|
||||
<li>Agents: bound embedded auto-compaction session write-lock watchdogs to the compaction timeout instead of the full run timeout, so stuck compaction cannot hold the live session lock for the whole run window. (#84949) Thanks @luoyanglang.</li>
|
||||
<li>Gateway/agents: return phase-aware <code>agent.wait</code> timeout attribution and only cool auth profiles on provider-started timeouts. Refs #65504. Thanks @100yenadmin.</li>
|
||||
<li>Gateway: defer provider auth-state prewarm until after startup readiness so early gateway tool/session requests are not blocked by provider auth discovery. (#85272) Thanks @dutifulbob.</li>
|
||||
<li>Gateway/models: coalesce provider auth-state rewarms after auth-profile failures and log event-loop delay for warm/rewarm work, so provider auth bursts no longer stack full auth sweeps behind channel replies.</li>
|
||||
<li>Gateway/models: stop cancelled provider auth-state prewarms from continuing full provider sweeps, so reload and auth-failure bursts no longer keep startup busy.</li>
|
||||
<li>Agents/Codex: show the first plan update as a transient chat status notice without counting it as final assistant content.</li>
|
||||
<li>CLI/update: walk the macOS process ancestry and honor the inherited Gateway runtime PID before package updates stop the managed Gateway service, so nested in-band updater children can refuse instead of killing the LaunchAgent-supervised Gateway that owns them. Fixes #85120.</li>
|
||||
<li>Gateway/LaunchAgent: wait for launchd reload bootout to finish and fall back to kickstart when bootstrap races, so reload handoff does not leave the service deregistered. Fixes #84630. (#84641) Thanks @NianJiuZst.</li>
|
||||
<li>Gateway/LaunchAgent: treat a concurrent launchd bootstrap as a successful restart when the service is already loaded, avoiding false macOS Gateway restart failures. Fixes #84721. (#84722) Thanks @googlerest.</li>
|
||||
<li>Gateway/service: include the active <code>openclaw</code> command bin directory in managed service PATH generation and doctor audit expectations for npm-global macOS installs. Fixes #84201. (#84475) Thanks @jbetala7.</li>
|
||||
<li>Control UI/chat: disable the thinking selector for known non-reasoning models instead of showing duplicate Off choices. Fixes #84069. Thanks @DrippingMellow.</li>
|
||||
<li>Memory: expand <code>~</code> in configured extra memory paths before resolving them, so home-relative folders are not treated as workspace-relative. Fixes #58026. Thanks @stadman.</li>
|
||||
<li>Skills: treat <code>openclaw.os: macos</code> as Darwin when checking skill requirements, so macOS-only skills no longer report as missing on macOS hosts. Fixes #61338. Thanks @Jessecq1995.</li>
|
||||
<li>Control UI/logs: strip ANSI escape sequences from displayed Gateway log messages so color codes no longer appear as raw text. Fixes #64399. Thanks @guguangxin-eng.</li>
|
||||
<li>Docker: pre-create the workspace and auth-profile config mount points with <code>node</code> ownership so first-run named volumes do not start root-owned. Fixes #85076. Thanks @Noerr.</li>
|
||||
<li>Telegram: pass configured markdown table mode through outbound markdown chunking so chunked sends render tables consistently. Fixes #85085. Thanks @ShuaiHui.</li>
|
||||
<li>CLI/update: preserve managed Gateway service environment during package cutovers so macOS LaunchAgent repair/restart reads the pre-update service state instead of caller shell state. (#83026)</li>
|
||||
<li>Agents/providers: honor per-model <code>api</code> and <code>baseUrl</code> overrides in custom provider auth hooks and transport selection. Fixes #80487. (#80488) Thanks @huveewomg.</li>
|
||||
<li>Gateway/restart: eager-load the lifecycle runtime before in-place upgrade signal handling so package replacement does not deadlock restart imports. (#84890) Thanks @myps6415.</li>
|
||||
<li>CLI/update: start managed Gateway update handoff helpers from a stable existing directory and tolerate deleted cwd/package roots during macOS LaunchAgent handoff. Fixes #83808. (#83875) Thanks @jason-allen-oneal.</li>
|
||||
<li>Skills: watch each shared skill directory once across agent workspaces instead of once per agent, preventing file-descriptor exhaustion (<code>EMFILE</code>) that disposed bundle-mcp processes and stalled sessions on multi-agent gateways. Fixes #84968. (#85130) Thanks @openperf.</li>
|
||||
<li>Release/security: keep generated npm shrinkwrap package versions inside the pnpm lock graph so published package locks cannot bypass pnpm dependency age and override policy.</li>
|
||||
<li>Cron: honor <code>cron.retry.retryOn: ["network"]</code> for common network error codes such as <code>EAI_AGAIN</code>, <code>EHOSTUNREACH</code>, and <code>ENETUNREACH</code>.</li>
|
||||
<li>Gateway chat: broadcast returned agent-run error payloads after an agent starts so ACP/WebChat clients receive terminal idle-timeout errors. Fixes #84945.</li>
|
||||
<li>Gateway chat display: preserve OpenAI-compatible <code>prompt_tokens</code>, <code>completion_tokens</code>, and <code>total_tokens</code> usage fields in sanitized chat history so llama.cpp sessions keep context counts. Fixes #77992. Thanks @MarTT79.</li>
|
||||
<li>Dashboard/CLI: allow macOS browser launching through <code>open</code> even when SSH environment variables are present, while preserving Linux SSH no-display protection. Fixes #67088. Thanks @theglove44.</li>
|
||||
<li>Codex app-server: keep native web search observations out of mirrored chat transcripts while preserving tool progress telemetry. Fixes #85109. Thanks @ugitmebaby.</li>
|
||||
<li>OpenCode Go: strip unsupported Kimi reasoning replay fields before provider requests so repeated <code>kimi-k2.6</code> turns do not fail schema validation. Fixes #83812. Thanks @Sleeck.</li>
|
||||
<li>Browser/CDP: add a WSL2 portproxy self-loop hint when Chrome DevTools endpoints accept connections but return an empty HTTP reply. Fixes #59209. Thanks @Owlock.</li>
|
||||
<li>Agents/OpenAI: preserve structured provider error code, type, and redacted body metadata on boundary-aware transport failures.</li>
|
||||
<li>Doctor/Codex: point native Codex asset warnings at the canonical <code>openclaw migrate plan codex</code> preview command. Fixes #84948. Thanks @markoa.</li>
|
||||
<li>CLI/models: make <code>capability model auth logout --agent</code> remove auth profiles from the selected non-default agent store. Fixes #85092. Thanks @islandpreneur007.</li>
|
||||
<li>Gateway/models: reuse prepared provider auth metadata during model-listing auth checks so repeated lookups avoid broad plugin discovery while preserving synthetic local auth.</li>
|
||||
<li>CLI/status: suppress systemd user-service setup hints when <code>openclaw status --deep</code> can already reach a running Gateway RPC service. Fixes #85094. Thanks @islandpreneur007.</li>
|
||||
<li>CLI/devices: recover local approval when a same-device repair request replaces the request ID being approved.</li>
|
||||
<li>CLI/agents: retry transient normal-close Gateway handshakes before falling back to embedded <code>openclaw agent</code> execution.</li>
|
||||
<li>CLI/update: keep managed Gateway service stop/restart status lines out of <code>openclaw update --json</code> stdout so package-update automation can parse the JSON payload.</li>
|
||||
<li>Plugins: resolve OpenClaw plugin SDK subpaths for native external plugin runtimes without mutating package installs or broadening process-wide module resolution.</li>
|
||||
<li>Agents/OpenAI: preserve Responses and Chat Completions <code>reasoning_tokens</code> usage metadata without double-counting it in aggregate output tokens. (#85319)</li>
|
||||
<li>Control UI/chat: convert pasted <code>data:image/...;base64,...</code> clipboard text into an image attachment instead of dumping the payload into the composer. Fixes #62604. Thanks @cpwilhelmi.</li>
|
||||
<li>Providers/Gemini: strip fractional seconds from web-search time range filters so Gemini accepts freshness-bound search requests. (#85071) Thanks @Noerr.</li>
|
||||
<li>OpenAI Codex: preserve image input support for sparse <code>openai-codex/gpt-5.5</code> catalog rows. (#85095) Thanks @sercada.</li>
|
||||
<li>CLI/models: add a piped or pasted API-key path for OpenAI Codex auth and warn when API keys are pasted into token-mode auth. (#85533) Thanks @joshavant.</li>
|
||||
<li>Telegram: dead-letter missing-harness isolated ingress failures so a poisoned spooled update no longer blocks later same-lane messages. Fixes #85470. (#85605) Thanks @joshavant.</li>
|
||||
<li>Plugins/discovery: strip <code>-plugin</code> package suffixes when deriving plugin id hints so package names line up with manifest ids. (#85170) Thanks @JulyanXu.</li>
|
||||
<li>Tlon: stop advertising a non-existent agent tool contract in the plugin manifest.</li>
|
||||
<li>Telegram: preserve fenced code block languages through Markdown rendering so Telegram receives <code>language-*</code> code classes. (#85209) Thanks @leno23.</li>
|
||||
<li>Windows installer: run npm and Corepack command shims from a Windows-local directory so installs launched from WSL2 UNC paths do not fail before OpenClaw is installed.</li>
|
||||
<li>Windows updates: roll back git-backed updates to the previous checkout when dependency install, build, UI build, or doctor repair fails.</li>
|
||||
<li>Windows installer: persist user-local portable Git on PATH and activate the repo-pinned pnpm version for git-backed installs and updates.</li>
|
||||
<li>Windows installer: bootstrap a user-local portable Node.js when native Windows has no Node and no winget, Chocolatey, or Scoop, so first-run installs can continue on raw hosts.</li>
|
||||
<li>Windows installer: extract the downloaded portable Node.js directory with native <code>tar</code> before falling back to .NET zip extraction, avoiding PowerShell 5.1 archive and path-length failures.</li>
|
||||
<li>fix(integrations): enforce channel read target allowlists [AI]. (#84982) Thanks @pgondhi987.</li>
|
||||
<li>Agents/heartbeat: route single-owner <code>session.dmScope=main</code> direct-message exec and cron event wakes back to the agent main session so async completions no longer strand context in orphan direct-DM queues. Fixes #71581. (#83743) Thanks @Kaspre.</li>
|
||||
<li>Agents/code-mode: expose outer code-mode <code>exec</code> source through the <code>command</code> hook alias with <code>toolKind</code>/<code>toolInputKind</code> discriminators so exec-shaped policies can distinguish code-mode cells. (#83483) Thanks @Kaspre.</li>
|
||||
<li>Agents/code mode: return structured timeout and runtime-unavailable error codes for known worker failures. Fixes #83389. (#83444) Thanks @Kaspre.</li>
|
||||
<li>QA-Lab: isolate multi-scenario suite workers when scenarios need startup config patches, preventing message-routing config from leaking into unrelated scenarios.</li>
|
||||
<li>QA-Lab: make the commitments heartbeat-target-none scenario request an immediate heartbeat instead of waiting for the next scheduled heartbeat.</li>
|
||||
<li>Codex/Plugin SDK: deliver Codex-native subagent completions through a generic harness task runtime so harness-backed plugins can mirror durable task lifecycle and completion delivery without Codex-specific SDK imports. (#83445) Thanks @bryanpearson.</li>
|
||||
<li>Gateway CLI: surface local post-challenge connect assembly failures immediately instead of waiting for the wrapper timeout. Fixes #68944. (#85253) Thanks @samzong.</li>
|
||||
<li>Messages: strip unsupported web-search citation control markers from outbound replies before they reach WebChat or external channels. Fixes #85193. (#85204) Thanks @neeravmakwana.</li>
|
||||
<li>Agents/exec: treat denied exec approvals as terminal instead of feeding them back into agent follow-up work, and recognize Chinese stop phrases in abort handling. Fixes #69386. (#85194) Thanks @samzong.</li>
|
||||
<li>CLI/agents: abort accepted Gateway-backed <code>openclaw agent</code> runs on SIGINT/SIGTERM so cron and supervisor timeouts do not leave remote agent work alive. Fixes #71710. (#84381) Thanks @Kaspre.</li>
|
||||
<li>Codex app-server: retry replay-safe stdio client-close turns once using structured failure metadata, while surfacing idle <code>turn/completed</code> timeouts instead of blindly replaying active shared-server turns. Thanks @VACInc.</li>
|
||||
<li>Codex app-server: reject command overrides that embed Node or package-manager arguments and point users to <code>appServer.args</code>, so Windows startup avoids shell parsing failures. (#84417) Thanks @TurboTheTurtle.</li>
|
||||
<li>Agents/Copilot: drop unsafe GitHub Copilot Responses reasoning replay items before send so Telegram direct sessions no longer fail on overlong replay IDs. Fixes #85197. (#85198) Thanks @galiniliev.</li>
|
||||
<li>UI: add accessible tooltips to the topbar color-mode buttons so System, Light, and Dark choices are labeled on hover and focus. (#85227) Thanks @amknight.</li>
|
||||
<li>fix: constrain Windows task script names [AI]. (#85064) Thanks @pgondhi987.</li>
|
||||
<li>Control UI: keep the chat session picker from hiding older or cross-agent configured conversations while preserving the bounded configured-agent refresh. (#85211) Thanks @amknight.</li>
|
||||
<li>Agents/Anthropic: preserve unsafe integer tool-call input values in streamed Anthropic tool-use JSON, preventing Discord-style IDs from being rounded before dispatch. Fixes #47229. (#83063) Thanks @leno23.</li>
|
||||
<li>Agents/Codex: estimate tool-heavy prompt pressure at the LLM boundary before provider submission, so persistent sessions compact before overflowing context windows. (#85541) Thanks @fuller-stack-dev and @joshavant.</li>
|
||||
<li>Agents/hooks: wait for local one-shot CLI and Codex <code>agent_end</code> plugin hooks before process cleanup so terminal observability flushes reliably. (#85007)</li>
|
||||
<li>Providers/Google: preserve Gemini 3 cron <code>thinkingDefault: "low"</code> when stale catalog metadata says <code>reasoning:false</code>, so scheduled runs keep provider-supported thinking instead of downgrading to off. (#85185) Thanks @neeravmakwana.</li>
|
||||
<li>CLI/agents: allow <code>openclaw agent --session-key</code> to target explicit session keys, including agent-scoped legacy keys. (#85121) Thanks @Kaspre.</li>
|
||||
<li>Auto-reply/ACP: wait for same-channel block reply delivery before starting tool work, while still honoring ACP dispatch aborts so stopped turns do not wait on slow channel sends. (#83722) Thanks @IWhatsskill.</li>
|
||||
<li>Codex/ACP: mark required child-run completions that only report progress, omit a final deliverable, or fail requester delivery as blocked while preserving real final reports. (#85110) Thanks @IWhatsskill.</li>
|
||||
<li>Channels: treat bare abort messages such as <code>stop</code>, <code>abort</code>, and <code>wait</code> as immediate control commands in inbound debounce paths so stop requests are not delayed behind pending message coalescing. (#83348) Thanks @IWhatsskill.</li>
|
||||
<li>Channels/message tool: resolve configured external channel plugins during in-agent channel selection, so <code>openclaw agent --local</code> message-tool sends no longer report an available channel as unavailable. (#85022) Thanks @Kaspre.</li>
|
||||
<li>Agents/heartbeat: honor group/channel <code>message_tool</code> visible-reply policy and model-specific Codex runtime config for scheduled heartbeat runs, so failed internal tool output stays private. Fixes #85310. (#85357) Thanks @neeravmakwana.</li>
|
||||
<li>Gateway/ACP: close child ACP sessions spawned via <code>sessions_spawn</code> when their parent session is reset or deleted, instead of leaving orphaned <code>claude-agent-acp</code> processes that accumulate and exhaust memory. Fixes #68916. (#85190) Thanks @openperf.</li>
|
||||
<li>Codex app-server: block native execution paths when OpenClaw exec resolves to a node host while preserving the first-party CLI node binding path. Fixes #85012. (#85534) Thanks @joshavant.</li>
|
||||
<li>Diagnostics: bound cleanup timeout detail logs, emit drop summaries when async diagnostic bursts exceed the queue cap, and surface async queue drops through diagnostic telemetry.</li>
|
||||
<li>Agents/subagents: surface blocked child-run completions as errors instead of successful subagent finishes. (#80886) Thanks @TurboTheTurtle.</li>
|
||||
<li>Context engines: fail closed with a descriptive error when the selected agent runtime cannot satisfy declared context-engine host requirements.</li>
|
||||
<li>Agents/Pi: treat accepted embedded <code>sessions_spawn</code> child-session handoffs as terminal progress so parent turns no longer report false non-deliverable failures. (#85054) Thanks @samzong.</li>
|
||||
<li>CLI/models: resolve <code>openclaw models set</code> aliases from the runtime config while keeping authored aliases ahead of runtime-only defaults. (#83262) Thanks @IWhatsskill.</li>
|
||||
<li>Doctor: show personal Codex CLI asset notices as info instead of warnings. Fixes #84859.</li>
|
||||
<li>WhatsApp: update Baileys to <code>7.0.0-rc13</code> and drop the obsolete logger type patch.</li>
|
||||
<li>CLI/update: pre-pack GitHub/git package update targets before the staged npm install, restoring <code>openclaw update --tag main</code> for one-off package updates. (#81296) Thanks @fuller-stack-dev.</li>
|
||||
<li>Gateway: mirror successful same-source message-tool sends into session transcripts so delivered replies stay in later history/context. (#84837) Thanks @iFiras-Max1.</li>
|
||||
<li>Media generation: keep image, music, and video completion delivery from duplicating or losing task ownership when generated media finishes through active session replies. (#84006) Thanks @fuller-stack-dev.</li>
|
||||
<li>Infra/json: retry transient <code>File changed during read</code> races while loading JSON state so config and state reads recover instead of failing the turn. (#84285)</li>
|
||||
<li>Plugins/providers: fail closed for workspace provider plugins during setup-mode discovery unless explicitly trusted, preventing untrusted workspace plugin code from running during provider setup. (#81069) Thanks @mmaps.</li>
|
||||
<li>Providers/Ollama: resolve configured Ollama Cloud <code>OLLAMA_API_KEY</code> markers to the real discovery key so cloud provider entries keep authenticated model catalog access. (#85037)</li>
|
||||
<li>Discord: keep persistent component registry fallback warnings actionable by forwarding structured error and cause metadata through the runtime logger. Fixes #84185. (#84190) Thanks @100menotu001.</li>
|
||||
<li>Gateway/sessions: preserve compatible session auth profile overrides when switching models within the same provider, including provider-auth aliases. Fixes #81837. (#81886) Thanks @TurboTheTurtle.</li>
|
||||
<li>Gateway/status: surface inbound delivery telemetry counters and transport-liveness warnings in <code>openclaw status --all</code>. Fixes #49577. (#72724)</li>
|
||||
<li>Docker: prune package-excluded plugin source workspaces and dependency closures so runtime images do not keep packages for plugins that were not opted in.</li>
|
||||
<li>Providers/Ollama: treat Docker/OrbStack host aliases as local Ollama endpoints so <code>ollama-local</code> marker auth works when OpenClaw runs inside a VM/container and Ollama runs on the host. Fixes #84875.</li>
|
||||
<li>QA-Lab: keep explicitly searchable/deferred OpenClaw dynamic tool rows report-only by default so tool-coverage gates do not treat mock discovery gaps as hard product failures. (#80319) Thanks @100yenadmin.</li>
|
||||
<li>Agents/config: keep non-Google provider model refs from being rewritten by Google Gemini preview-id normalization. (#84762) Thanks @zhangguiping-xydt.</li>
|
||||
<li>Installer: require a real controlling terminal before launching onboarding so headless <code>curl | bash</code> installs finish cleanly after installing the CLI.</li>
|
||||
<li>Agents/Codex: promote a completed final assistant response when a prompt timeout races Codex app-server completion instead of returning an empty timeout envelope. Refs #84516.</li>
|
||||
<li>Codex app-server: keep interrupted turn statuses from being treated as OpenClaw aborts by themselves, so tool-only turns remain eligible for no-visible-answer recovery. Fixes #84492.</li>
|
||||
<li>Agents: cap heartbeat model bleed context hints by the stored session window when runtime model metadata is unavailable, so overflow recovery advice does not suggest a larger window than the active session actually has.</li>
|
||||
<li>Control UI/Web Push: use <code>https://openclaw.ai</code> as the generated default VAPID subject instead of the old localhost mailbox so iOS PWA push setup uses an Apple-acceptable subject when <code>OPENCLAW_VAPID_SUBJECT</code> is unset. Fixes #83134. (#83317) Thanks @IWhatsskill.</li>
|
||||
<li>Control UI: distinguish inherited thinking-off settings from explicit Off selections so the thinking selector no longer shows two identical Off rows. (#85223) Thanks @amknight.</li>
|
||||
<li>Agents/Pi: keep embedded session transcript writes from tripping false takeover detection after packaged npm onboarding agent turns.</li>
|
||||
<li>Codex/TUI: surface Codex-native post-turn compaction failures instead of continuing uncompacted, and keep successful native compaction serialized before local idle/next-turn handling. Fixes #84305. (#85160) Thanks @joshavant.</li>
|
||||
<li>Memory/search: stop recall tracking from writing dreaming side-effect artifacts when <code>dreaming.enabled=false</code>, while preserving normal search results. Fixes #84436. (#84444) Thanks @NianJiuZst.</li>
|
||||
<li>Diffs: render viewer toolbar icons from a closed icon-name map instead of HTML strings, removing the toolbar icon XSS sink. (#83955) Thanks @tanshanshan.</li>
|
||||
<li>QA: keep <code>pnpm qa:e2e</code> self-check runs inside the private QA runtime envelope even when inherited shell env disables bundled plugins.</li>
|
||||
<li>fix(config): validate browser sandbox bind sources [AI]. (#84799) Thanks @pgondhi987.</li>
|
||||
<li>doctor: constrain legacy plugin cleanup paths [AI]. (#84801) Thanks @pgondhi987.</li>
|
||||
<li>Update/doctor: prune stale local bundled plugin install records that point at old compiled bundled output so current bundled plugin schemas win after upgrade. (#84863) Thanks @fuller-stack-dev.</li>
|
||||
<li>Providers/Ollama: preserve native Ollama tool-call IDs across assistant replay so Gemini over Ollama Cloud can keep its hidden function-call thought-signature handle.</li>
|
||||
<li>Discord: keep session recovery and <code>/stop</code> abort ownership on the source dispatch lane while bound ACP turns continue routing to their target session, so stalled pre-run work and late replies are cleared instead of leaking after stop. Fixes #84477. (#85100) Thanks @joshavant.</li>
|
||||
<li>Codex app-server: mark missing turn completion after observed execution as replay-unsafe and release the session so follow-up turns can run. Fixes #84076. (#85107) Thanks @joshavant.</li>
|
||||
<li>Codex app-server: give visible <code>message</code> dynamic tool sends a longer timeout budget so slow channel delivery can return its own result or error instead of hitting the 30-second Codex wrapper. (#85216) Thanks @amknight.</li>
|
||||
<li>Codex app-server: add a dedicated post-tool raw assistant completion idle timeout config so trusted heavy turns can wait longer after tool handoff without weakening final assistant release.</li>
|
||||
<li>Matrix: keep explicitly configured two-person rooms on the room route before stale <code>m.direct</code> or strict two-member DM fallback can bypass mention gating. Fixes #85017. (#85137) Thanks @joshavant.</li>
|
||||
<li>Agents/subagents: require explicit subagent allowlist targets to be configured agents so stale deleted-agent ids are omitted from <code>agents_list</code> and rejected by <code>sessions_spawn</code>. Fixes #84811. (#85154) Thanks @joshavant.</li>
|
||||
<li>PDF tool: time out idle remote PDF body reads after 120 seconds so stalled remote documents return an error instead of wedging the session. Fixes #68649. (#84768) Thanks @luoyanglang.</li>
|
||||
<li>Diagnostics/OpenTelemetry plugin: suppress handled OTLP exporter promise rejections so collector shutdowns no longer crash the Gateway. (#81085) Thanks @luoyanglang.</li>
|
||||
<li>Agents/exec: omit raw command text and env values from denied exec failure logs while keeping safe correlation metadata. Fixes #85049. (#85140) Thanks @joshavant.</li>
|
||||
<li>Media/audio: skip empty structured sherpa-onnx transcripts instead of treating the raw JSON payload as spoken text. (#84667) Thanks @TurboTheTurtle.</li>
|
||||
<li>Agents/exec: preserve inherited XDG base-directory environment values for subprocesses while still rejecting agent-supplied XDG overrides. Fixes #84854. (#85139) Thanks @joshavant.</li>
|
||||
<li>Node/Linux: keep <code>OPENCLAW_GATEWAY_TOKEN</code> out of generated systemd unit files by writing node service token values to a node-specific env file. (#84408)</li>
|
||||
<li>Memory-core/dreaming: reuse stable narrative subagent session keys per workspace and phase while keeping per-run idempotency and bounded cleanup, so stale <code>dreaming-narrative-*</code> sessions do not accumulate. Fixes #68252, #69187, and #70402. (#70464) Thanks @chiyouYCH.</li>
|
||||
<li>Trajectory/support: tolerate partial skill snapshot entries when building support metadata so rejected skill path scans no longer abort trajectory capture. (#71185) Thanks @lukeboyett.</li>
|
||||
<li>TUI: coalesce repeated idle Esc abort notices into a single <code>no active run xN</code> system row instead of appending duplicate rows.</li>
|
||||
<li>Telegram: honor <code>channels.telegram.pollingStallThresholdMs</code> in the default isolated polling path, restarting silent workers instead of leaving inbound updates wedged. Fixes #83950. (#84861) Thanks @joshavant.</li>
|
||||
<li>Telegram: dedupe replayed message dispatches by Telegram chat/message identity so isolated-ingress replays do not trigger duplicate model dispatches. Fixes #84886. (#85208) Thanks @joshavant.</li>
|
||||
<li>Slack: suppress reasoning payloads before reply delivery and dispatch accounting, so Slack monitor, slash-command, fallback, and direct reply paths do not leak model reasoning. Fixes #84319. (#84322) Thanks @ffluk3 and @joshavant.</li>
|
||||
<li>Slack: deliver native plugin approval prompts and updates when Slack native approvals are enabled, while keeping plugin approval authorization separate from exec approvers.</li>
|
||||
<li>Slack: keep native plugin approval prompts in the originating app conversation thread when the live Slack turn source is a <code>D...</code> conversation.</li>
|
||||
<li>Agents/Pi: disable the embedded pi-coding-agent runtime auto-retry so OpenClaw's own retry and failover loop does not replay failed tool calls through a nested SDK retry. Fixes #73781. (#74434) Thanks @yelog.</li>
|
||||
<li>CLI/perf: keep <code>setup --help</code>, <code>onboard --help</code>, and <code>configure --help</code> out of the full wizard runtime while preserving the existing help output. (#84488) Thanks @frankekn.</li>
|
||||
<li>CLI/perf: keep <code>agents --help</code> out of agents action/runtime imports so help, completion, and command discovery paths avoid loading the full agents runtime. (#84483) Thanks @frankekn.</li>
|
||||
<li>CLI/perf: keep <code>secrets --help</code> and <code>nodes --help</code> on the precomputed help path so parent help avoids loading action-heavy command runtime modules. (#84818) Thanks @frankekn.</li>
|
||||
<li>CLI/perf: serve <code>doctor</code>, <code>gateway</code>, <code>models</code>, and <code>plugins</code> parent help from startup metadata so common subcommand help avoids full CLI program construction. (#84786) Thanks @frankekn.</li>
|
||||
<li>Codex/Lossless: keep context-engine history on the canonical run session when Telegram DMs use per-peer runtime policy keys. Fixes #84936. (#84954) Thanks @neeravmakwana.</li>
|
||||
<li>Codex: keep heartbeat response tool schemas durable without exposing dynamic tools disabled by turn policy, so heartbeat wakeups can reuse threads while scoped tool allowlists stay enforced. (#84681) Thanks @jalehman.</li>
|
||||
<li>Auth/OAuth: skip the refresh adapter when a stored OAuth credential has no refresh token so agent turns fail fast on missing-key instead of waiting on the 120s refresh timeout. Thanks @romneyda.</li>
|
||||
<li>Auth/Codex: load legacy OAuth sidecar credentials in the embedded runner's secrets-runtime auth loaders so Telegram replies, cron-triggered turns, and other isolated sub-agent lanes can reach the existing #83312 refresh-and-rewrite migration instead of failing with <code>No API key found for provider "openai-codex"</code> until the user runs <code>openclaw doctor</code>. Thanks @Totalsolutionsync and @romneyda.</li>
|
||||
<li>Codex/failover: classify <code>deactivated_workspace</code> as a permanent auth failure so configured fallback models can advance when a Codex workspace is deactivated. (#55893) Thanks @litang9.</li>
|
||||
<li>Exec: keep configured <code>tools.exec.pathPrepend</code> entries ahead of user shell startup PATH changes on POSIX gateway runs. (#81403) Thanks @medns.</li>
|
||||
<li>Gateway/sessions: allow shared-secret bearer callers to read and stream session history without an explicit scope header. (#81815) Thanks @medns.</li>
|
||||
<li>Agents/embedded runner: classify HTML auth provider responses as <code>auth_html</code> and return a re-authentication hint instead of the CDN-blocked copy that <code>upstream_html</code> returns. Cloudflare Access login pages, nginx basic-auth challenges, and gateway login walls all produce HTML auth bodies that were previously misdiagnosed as transient CDN blocks. (#79900) Thanks @martingarramon.</li>
|
||||
<li>TUI/streaming watchdog: dismiss the <code>This response is taking longer than expected</code> notice as soon as a chat event for the same run arrives, so the message no longer sits next to the recovered response when the run was only briefly silent. Refs #67052, #69081 (closed), prior attempt #69026. Thanks @jpruit20 and @romneyda.</li>
|
||||
<li>Agents/Pi: tolerate OpenClaw-owned transcript writes while embedded prompts are released for model I/O, keeping long-running Feishu, Slack, Telegram, and cron turns from failing with false session-takeover errors. Fixes #84059. (#84250) Thanks @tianxiaochannel-oss88.</li>
|
||||
</ul>
|
||||
<p><a href="https://github.com/openclaw/openclaw/blob/main/CHANGELOG.md">View full changelog</a></p>
|
||||
]]></description>
|
||||
<enclosure url="https://github.com/openclaw/openclaw/releases/download/v2026.5.22/OpenClaw-2026.5.22.zip" length="54409357" type="application/octet-stream" sparkle:edSignature="am1mwLOmUHor9QuQWtxSsKoBOCySUBo4fB+0Qdcrz0E3wf6ESIMTfOC0k+dKJSh9gtLZw5jzpWVqTBzEdU36Aw=="/>
|
||||
</item>
|
||||
</channel>
|
||||
</rss>
|
||||
@@ -65,8 +65,8 @@ android {
|
||||
applicationId = "ai.openclaw.app"
|
||||
minSdk = 31
|
||||
targetSdk = 36
|
||||
versionCode = 2026052801
|
||||
versionName = "2026.5.28"
|
||||
versionCode = 2026053001
|
||||
versionName = "2026.5.30"
|
||||
ndk {
|
||||
// Support all major ABIs — native libs are tiny (~47 KB per ABI)
|
||||
abiFilters += listOf("armeabi-v7a", "arm64-v8a", "x86", "x86_64")
|
||||
|
||||
@@ -1,5 +1,13 @@
|
||||
# OpenClaw iOS Changelog
|
||||
|
||||
## 2026.5.30 - 2026-05-30
|
||||
|
||||
Maintenance update for the current OpenClaw release.
|
||||
|
||||
- Added hosted push relay defaults, realtime Talk playback, and safer WebSocket ping handling for mobile sessions.
|
||||
- Updated App Store screenshots to cover Gateway pairing, Command, Chat, Talk, Agent, and Settings flows.
|
||||
- Highlighted realtime Talk relay, Gateway connection status, node capabilities, push wake, and privacy controls.
|
||||
|
||||
## 2026.5.28 - 2026-05-28
|
||||
|
||||
Maintenance update for the current OpenClaw release.
|
||||
|
||||
@@ -2,8 +2,8 @@
|
||||
// Source of truth: apps/ios/version.json
|
||||
// Generated by scripts/ios-sync-versioning.ts.
|
||||
|
||||
OPENCLAW_IOS_VERSION = 2026.5.28
|
||||
OPENCLAW_MARKETING_VERSION = 2026.5.28
|
||||
OPENCLAW_IOS_VERSION = 2026.5.30
|
||||
OPENCLAW_MARKETING_VERSION = 2026.5.30
|
||||
OPENCLAW_BUILD_VERSION = 1
|
||||
|
||||
#include? "../build/Version.xcconfig"
|
||||
|
||||
@@ -29,6 +29,14 @@ def clear_empty_env_var(key)
|
||||
ENV.delete(key) unless env_present?(ENV[key])
|
||||
end
|
||||
|
||||
def screenshot_upload_requested?
|
||||
ENV["DELIVER_SCREENSHOTS"] == "1"
|
||||
end
|
||||
|
||||
def screenshot_paths
|
||||
Dir[File.join(__dir__, "screenshots", "**", "*.png")]
|
||||
end
|
||||
|
||||
def maybe_decode_hex_keychain_secret(value)
|
||||
return value unless env_present?(value)
|
||||
|
||||
@@ -314,6 +322,7 @@ platform :ios do
|
||||
desc "Upload App Store metadata (and optionally screenshots)"
|
||||
lane :metadata do
|
||||
sync_ios_versioning!
|
||||
version_metadata = read_ios_version_metadata
|
||||
api_key = asc_api_key
|
||||
clear_empty_env_var("APP_STORE_CONNECT_API_KEY_PATH")
|
||||
app_identifier = ENV["ASC_APP_IDENTIFIER"]
|
||||
@@ -321,11 +330,21 @@ platform :ios do
|
||||
app_identifier = nil unless env_present?(app_identifier)
|
||||
app_id = nil unless env_present?(app_id)
|
||||
|
||||
if screenshot_upload_requested? && screenshot_paths.empty?
|
||||
UI.user_error!("DELIVER_SCREENSHOTS=1 but no PNG screenshots were found under apps/ios/fastlane/screenshots.")
|
||||
end
|
||||
|
||||
deliver_options = {
|
||||
api_key: api_key,
|
||||
force: true,
|
||||
skip_screenshots: ENV["DELIVER_SCREENSHOTS"] != "1",
|
||||
app_version: version_metadata[:short_version],
|
||||
copyright: "2026 OpenClaw",
|
||||
primary_category: "PRODUCTIVITY",
|
||||
secondary_category: "UTILITIES",
|
||||
skip_screenshots: !screenshot_upload_requested?,
|
||||
skip_metadata: ENV["DELIVER_METADATA"] != "1",
|
||||
skip_binary_upload: true,
|
||||
overwrite_screenshots: screenshot_upload_requested?,
|
||||
run_precheck_before_submit: false
|
||||
}
|
||||
deliver_options[:app_identifier] = app_identifier if app_identifier
|
||||
|
||||
@@ -1,18 +1,19 @@
|
||||
OpenClaw is a personal AI assistant you run on your own devices.
|
||||
|
||||
Pair this iPhone app with your OpenClaw Gateway to connect your phone as a secure node for voice, camera, and device automation.
|
||||
Pair this iPhone app with your OpenClaw Gateway to use your phone as a secure node for chat, voice, approvals, sharing, and device-aware automation.
|
||||
|
||||
What you can do:
|
||||
- Pair with your private OpenClaw Gateway by QR code or setup code
|
||||
- Chat with your assistant from iPhone
|
||||
- Use voice wake and push-to-talk
|
||||
- Capture photos and short clips on request
|
||||
- Record screen snippets for troubleshooting and workflows
|
||||
- Use realtime Talk mode and push-to-talk
|
||||
- Review Gateway action approvals from your phone
|
||||
- Share text, links, and media directly from iOS into OpenClaw
|
||||
- Run location-aware and device-aware automations
|
||||
- Enable device capabilities such as camera, screen, location, photos, contacts, calendar, and reminders when you choose
|
||||
- Receive push wakes and node status updates for connected workflows
|
||||
|
||||
OpenClaw is local-first: you control your gateway, keys, and configuration.
|
||||
OpenClaw is local-first: you control your gateway, keys, configuration, and permissions. Device access is managed by iOS permissions and can be enabled only for the capabilities you want to use.
|
||||
|
||||
Getting started:
|
||||
1) Set up your OpenClaw Gateway
|
||||
2) Open the iOS app and pair with your gateway
|
||||
3) Start using commands and automations from your phone
|
||||
3) Start using chat, Talk mode, approvals, and automations from your phone
|
||||
|
||||
@@ -1 +1 @@
|
||||
openclaw,ai assistant,local ai,voice assistant,automation,gateway,chat,agent,node
|
||||
openclaw,ai assistant,local ai,iphone ai,voice assistant,automation,gateway,chat,agent
|
||||
|
||||
@@ -1 +1 @@
|
||||
Run OpenClaw from your iPhone: pair with your own gateway, trigger automations, and use voice, camera, and share actions.
|
||||
Pair your iPhone with your OpenClaw Gateway for chat, realtime voice, approvals, device capabilities, and private automation.
|
||||
|
||||
@@ -1 +1,5 @@
|
||||
Maintenance update for the current OpenClaw release.
|
||||
|
||||
- Added hosted push relay defaults, realtime Talk playback, and safer WebSocket ping handling for mobile sessions.
|
||||
- Updated App Store screenshots to cover Gateway pairing, Command, Chat, Talk, Agent, and Settings flows.
|
||||
- Highlighted realtime Talk relay, Gateway connection status, node capabilities, push wake, and privacy controls.
|
||||
|
||||
@@ -1,3 +1,3 @@
|
||||
{
|
||||
"version": "2026.5.28"
|
||||
"version": "2026.5.30"
|
||||
}
|
||||
|
||||
@@ -15,9 +15,9 @@
|
||||
<key>CFBundlePackageType</key>
|
||||
<string>APPL</string>
|
||||
<key>CFBundleShortVersionString</key>
|
||||
<string>2026.5.28</string>
|
||||
<string>2026.5.30</string>
|
||||
<key>CFBundleVersion</key>
|
||||
<string>2026052800</string>
|
||||
<string>2026053000</string>
|
||||
<key>CFBundleIconFile</key>
|
||||
<string>OpenClaw</string>
|
||||
<key>CFBundleURLTypes</key>
|
||||
|
||||
@@ -14,6 +14,22 @@ public protocol WebSocketTasking: AnyObject {
|
||||
|
||||
extension URLSessionWebSocketTask: WebSocketTasking {}
|
||||
|
||||
private final class WebSocketPingContinuationGate: @unchecked Sendable {
|
||||
private let lock = NSLock()
|
||||
private var didResume = false
|
||||
|
||||
func resumeOnce(_ resume: () -> Void) {
|
||||
self.lock.lock()
|
||||
if self.didResume {
|
||||
self.lock.unlock()
|
||||
return
|
||||
}
|
||||
self.didResume = true
|
||||
self.lock.unlock()
|
||||
resume()
|
||||
}
|
||||
}
|
||||
|
||||
public struct WebSocketTaskBox: @unchecked Sendable {
|
||||
public let task: any WebSocketTasking
|
||||
public init(task: any WebSocketTasking) {
|
||||
@@ -48,8 +64,13 @@ public struct WebSocketTaskBox: @unchecked Sendable {
|
||||
|
||||
public func sendPing() async throws {
|
||||
try await withCheckedThrowingContinuation { (continuation: CheckedContinuation<Void, Error>) in
|
||||
let gate = WebSocketPingContinuationGate()
|
||||
self.task.sendPing { error in
|
||||
ThrowingContinuationSupport.resumeVoid(continuation, error: error)
|
||||
// URLSession can race ping callbacks with cancellation; only the first
|
||||
// pong result owns this checked continuation or Swift traps the app.
|
||||
gate.resumeOnce {
|
||||
ThrowingContinuationSupport.resumeVoid(continuation, error: error)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -389,6 +389,15 @@
|
||||
"plan.0.step"
|
||||
]
|
||||
},
|
||||
"skill_workshop": {
|
||||
"emoji": "🧰",
|
||||
"title": "Skill Workshop",
|
||||
"detailKeys": [
|
||||
"action",
|
||||
"name",
|
||||
"proposal_id"
|
||||
]
|
||||
},
|
||||
"gateway": {
|
||||
"emoji": "🔌",
|
||||
"title": "Gateway",
|
||||
|
||||
@@ -5276,6 +5276,334 @@ public struct SkillsDetailResult: Codable, Sendable {
|
||||
}
|
||||
}
|
||||
|
||||
public struct SkillsProposalsListParams: Codable, Sendable {
|
||||
public let agentid: String?
|
||||
|
||||
public init(
|
||||
agentid: String? = nil)
|
||||
{
|
||||
self.agentid = agentid
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case agentid = "agentId"
|
||||
}
|
||||
}
|
||||
|
||||
public struct SkillsProposalsListResult: Codable, Sendable {
|
||||
public let schema: String
|
||||
public let updatedat: String
|
||||
public let proposals: [[String: AnyCodable]]
|
||||
|
||||
public init(
|
||||
schema: String,
|
||||
updatedat: String,
|
||||
proposals: [[String: AnyCodable]])
|
||||
{
|
||||
self.schema = schema
|
||||
self.updatedat = updatedat
|
||||
self.proposals = proposals
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case schema
|
||||
case updatedat = "updatedAt"
|
||||
case proposals
|
||||
}
|
||||
}
|
||||
|
||||
public struct SkillsProposalInspectParams: Codable, Sendable {
|
||||
public let agentid: String?
|
||||
public let proposalid: String
|
||||
|
||||
public init(
|
||||
agentid: String? = nil,
|
||||
proposalid: String)
|
||||
{
|
||||
self.agentid = agentid
|
||||
self.proposalid = proposalid
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case agentid = "agentId"
|
||||
case proposalid = "proposalId"
|
||||
}
|
||||
}
|
||||
|
||||
public struct SkillsProposalInspectResult: Codable, Sendable {
|
||||
public let record: SkillsProposalRecordResult
|
||||
public let content: String
|
||||
public let supportfiles: [[String: AnyCodable]]?
|
||||
|
||||
public init(
|
||||
record: SkillsProposalRecordResult,
|
||||
content: String,
|
||||
supportfiles: [[String: AnyCodable]]?)
|
||||
{
|
||||
self.record = record
|
||||
self.content = content
|
||||
self.supportfiles = supportfiles
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case record
|
||||
case content
|
||||
case supportfiles = "supportFiles"
|
||||
}
|
||||
}
|
||||
|
||||
public struct SkillsProposalCreateParams: Codable, Sendable {
|
||||
public let agentid: String?
|
||||
public let name: String
|
||||
public let description: String
|
||||
public let content: String
|
||||
public let supportfiles: [[String: AnyCodable]]?
|
||||
public let goal: String?
|
||||
public let evidence: String?
|
||||
|
||||
public init(
|
||||
agentid: String? = nil,
|
||||
name: String,
|
||||
description: String,
|
||||
content: String,
|
||||
supportfiles: [[String: AnyCodable]]?,
|
||||
goal: String?,
|
||||
evidence: String?)
|
||||
{
|
||||
self.agentid = agentid
|
||||
self.name = name
|
||||
self.description = description
|
||||
self.content = content
|
||||
self.supportfiles = supportfiles
|
||||
self.goal = goal
|
||||
self.evidence = evidence
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case agentid = "agentId"
|
||||
case name
|
||||
case description
|
||||
case content
|
||||
case supportfiles = "supportFiles"
|
||||
case goal
|
||||
case evidence
|
||||
}
|
||||
}
|
||||
|
||||
public struct SkillsProposalUpdateParams: Codable, Sendable {
|
||||
public let agentid: String?
|
||||
public let skillname: String
|
||||
public let description: String?
|
||||
public let content: String
|
||||
public let supportfiles: [[String: AnyCodable]]?
|
||||
public let goal: String?
|
||||
public let evidence: String?
|
||||
|
||||
public init(
|
||||
agentid: String? = nil,
|
||||
skillname: String,
|
||||
description: String?,
|
||||
content: String,
|
||||
supportfiles: [[String: AnyCodable]]?,
|
||||
goal: String?,
|
||||
evidence: String?)
|
||||
{
|
||||
self.agentid = agentid
|
||||
self.skillname = skillname
|
||||
self.description = description
|
||||
self.content = content
|
||||
self.supportfiles = supportfiles
|
||||
self.goal = goal
|
||||
self.evidence = evidence
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case agentid = "agentId"
|
||||
case skillname = "skillName"
|
||||
case description
|
||||
case content
|
||||
case supportfiles = "supportFiles"
|
||||
case goal
|
||||
case evidence
|
||||
}
|
||||
}
|
||||
|
||||
public struct SkillsProposalReviseParams: Codable, Sendable {
|
||||
public let agentid: String?
|
||||
public let proposalid: String
|
||||
public let content: String
|
||||
public let supportfiles: [[String: AnyCodable]]?
|
||||
public let description: String?
|
||||
public let goal: String?
|
||||
public let evidence: String?
|
||||
|
||||
public init(
|
||||
agentid: String? = nil,
|
||||
proposalid: String,
|
||||
content: String,
|
||||
supportfiles: [[String: AnyCodable]]?,
|
||||
description: String?,
|
||||
goal: String?,
|
||||
evidence: String?)
|
||||
{
|
||||
self.agentid = agentid
|
||||
self.proposalid = proposalid
|
||||
self.content = content
|
||||
self.supportfiles = supportfiles
|
||||
self.description = description
|
||||
self.goal = goal
|
||||
self.evidence = evidence
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case agentid = "agentId"
|
||||
case proposalid = "proposalId"
|
||||
case content
|
||||
case supportfiles = "supportFiles"
|
||||
case description
|
||||
case goal
|
||||
case evidence
|
||||
}
|
||||
}
|
||||
|
||||
public struct SkillsProposalActionParams: Codable, Sendable {
|
||||
public let agentid: String?
|
||||
public let proposalid: String
|
||||
public let reason: String?
|
||||
|
||||
public init(
|
||||
agentid: String? = nil,
|
||||
proposalid: String,
|
||||
reason: String?)
|
||||
{
|
||||
self.agentid = agentid
|
||||
self.proposalid = proposalid
|
||||
self.reason = reason
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case agentid = "agentId"
|
||||
case proposalid = "proposalId"
|
||||
case reason
|
||||
}
|
||||
}
|
||||
|
||||
public struct SkillsProposalApplyResult: Codable, Sendable {
|
||||
public let record: SkillsProposalRecordResult
|
||||
public let targetskillfile: String
|
||||
|
||||
public init(
|
||||
record: SkillsProposalRecordResult,
|
||||
targetskillfile: String)
|
||||
{
|
||||
self.record = record
|
||||
self.targetskillfile = targetskillfile
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case record
|
||||
case targetskillfile = "targetSkillFile"
|
||||
}
|
||||
}
|
||||
|
||||
public struct SkillsProposalRecordResult: Codable, Sendable {
|
||||
public let schema: String
|
||||
public let id: String
|
||||
public let kind: AnyCodable
|
||||
public let status: AnyCodable
|
||||
public let title: String
|
||||
public let description: String
|
||||
public let createdat: String
|
||||
public let updatedat: String
|
||||
public let createdby: AnyCodable
|
||||
public let proposedversion: String
|
||||
public let draftfile: String
|
||||
public let drafthash: String
|
||||
public let supportfiles: [[String: AnyCodable]]?
|
||||
public let target: [String: AnyCodable]
|
||||
public let scan: [String: AnyCodable]
|
||||
public let goal: String?
|
||||
public let evidence: String?
|
||||
public let appliedat: String?
|
||||
public let rejectedat: String?
|
||||
public let quarantinedat: String?
|
||||
public let staleat: String?
|
||||
public let statusreason: String?
|
||||
|
||||
public init(
|
||||
schema: String,
|
||||
id: String,
|
||||
kind: AnyCodable,
|
||||
status: AnyCodable,
|
||||
title: String,
|
||||
description: String,
|
||||
createdat: String,
|
||||
updatedat: String,
|
||||
createdby: AnyCodable,
|
||||
proposedversion: String,
|
||||
draftfile: String,
|
||||
drafthash: String,
|
||||
supportfiles: [[String: AnyCodable]]?,
|
||||
target: [String: AnyCodable],
|
||||
scan: [String: AnyCodable],
|
||||
goal: String?,
|
||||
evidence: String?,
|
||||
appliedat: String?,
|
||||
rejectedat: String?,
|
||||
quarantinedat: String?,
|
||||
staleat: String?,
|
||||
statusreason: String?)
|
||||
{
|
||||
self.schema = schema
|
||||
self.id = id
|
||||
self.kind = kind
|
||||
self.status = status
|
||||
self.title = title
|
||||
self.description = description
|
||||
self.createdat = createdat
|
||||
self.updatedat = updatedat
|
||||
self.createdby = createdby
|
||||
self.proposedversion = proposedversion
|
||||
self.draftfile = draftfile
|
||||
self.drafthash = drafthash
|
||||
self.supportfiles = supportfiles
|
||||
self.target = target
|
||||
self.scan = scan
|
||||
self.goal = goal
|
||||
self.evidence = evidence
|
||||
self.appliedat = appliedat
|
||||
self.rejectedat = rejectedat
|
||||
self.quarantinedat = quarantinedat
|
||||
self.staleat = staleat
|
||||
self.statusreason = statusreason
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case schema
|
||||
case id
|
||||
case kind
|
||||
case status
|
||||
case title
|
||||
case description
|
||||
case createdat = "createdAt"
|
||||
case updatedat = "updatedAt"
|
||||
case createdby = "createdBy"
|
||||
case proposedversion = "proposedVersion"
|
||||
case draftfile = "draftFile"
|
||||
case drafthash = "draftHash"
|
||||
case supportfiles = "supportFiles"
|
||||
case target
|
||||
case scan
|
||||
case goal
|
||||
case evidence
|
||||
case appliedat = "appliedAt"
|
||||
case rejectedat = "rejectedAt"
|
||||
case quarantinedat = "quarantinedAt"
|
||||
case staleat = "staleAt"
|
||||
case statusreason = "statusReason"
|
||||
}
|
||||
}
|
||||
|
||||
public struct SkillsSecurityVerdictsParams: Codable, Sendable {
|
||||
public let agentid: String?
|
||||
|
||||
|
||||
@@ -11,6 +11,42 @@ private extension NSLock {
|
||||
}
|
||||
}
|
||||
|
||||
private final class DoubleCallbackPingWebSocketTask: WebSocketTasking, @unchecked Sendable {
|
||||
private let callbacks: [Error?]
|
||||
|
||||
init(callbacks: [Error?]) {
|
||||
self.callbacks = callbacks
|
||||
}
|
||||
|
||||
var state: URLSessionTask.State { .running }
|
||||
|
||||
func resume() {}
|
||||
|
||||
func cancel(with closeCode: URLSessionWebSocketTask.CloseCode, reason: Data?) {
|
||||
_ = (closeCode, reason)
|
||||
}
|
||||
|
||||
func send(_ message: URLSessionWebSocketTask.Message) async throws {
|
||||
_ = message
|
||||
}
|
||||
|
||||
func sendPing(pongReceiveHandler: @escaping @Sendable (Error?) -> Void) {
|
||||
for callback in self.callbacks {
|
||||
pongReceiveHandler(callback)
|
||||
}
|
||||
}
|
||||
|
||||
func receive() async throws -> URLSessionWebSocketTask.Message {
|
||||
throw URLError(.badServerResponse)
|
||||
}
|
||||
|
||||
func receive(
|
||||
completionHandler: @escaping @Sendable (Result<URLSessionWebSocketTask.Message, Error>) -> Void)
|
||||
{
|
||||
completionHandler(.failure(URLError(.badServerResponse)))
|
||||
}
|
||||
}
|
||||
|
||||
private final class FakeGatewayWebSocketTask: WebSocketTasking, @unchecked Sendable {
|
||||
private let lock = NSLock()
|
||||
private let helloAuth: [String: Any]?
|
||||
@@ -193,6 +229,25 @@ private actor SeqGapProbe {
|
||||
|
||||
@Suite(.serialized)
|
||||
struct GatewayNodeSessionTests {
|
||||
@Test
|
||||
func websocketPingIgnoresDuplicateSuccessCallbacks() async throws {
|
||||
let task = DoubleCallbackPingWebSocketTask(callbacks: [nil, nil])
|
||||
try await WebSocketTaskBox(task: task).sendPing()
|
||||
}
|
||||
|
||||
@Test
|
||||
func websocketPingIgnoresDuplicateCallbacksAfterFirstError() async throws {
|
||||
let firstError = URLError(.networkConnectionLost)
|
||||
let task = DoubleCallbackPingWebSocketTask(callbacks: [firstError, nil])
|
||||
|
||||
do {
|
||||
try await WebSocketTaskBox(task: task).sendPing()
|
||||
Issue.record("sendPing unexpectedly succeeded")
|
||||
} catch let error as URLError {
|
||||
#expect(error.code == firstError.code)
|
||||
}
|
||||
}
|
||||
|
||||
@Test
|
||||
func scannedSetupCodePrefersBootstrapAuthOverStoredDeviceToken() async throws {
|
||||
let tempDir = FileManager.default.temporaryDirectory
|
||||
|
||||
@@ -180,6 +180,14 @@ const config = {
|
||||
entry: ["src/index.ts!", "src/ip.ts!"],
|
||||
project: ["src/**/*.ts!"],
|
||||
},
|
||||
"packages/markdown-core": {
|
||||
entry: ["src/*.ts!"],
|
||||
project: ["src/**/*.ts!"],
|
||||
},
|
||||
"packages/terminal-core": {
|
||||
entry: ["src/*.ts!"],
|
||||
project: ["src/**/*.ts!"],
|
||||
},
|
||||
"packages/speech-core": {
|
||||
entry: ["api.ts!", "runtime-api.ts!", "speaker.ts!", "voice-models.ts!"],
|
||||
project: ["**/*.ts!"],
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
ac5e91a6adaf02491d2ff6b983f054c813972da3bf79db68cd1d10887a22c594 config-baseline.json
|
||||
023e3b85ee79e85f90257e65a1376b1212cf534b6a9cff4b4388c9092e846549 config-baseline.core.json
|
||||
370da2e3a4253f00c3963a3ad8b57707ea3f67a8d0d394b7d2b96db4f3413d32 config-baseline.json
|
||||
6a66c70d36dacf5fd1a8b7e157d1ff4812e97f518c13ebc3190509df4c269f29 config-baseline.core.json
|
||||
a9102c0611b8170fac37853cc31771810f31757a9e3b2c6796bbd9625f9b9206 config-baseline.channel.json
|
||||
2f018852d9682871dd22f0920cafc8994a6c0952e8101229210efa6103ae9536 config-baseline.plugin.json
|
||||
923a8cac695c752e51751cc2dea185a3fbe19d0015722f7ea1909f897dfbb898 config-baseline.plugin.json
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
49a138a9743063067b983c4dd27d047572aef0764c0e5f87a98d91f43d4f8213 plugin-sdk-api-baseline.json
|
||||
cd7ea2f2b4c1d1d073c3077410d44270244e778f33197567f4127a946cc0f7f7 plugin-sdk-api-baseline.jsonl
|
||||
cf29066e9465cb5ac1387d1d482d0939b9176220ecc69964da9af1a471939269 plugin-sdk-api-baseline.json
|
||||
ab43993cf713a96b191c55cf89bb215c18ecdc2d8edf50f31369ce3b162c56e3 plugin-sdk-api-baseline.jsonl
|
||||
|
||||
@@ -40,11 +40,9 @@ Cron is the Gateway's built-in scheduler. It persists jobs, wakes the agent at t
|
||||
## How cron works
|
||||
|
||||
- Cron runs **inside the Gateway** process (not inside the model).
|
||||
- Job definitions persist at `~/.openclaw/cron/jobs.json` so restarts do not lose schedules.
|
||||
- Runtime execution state persists next to it in `~/.openclaw/cron/jobs-state.json`. If you track cron definitions in git, track `jobs.json` and gitignore `jobs-state.json`.
|
||||
- If `jobs.json` contains malformed rows, the Gateway keeps valid jobs running, removes the malformed rows from the active store, and saves the raw rows beside it in `jobs-quarantine.json` for later repair or review.
|
||||
- After the split, older OpenClaw versions can read `jobs.json` but may treat jobs as fresh because runtime fields now live in `jobs-state.json`.
|
||||
- When `jobs.json` is edited while the Gateway is running or stopped, OpenClaw compares the changed schedule fields with pending runtime slot metadata and clears stale `nextRunAtMs` values. Pure formatting or key-order-only rewrites preserve the pending slot.
|
||||
- Job definitions, runtime state, and run history persist in OpenClaw's shared SQLite state database so restarts do not lose schedules.
|
||||
- On upgrade, legacy `~/.openclaw/cron/jobs.json`, `jobs-state.json`, and `runs/*.jsonl` files are imported once and renamed with a `.migrated` suffix. Malformed job rows are skipped from runtime and copied to `jobs-quarantine.json` for later repair or review.
|
||||
- `cron.store` still names the logical cron store key and legacy import path. After import, editing that JSON file no longer changes active cron jobs; use `openclaw cron add|edit|remove` or the Gateway cron RPC methods instead.
|
||||
- All cron executions create [background task](/automation/tasks) records.
|
||||
- On Gateway startup, overdue isolated agent-turn jobs are rescheduled out of the channel-connect window instead of replaying immediately, so Discord/Telegram startup and native-command setup stay responsive after restarts.
|
||||
- One-shot jobs (`--at`) auto-delete after success by default.
|
||||
@@ -462,9 +460,7 @@ Model override note:
|
||||
|
||||
`maxConcurrentRuns` limits both scheduled cron dispatch and isolated agent-turn execution, and defaults to 8. Isolated cron agent turns use the queue's dedicated `cron-nested` execution lane internally, so raising this value lets independent cron LLM runs progress in parallel instead of only starting their outer cron wrappers. The shared non-cron `nested` lane is not widened by this setting.
|
||||
|
||||
The runtime state sidecar is derived from `cron.store`: a `.json` store such as `~/clawd/cron/jobs.json` uses `~/clawd/cron/jobs-state.json`, while a store path without a `.json` suffix appends `-state.json`.
|
||||
|
||||
If you hand-edit `jobs.json`, leave `jobs-state.json` out of source control. OpenClaw uses that sidecar for pending slots, active markers, last-run metadata, and the schedule identity that tells the scheduler when an externally edited job needs a fresh `nextRunAtMs`.
|
||||
`cron.store` is a logical store key and legacy import path. Existing stores are imported into SQLite on first load and archived; future cron changes should go through the CLI or Gateway API.
|
||||
|
||||
Disable cron: `cron.enabled: false` or `OPENCLAW_SKIP_CRON=1`.
|
||||
|
||||
@@ -476,7 +472,7 @@ Disable cron: `cron.enabled: false` or `OPENCLAW_SKIP_CRON=1`.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Maintenance">
|
||||
`cron.sessionRetention` (default `24h`) prunes isolated run-session entries. `cron.runLog.maxBytes` / `cron.runLog.keepLines` auto-prune run-log files.
|
||||
`cron.sessionRetention` (default `24h`) prunes isolated run-session entries. `cron.runLog.keepLines` limits retained SQLite run-history rows per job; `maxBytes` is retained for config compatibility with older file-backed run logs.
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
|
||||
@@ -346,7 +346,7 @@ A sweeper runs every **60 seconds** and handles four things:
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Tasks and cron">
|
||||
A cron job **definition** lives in `~/.openclaw/cron/jobs.json`; runtime execution state lives beside it in `~/.openclaw/cron/jobs-state.json`. **Every** cron execution creates a task record - both main-session and isolated. Main-session cron tasks default to `silent` notify policy so they track without generating notifications.
|
||||
Cron job definitions, runtime execution state, and run history live in OpenClaw's shared SQLite state database. **Every** cron execution creates a task record - both main-session and isolated. Main-session cron tasks default to `silent` notify policy so they track without generating notifications.
|
||||
|
||||
See [Cron Jobs](/automation/cron-jobs).
|
||||
|
||||
|
||||
@@ -354,7 +354,7 @@ To restrict who can click a button, set `allowedUsers` on that button (Discord u
|
||||
|
||||
Component callbacks expire after 30 minutes by default. Set `channels.discord.agentComponents.ttlMs` to change that callback registry lifetime for the default Discord account, or `channels.discord.accounts.<accountId>.agentComponents.ttlMs` to override one account in a multi-account setup. The value is milliseconds, must be a positive integer, and is capped at `86400000` (24 hours). Longer TTLs are useful for review or approval workflows that need buttons to remain usable, but they also extend the window where an old Discord message can still trigger an action. Prefer the shortest TTL that fits the workflow, and keep the default when stale callbacks would be surprising.
|
||||
|
||||
The `/model` and `/models` slash commands open an interactive model picker with provider, model, and compatible runtime dropdowns plus a Submit step. `/models add` is deprecated and now returns a deprecation message instead of registering models from chat. The picker reply is ephemeral and only the invoking user can use it. Discord select menus are limited to 25 options, so add `provider/*` entries to `agents.defaults.models` when you want the picker to show dynamically discovered models only for selected providers such as `openai-codex` or `vllm`.
|
||||
The `/model` and `/models` slash commands open an interactive model picker with provider, model, and compatible runtime dropdowns plus a Submit step. `/models add` is deprecated and now returns a deprecation message instead of registering models from chat. The picker reply is ephemeral and only the invoking user can use it. Discord select menus are limited to 25 options, so add `provider/*` entries to `agents.defaults.models` when you want the picker to show dynamically discovered models only for selected providers such as `openai` or `vllm`.
|
||||
|
||||
File attachments:
|
||||
|
||||
@@ -1197,7 +1197,7 @@ Auto-join example:
|
||||
discord: {
|
||||
voice: {
|
||||
enabled: true,
|
||||
model: "openai-codex/gpt-5.5",
|
||||
model: "openai/gpt-5.5",
|
||||
autoJoin: [
|
||||
{
|
||||
guildId: "123456789012345678",
|
||||
@@ -1234,7 +1234,7 @@ Notes:
|
||||
- `voice.followUsers` lets the bot join, move, and leave Discord voice with selected users. See [Follow users in voice](#follow-users-in-voice) for behavior rules and examples.
|
||||
- `agent-proxy` routes speech through `discord-voice`, which preserves normal owner/tool authorization for the speaker and target session but hides the agent `tts` tool because Discord voice owns playback. By default, `agent-proxy` gives the consult full owner-equivalent tool access for owner speakers (`voice.realtime.toolPolicy: "owner"`) and strongly prefers consulting the OpenClaw agent before substantive answers (`voice.realtime.consultPolicy: "always"`). In that default `always` mode, the realtime layer does not auto-speak filler before the consult answer; it captures and transcribes speech, then speaks the routed OpenClaw answer. If multiple forced consult answers finish while Discord is still playing the first answer, later exact-speech answers are queued until playback idles instead of replacing speech mid-sentence.
|
||||
- In `stt-tts` mode, STT uses `tools.media.audio`; `voice.model` does not affect transcription.
|
||||
- In realtime modes, `voice.realtime.provider`, `voice.realtime.model`, and `voice.realtime.speakerVoice` configure the realtime audio session. For OpenAI Realtime 2 plus the Codex brain, use `voice.realtime.model: "gpt-realtime-2"` and `voice.model: "openai-codex/gpt-5.5"`.
|
||||
- In realtime modes, `voice.realtime.provider`, `voice.realtime.model`, and `voice.realtime.speakerVoice` configure the realtime audio session. For OpenAI Realtime 2 plus the Codex brain, use `voice.realtime.model: "gpt-realtime-2"` and `voice.model: "openai/gpt-5.5"`.
|
||||
- Realtime voice modes include small `IDENTITY.md`, `USER.md`, and `SOUL.md` profile files in the realtime provider instructions by default so fast direct turns keep the same identity, user grounding, and persona as the routed OpenClaw agent. Set `voice.realtime.bootstrapContextFiles` to a subset to customize this, or `[]` to disable it. The supported realtime bootstrap files are limited to those profile files; `AGENTS.md` stays in the normal agent context. The injected profile context does not replace `openclaw_agent_consult` for workspace work, current facts, memory lookup, or tool-backed actions.
|
||||
- In OpenAI `agent-proxy` realtime mode, set `voice.realtime.requireWakeName: true` to keep Discord realtime voice silent until a transcript starts or ends with a wake name. Configured wake names must be one or two words. If `voice.realtime.wakeNames` is unset, OpenClaw uses the routed agent `name` plus `OpenClaw`, falling back to the agent id plus `OpenClaw`. Wake-name gating disables realtime provider auto-response, routes accepted turns through the OpenClaw agent consult path, and gives a short spoken acknowledgement when a leading wake name is recognized from partial transcription before the final transcript arrives.
|
||||
- The OpenAI realtime provider accepts current Realtime 2 event names and legacy Codex-compatible aliases for output audio and transcript events, so compatible provider snapshots can drift without dropping assistant audio.
|
||||
@@ -1325,7 +1325,7 @@ Default agent-proxy voice-channel session example:
|
||||
discord: {
|
||||
voice: {
|
||||
enabled: true,
|
||||
model: "openai-codex/gpt-5.5",
|
||||
model: "openai/gpt-5.5",
|
||||
followUsersEnabled: true,
|
||||
followUsers: ["123456789012345678"],
|
||||
realtime: {
|
||||
@@ -1375,7 +1375,7 @@ Realtime bidi example:
|
||||
voice: {
|
||||
enabled: true,
|
||||
mode: "bidi",
|
||||
model: "openai-codex/gpt-5.5",
|
||||
model: "openai/gpt-5.5",
|
||||
realtime: {
|
||||
provider: "openai",
|
||||
model: "gpt-realtime-2",
|
||||
@@ -1398,7 +1398,7 @@ Voice as an extension of an existing Discord channel session:
|
||||
voice: {
|
||||
enabled: true,
|
||||
mode: "agent-proxy",
|
||||
model: "openai-codex/gpt-5.5",
|
||||
model: "openai/gpt-5.5",
|
||||
agentSession: {
|
||||
mode: "target",
|
||||
target: "channel:123456789012345678",
|
||||
@@ -1433,7 +1433,7 @@ Echo-heavy OpenAI Realtime example:
|
||||
voice: {
|
||||
enabled: true,
|
||||
mode: "bidi",
|
||||
model: "openai-codex/gpt-5.5",
|
||||
model: "openai/gpt-5.5",
|
||||
realtime: {
|
||||
provider: "openai",
|
||||
model: "gpt-realtime-2",
|
||||
|
||||
@@ -915,9 +915,10 @@ Uploaded files are stored in a `/OpenClawShared/` folder in the configured Share
|
||||
OpenClaw sends Teams polls as Adaptive Cards (there is no native Teams poll API).
|
||||
|
||||
- CLI: `openclaw message poll --channel msteams --target conversation:<id> ...`
|
||||
- Votes are recorded by the gateway in `~/.openclaw/msteams-polls.json`.
|
||||
- Votes are recorded by the gateway in OpenClaw plugin-state SQLite under `state/openclaw.sqlite`.
|
||||
- Existing `msteams-polls.json` files are imported once when the MSTeams plugin starts.
|
||||
- The gateway must stay online to record votes.
|
||||
- Polls do not auto-post result summaries yet (inspect the store file if needed).
|
||||
- Polls do not auto-post result summaries yet, and there is no supported poll-results CLI yet.
|
||||
|
||||
## Presentation cards
|
||||
|
||||
|
||||
@@ -118,7 +118,7 @@ Skipped runs are tracked separately from execution errors. They do not affect re
|
||||
|
||||
For isolated jobs that target a local configured model provider, cron runs a lightweight provider preflight before starting the agent turn. Loopback, private-network, and `.local` `api: "ollama"` providers are probed at `/api/tags`; local OpenAI-compatible providers such as vLLM, SGLang, and LM Studio are probed at `/models`. If the endpoint is unreachable, the run is recorded as `skipped` and retried on a later schedule; matching dead endpoints are cached for 5 minutes to avoid many jobs hammering the same local server.
|
||||
|
||||
Note: cron job definitions live in `jobs.json`, while pending runtime state lives in `jobs-state.json`. If `jobs.json` is edited externally, the Gateway reloads changed schedules and clears stale pending slots; formatting-only rewrites do not clear the pending slot. Malformed job rows are removed from active `jobs.json` at load time after their raw contents are copied to `jobs-quarantine.json`.
|
||||
Note: cron jobs, pending runtime state, and run history live in the shared SQLite state database. Legacy `jobs.json`, `jobs-state.json`, and `runs/*.jsonl` files are imported once and renamed with a `.migrated` suffix. After import, edit schedules with `openclaw cron add|edit|remove` instead of editing JSON files.
|
||||
|
||||
### Manual runs
|
||||
|
||||
@@ -199,7 +199,7 @@ Cron does not classify final-output prose or approval-looking refusal phrases as
|
||||
Retention and pruning are controlled in config:
|
||||
|
||||
- `cron.sessionRetention` (default `24h`) prunes completed isolated run sessions.
|
||||
- `cron.runLog.maxBytes` and `cron.runLog.keepLines` prune `~/.openclaw/cron/runs/<jobId>.jsonl`.
|
||||
- `cron.runLog.keepLines` prunes retained SQLite run-history rows per job. `cron.runLog.maxBytes` remains accepted for compatibility with older file-backed run logs.
|
||||
|
||||
## Migrating older jobs
|
||||
|
||||
|
||||
@@ -203,7 +203,7 @@ Notes:
|
||||
- Doctor reports cron jobs with explicit `payload.model` overrides, including provider namespace counts and mismatches against `agents.defaults.model`, so scheduled jobs that do not inherit the default model are visible during auth or billing investigations.
|
||||
- On Linux, doctor warns when the user's crontab still runs legacy `~/.openclaw/bin/ensure-whatsapp.sh`; that script is no longer maintained and can log false WhatsApp gateway outages when cron lacks the systemd user-bus environment.
|
||||
- When WhatsApp is enabled, doctor checks for a degraded Gateway event loop with local `openclaw-tui` clients still running. `doctor --fix` stops only verified local TUI clients so WhatsApp replies are not queued behind stale TUI refresh loops.
|
||||
- Doctor rewrites legacy `openai-codex/*` model refs to canonical `openai/*` refs across primary models, fallbacks, heartbeat/subagent/compaction overrides, hooks, channel model overrides, and stale session route pins. `--fix` moves Codex intent onto provider/model-scoped `agentRuntime.id: "codex"` entries, preserves session auth-profile pins such as `openai-codex:...`, removes stale whole-agent/session runtime pins, and keeps repaired OpenAI agent refs on Codex auth routing instead of direct OpenAI API-key auth.
|
||||
- Doctor rewrites legacy `openai-codex/*` model refs to canonical `openai/*` refs across primary models, fallbacks, image/video generation models, heartbeat/subagent/compaction overrides, hooks, channel model overrides, and stale session route pins. `--fix` also migrates legacy `openai-codex:*` auth profiles and `auth.order.openai-codex` entries to `openai:*`, moves Codex intent onto provider/model-scoped `agentRuntime.id: "codex"` entries, removes stale whole-agent/session runtime pins, and keeps repaired OpenAI agent refs on Codex auth routing instead of direct OpenAI API-key auth.
|
||||
- Doctor cleans legacy plugin dependency staging state created by older OpenClaw versions and relinks the host `openclaw` package for managed npm plugins that declare it as a peer dependency. It also repairs missing downloadable plugins that are referenced by config, such as `plugins.entries`, configured channels, configured provider/search settings, or configured agent runtimes. During package updates, doctor skips package-manager plugin repair until the package swap is complete; rerun `openclaw doctor --fix` afterward if a configured plugin still needs recovery. If the download fails, doctor reports the install error and preserves the configured plugin entry for the next repair attempt.
|
||||
- Doctor repairs stale plugin config by removing missing plugin ids from `plugins.allow`/`plugins.deny`/`plugins.entries`, plus matching dangling channel config, heartbeat targets, and channel model overrides when plugin discovery is healthy.
|
||||
- Doctor quarantines invalid plugin config by disabling the affected `plugins.entries.<id>` entry and removing its invalid `config` payload. Gateway startup already skips only that bad plugin so other plugins and channels can keep running.
|
||||
|
||||
@@ -129,7 +129,7 @@ This table maps common inference tasks to the corresponding infer command.
|
||||
- Use `model run --thinking <level>` to pass a one-shot thinking/reasoning level (`off`, `minimal`, `low`, `medium`, `high`, `adaptive`, `xhigh`, or `max`) while keeping the run raw.
|
||||
- For `image describe`, `audio transcribe`, and `video describe`, `--model` must use the form `<provider/model>`.
|
||||
- For `image describe`, `--file` accepts local paths and HTTP(S) image URLs. Remote URLs use the normal media-fetch SSRF policy.
|
||||
- For `image describe`, an explicit `--model` runs that provider/model directly. The model must be image-capable in the model catalog or provider config. `codex/<model>` runs a bounded Codex app-server image-understanding turn; `openai-codex/<model>` uses the OpenAI Codex OAuth provider path.
|
||||
- For `image describe`, an explicit `--model` runs that provider/model directly. The model must be image-capable in the model catalog or provider config. `codex/<model>` runs a bounded Codex app-server image-understanding turn; `openai/<model>` uses the OpenAI provider path with either API-key or ChatGPT/Codex OAuth auth.
|
||||
- Stateless execution commands default to local.
|
||||
- Gateway-managed state commands default to gateway.
|
||||
- The normal local path does not require the gateway to be running.
|
||||
@@ -172,7 +172,7 @@ Notes:
|
||||
- Local `model run` is the narrowest CLI smoke for provider/model/auth health because, for non-Codex providers, it sends only the supplied prompt to the selected model.
|
||||
- Local `model run --model <provider/model>` can use exact bundled static catalog rows from `models list --all` before that provider is written to config. Provider auth is still required; missing credentials fail as auth errors, not `Unknown model`.
|
||||
- For Mistral Medium 3.5 reasoning probes, leave temperature unset/default. Mistral rejects `reasoning_effort="high"` plus `temperature: 0`; use `mistral/mistral-medium-3-5` with default temperature or a non-zero reasoning-mode value such as `0.7`.
|
||||
- `openai-codex/*` local probes are the narrow exception: OpenClaw adds a minimal system instruction so the Codex Responses transport can populate its required `instructions` field, without adding full agent context, tools, memory, or session transcript.
|
||||
- Codex Responses local probes are the narrow exception: OpenClaw adds a minimal system instruction so the transport can populate its required `instructions` field, without adding full agent context, tools, memory, or session transcript.
|
||||
- Local `model run --file` keeps that lean path and attaches image content directly to the single user message. Common image files such as PNG, JPEG, and WebP work when their MIME type is detected as `image/*`; unsupported or unrecognized files fail before the provider is called.
|
||||
- `model run --file` is best when you want to test the selected multimodal text model directly. Use `infer image describe` when you want OpenClaw's image-understanding provider selection and default image-model routing.
|
||||
- The selected model must support image input; text-only models may reject the request at the provider layer.
|
||||
|
||||
@@ -348,7 +348,8 @@ For broader testing context, see [Testing](/help/testing).
|
||||
|
||||
## OpenClaw as an MCP client registry
|
||||
|
||||
This is the `openclaw mcp list`, `show`, `set`, and `unset` path.
|
||||
This is the `openclaw mcp list`, `show`, `status`, `probe`, `set`, `tools`,
|
||||
and `unset` path.
|
||||
|
||||
These commands do not expose OpenClaw over MCP. They manage OpenClaw-owned MCP server definitions under `mcp.servers` in OpenClaw config.
|
||||
|
||||
@@ -357,10 +358,15 @@ Those saved definitions are for runtimes that OpenClaw launches or configures la
|
||||
<AccordionGroup>
|
||||
<Accordion title="Important behavior">
|
||||
- these commands only read or write OpenClaw config
|
||||
- they do not connect to the target MCP server
|
||||
- `status`, `list`, `show`, `set`, `tools`, and `unset` do not connect to the target MCP server
|
||||
- `probe` connects to the selected server or all configured servers, lists tools, and reports capabilities/diagnostics
|
||||
- they do not validate whether the command, URL, or remote transport is reachable right now
|
||||
- runtime adapters decide which transport shapes they actually support at execution time
|
||||
- embedded OpenClaw exposes configured MCP tools in normal `coding` and `messaging` tool profiles; `minimal` still hides them, and `tools.deny: ["bundle-mcp"]` disables them explicitly
|
||||
- per-server `toolFilter.include` and `toolFilter.exclude` filter discovered MCP tools before they become OpenClaw tools
|
||||
- servers that advertise resources or prompts also expose utility tools for listing/reading resources and listing/fetching prompts; those generated utility names (`resources_list`, `resources_read`, `prompts_list`, `prompts_get`) use the same include/exclude filter
|
||||
- dynamic MCP tool-list changes invalidate the cached catalog for that session; the next discovery/use refreshes from the server
|
||||
- repeated MCP tool request/protocol failures pause that server briefly so one broken server does not consume the whole turn
|
||||
- session-scoped bundled MCP runtimes are reaped after `mcp.sessionIdleTtlMs` milliseconds of idle time (default 10 minutes; set `0` to disable) and one-shot embedded runs clean them up at run end
|
||||
|
||||
</Accordion>
|
||||
@@ -387,14 +393,20 @@ Commands:
|
||||
|
||||
- `openclaw mcp list`
|
||||
- `openclaw mcp show [name]`
|
||||
- `openclaw mcp status`
|
||||
- `openclaw mcp probe [name]`
|
||||
- `openclaw mcp set <name> <json>`
|
||||
- `openclaw mcp tools <name> [--include csv] [--exclude csv] [--clear]`
|
||||
- `openclaw mcp unset <name>`
|
||||
|
||||
Notes:
|
||||
|
||||
- `list` sorts server names.
|
||||
- `show` without a name prints the full configured MCP server object.
|
||||
- `status` classifies configured transports without connecting.
|
||||
- `probe` connects and reports tool counts, resources/prompts support, list-change support, and diagnostics.
|
||||
- `set` expects one JSON object value on the command line.
|
||||
- `tools` updates per-server tool filters. Include/exclude entries are MCP tool names and simple `*` globs.
|
||||
- Use `transport: "streamable-http"` for Streamable HTTP MCP servers. `openclaw mcp set` also normalizes CLI-native `type: "http"` to the same canonical config shape for compatibility.
|
||||
- `unset` fails if the named server does not exist.
|
||||
|
||||
@@ -403,7 +415,10 @@ Examples:
|
||||
```bash
|
||||
openclaw mcp list
|
||||
openclaw mcp show context7 --json
|
||||
openclaw mcp status
|
||||
openclaw mcp probe context7 --json
|
||||
openclaw mcp set context7 '{"command":"uvx","args":["context7-mcp"]}'
|
||||
openclaw mcp tools context7 --include 'resolve-library-id,get-library-docs'
|
||||
openclaw mcp set docs '{"url":"https://mcp.example.com","transport":"streamable-http"}'
|
||||
openclaw mcp unset context7
|
||||
```
|
||||
@@ -420,7 +435,11 @@ Example config shape:
|
||||
},
|
||||
"docs": {
|
||||
"url": "https://mcp.example.com",
|
||||
"transport": "streamable-http"
|
||||
"transport": "streamable-http",
|
||||
"toolFilter": {
|
||||
"include": ["search_*"],
|
||||
"exclude": ["admin_*"]
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -28,8 +28,8 @@ openclaw models scan
|
||||
`openclaw models status` shows the resolved default/fallbacks plus an auth overview.
|
||||
When provider usage snapshots are available, the OAuth/API-key status section includes
|
||||
provider usage windows and quota snapshots.
|
||||
Current usage-window providers: Anthropic, GitHub Copilot, Gemini CLI, OpenAI
|
||||
Codex, MiniMax, Xiaomi, and z.ai. Usage auth comes from provider-specific hooks
|
||||
Current usage-window providers: Anthropic, GitHub Copilot, Gemini CLI, OpenAI,
|
||||
MiniMax, Xiaomi, and z.ai. Usage auth comes from provider-specific hooks
|
||||
when available; otherwise OpenClaw falls back to matching OAuth/API-key
|
||||
credentials from auth profiles, env, or config.
|
||||
In `--json` output, `auth.providers` is the env/config/store-aware provider
|
||||
@@ -40,10 +40,10 @@ Use `--agent <id>` to inspect a configured agent's model/auth state. When omitte
|
||||
the command uses `OPENCLAW_AGENT_DIR` if set, otherwise the
|
||||
configured default agent.
|
||||
Probe rows can come from auth profiles, env credentials, or `models.json`.
|
||||
For Codex OAuth troubleshooting, `openclaw models status`,
|
||||
`openclaw models auth list --provider openai-codex`, and
|
||||
For OpenAI ChatGPT/Codex OAuth troubleshooting, `openclaw models status`,
|
||||
`openclaw models auth list --provider openai`, and
|
||||
`openclaw config get agents.defaults.model --json` are the quickest way to
|
||||
confirm whether an agent has a usable `openai-codex` auth profile for
|
||||
confirm whether an agent has a usable `openai` OAuth profile for
|
||||
`openai/*` through the native Codex runtime. See [OpenAI provider setup](/providers/openai#check-and-recover-codex-oauth-routing).
|
||||
|
||||
Notes:
|
||||
@@ -76,7 +76,7 @@ Notes:
|
||||
cap differs from the native context window; JSON rows include `contextTokens`
|
||||
when a provider exposes that cap.
|
||||
- `models list --provider <id>` filters by provider id, such as `moonshot` or
|
||||
`openai-codex`. It does not accept display labels from interactive provider
|
||||
`openai`. It does not accept display labels from interactive provider
|
||||
pickers, such as `Moonshot AI`.
|
||||
- Model refs are parsed by splitting on the **first** `/`. If the model ID includes `/` (OpenRouter-style), include the provider prefix (example: `openrouter/moonshotai/kimi-k2`).
|
||||
- If you omit the provider, OpenClaw resolves the input as an alias first, then
|
||||
@@ -181,7 +181,7 @@ provider you choose.
|
||||
|
||||
`models auth list` lists saved auth profiles for the selected agent without
|
||||
printing token, API-key, or OAuth secret material. Use `--provider <id>` to
|
||||
filter to one provider, such as `openai-codex`, and `--json` for scripting.
|
||||
filter to one provider, such as `openai`, and `--json` for scripting.
|
||||
|
||||
`models auth login` runs a provider plugin's auth flow (OAuth/API key). Use
|
||||
`openclaw plugins list` to see which providers are installed.
|
||||
@@ -192,15 +192,15 @@ specific configured agent store. The parent `--agent` flag is honored by
|
||||
|
||||
For OpenAI models, `--provider openai` defaults to ChatGPT/Codex account login.
|
||||
Use `--method api-key` only when you want to add an OpenAI API-key profile,
|
||||
usually as a backup for Codex subscription limits. The legacy
|
||||
`--provider openai-codex` spelling still works for existing scripts.
|
||||
usually as a backup for Codex subscription limits. Run `openclaw doctor --fix`
|
||||
to migrate older `openai-codex` auth/profile state to `openai`.
|
||||
|
||||
Examples:
|
||||
|
||||
```bash
|
||||
openclaw models auth login --provider openai --set-default
|
||||
openclaw models auth login --provider openai --method api-key
|
||||
openclaw models auth paste-api-key --provider openai-codex
|
||||
openclaw models auth paste-api-key --provider openai
|
||||
openclaw models auth list --provider openai
|
||||
```
|
||||
|
||||
@@ -212,7 +212,7 @@ Notes:
|
||||
- `paste-api-key` accepts API keys generated elsewhere, prompts for the key
|
||||
value, and writes it to the default profile id `<provider>:manual` unless you
|
||||
pass `--profile-id`. In automation, pipe the key on stdin, for example
|
||||
`printf "%s\n" "$OPENAI_API_KEY" | openclaw models auth paste-api-key --provider openai-codex`.
|
||||
`printf "%s\n" "$OPENAI_API_KEY" | openclaw models auth paste-api-key --provider openai`.
|
||||
- `setup-token` and `paste-token` remain generic token commands for providers
|
||||
that expose token auth methods.
|
||||
- `setup-token` requires an interactive TTY and runs the provider's token-auth
|
||||
@@ -226,7 +226,7 @@ Notes:
|
||||
provider credentials do not appear in shell history or process lists.
|
||||
- `paste-token --expires-in <duration>` stores an absolute token expiry from a
|
||||
relative duration such as `365d` or `12h`.
|
||||
- For `openai-codex`, OpenAI API keys and ChatGPT/OAuth token material are
|
||||
- For `openai`, OpenAI API keys and ChatGPT/OAuth token material are
|
||||
different auth shapes. Use `paste-api-key` for `sk-...` OpenAI API keys and
|
||||
`paste-token` only for token auth material.
|
||||
- Anthropic note: Anthropic staff told us OpenClaw-style Claude CLI usage is allowed again, so OpenClaw treats Claude CLI reuse and `claude -p` usage as sanctioned for this integration unless Anthropic publishes a new policy.
|
||||
|
||||
@@ -326,6 +326,8 @@ Use `--link` to avoid copying a local directory (adds to `plugins.load.paths`):
|
||||
openclaw plugins install -l ./my-plugin
|
||||
```
|
||||
|
||||
Standalone plugin files must be listed in `plugins.load.paths` rather than placed directly in `~/.openclaw/extensions` or `<workspace>/.openclaw/extensions`. Those auto-discovered roots load plugin package or bundle directories, while top-level script files are treated as local helpers and skipped.
|
||||
|
||||
<Note>
|
||||
`--force` is not supported with `--link` because linked installs reuse the source path instead of copying over a managed install target.
|
||||
|
||||
|
||||
@@ -47,6 +47,20 @@ Scope selection:
|
||||
- `--store <path>`: explicit store path (cannot be combined with `--agent` or `--all-agents`)
|
||||
- `--limit <n|all>`: max rows to output (default `100`; `all` restores full output)
|
||||
|
||||
Tail human-readable trajectory progress for stored sessions:
|
||||
|
||||
```bash
|
||||
openclaw sessions tail
|
||||
openclaw sessions tail --follow
|
||||
openclaw sessions tail --session-key "agent:main:telegram:direct:123" --tail 25
|
||||
openclaw sessions --agent work tail --follow
|
||||
openclaw sessions --all-agents tail --follow
|
||||
```
|
||||
|
||||
`openclaw sessions tail` renders recent trajectory JSONL events as compact progress lines. Without `--session-key`, it tails running sessions first, then the latest stored session. `--tail <count>` controls how many existing events print before follow mode; the default is `80`, and `0` starts at the current end. `--follow` keeps watching the selected trajectory files, including relocated files referenced by `<session>.trajectory-path.json`.
|
||||
|
||||
The progress view is intentionally conservative: prompt text, tool arguments, and tool result bodies are not printed. Tool calls show the tool name with `{...redacted...}`; tool results show status such as `ok`, `error`, or `done`; model completion lines show provider/model and terminal status.
|
||||
|
||||
Export a trajectory bundle for a stored session:
|
||||
|
||||
```bash
|
||||
@@ -104,7 +118,7 @@ openclaw sessions cleanup --json
|
||||
|
||||
`openclaw sessions cleanup` uses `session.maintenance` settings from config:
|
||||
|
||||
- Scope note: `openclaw sessions cleanup` maintains session stores, transcripts, and trajectory sidecars. It does not prune cron run logs (`cron/runs/<jobId>.jsonl`), which are managed by `cron.runLog.maxBytes` and `cron.runLog.keepLines` in [Cron configuration](/automation/cron-jobs#configuration) and explained in [Cron maintenance](/automation/cron-jobs#maintenance).
|
||||
- Scope note: `openclaw sessions cleanup` maintains session stores, transcripts, and trajectory sidecars. It does not prune cron run history, which is managed by `cron.runLog.keepLines` in [Cron configuration](/automation/cron-jobs#configuration) and explained in [Cron maintenance](/automation/cron-jobs#maintenance).
|
||||
- Cleanup also prunes unreferenced primary transcripts, compaction checkpoints, and trajectory sidecars older than `session.maintenance.pruneAfter`; files still referenced by `sessions.json` are preserved.
|
||||
|
||||
- `--dry-run`: preview how many entries would be pruned/capped without writing.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
summary: "CLI reference for `openclaw skills` (search/install/update/verify/list/info/check)"
|
||||
summary: "CLI reference for `openclaw skills` (search/install/update/verify/list/info/check/workshop)"
|
||||
read_when:
|
||||
- You want to see which skills are available and ready to run
|
||||
- You want to search ClawHub or install skills from ClawHub, Git, or local directories
|
||||
@@ -53,6 +53,14 @@ openclaw skills info <name> --agent <id>
|
||||
openclaw skills check
|
||||
openclaw skills check --agent <id>
|
||||
openclaw skills check --json
|
||||
openclaw skills workshop propose-create --name "qa-check" --description "QA checklist" --proposal ./PROPOSAL.md
|
||||
openclaw skills workshop propose-update qa-check --proposal ./PROPOSAL.md
|
||||
openclaw skills workshop list
|
||||
openclaw skills workshop inspect <proposal-id>
|
||||
openclaw skills workshop revise <proposal-id> --proposal ./PROPOSAL.md
|
||||
openclaw skills workshop apply <proposal-id>
|
||||
openclaw skills workshop reject <proposal-id> --reason "Not reusable"
|
||||
openclaw skills workshop quarantine <proposal-id> --reason "Needs security review"
|
||||
```
|
||||
|
||||
`search`, `update`, and `verify` use ClawHub directly. `install <slug>` installs
|
||||
@@ -116,6 +124,76 @@ Notes:
|
||||
`--json`, that means the machine-readable payload stays on stdout for pipes
|
||||
and scripts.
|
||||
|
||||
## Skill Workshop proposals
|
||||
|
||||
`openclaw skills workshop` manages pending skill proposals in the selected
|
||||
workspace. Proposals are durable OpenClaw state under
|
||||
`<OPENCLAW_STATE_DIR>/skill-workshop/proposals/`; they are not active skills
|
||||
until applied. The default state directory is `~/.openclaw`. Proposal bodies
|
||||
honor `skills.workshop.maxSkillBytes`, and proposal descriptions are capped at
|
||||
160 bytes because they can appear in discovery and listing output.
|
||||
|
||||
Create a proposal from a draft markdown file:
|
||||
|
||||
```bash
|
||||
openclaw skills workshop propose-create \
|
||||
--name "qa-check" \
|
||||
--description "Repeatable QA checklist" \
|
||||
--proposal ./PROPOSAL.md
|
||||
```
|
||||
|
||||
Or create a proposal from a full draft skill directory:
|
||||
|
||||
```bash
|
||||
openclaw skills workshop propose-create \
|
||||
--name "qa-check" \
|
||||
--description "Repeatable QA checklist" \
|
||||
--proposal-dir ./qa-check-proposal
|
||||
```
|
||||
|
||||
Update an existing workspace skill through the same pending path:
|
||||
|
||||
```bash
|
||||
openclaw skills workshop propose-update qa-check --proposal ./PROPOSAL.md
|
||||
```
|
||||
|
||||
Revise a pending proposal before approval:
|
||||
|
||||
```bash
|
||||
openclaw skills workshop revise <proposal-id> --proposal ./PROPOSAL.md
|
||||
```
|
||||
|
||||
The supplied draft is stored as `PROPOSAL.md` with proposal-only frontmatter:
|
||||
|
||||
```markdown
|
||||
---
|
||||
name: qa-check
|
||||
description: Repeatable QA checklist
|
||||
status: proposal
|
||||
version: v1
|
||||
date: "2026-05-30T00:00:00.000Z"
|
||||
---
|
||||
```
|
||||
|
||||
Applying a proposal writes the active `SKILL.md` into the workspace `skills/`
|
||||
root, strips `status`, proposal `version`, and proposal `date` from the
|
||||
frontmatter, scans the draft, writes rollback metadata, and refuses stale
|
||||
updates when the target skill changed after the proposal was created.
|
||||
|
||||
When `--proposal-dir` is used, the directory must contain `PROPOSAL.md`.
|
||||
Support files can be included under `assets/`, `examples/`, `references/`,
|
||||
`scripts/`, or `templates/`. OpenClaw stores support files with the proposal,
|
||||
scans them, verifies their hashes before apply, and writes them beside the
|
||||
active `SKILL.md` only after the proposal is applied.
|
||||
|
||||
Agents can create, revise, list, and inspect pending proposals through the
|
||||
`skill_workshop` tool when the user asks for reusable work to be captured.
|
||||
Autonomous proposal capture from durable conversation signals is off by
|
||||
default and is enabled with `skills.workshop.autonomous.enabled`. If the user
|
||||
explicitly asks to approve/use/apply, reject, or quarantine a specific
|
||||
proposal, `skill_workshop` can also perform that proposal lifecycle action
|
||||
through the same Skill Workshop safeguards.
|
||||
|
||||
## Related
|
||||
|
||||
- [CLI reference](/cli)
|
||||
|
||||
@@ -16,7 +16,7 @@ configuration. They are different layers:
|
||||
|
||||
| Layer | Examples | What it means |
|
||||
| ------------- | -------------------------------------------- | ------------------------------------------------------------------- |
|
||||
| Provider | `openai`, `anthropic`, `openai-codex` | How OpenClaw authenticates, discovers models, and names model refs. |
|
||||
| Provider | `openai`, `anthropic`, `github-copilot` | How OpenClaw authenticates, discovers models, and names model refs. |
|
||||
| Model | `gpt-5.5`, `claude-opus-4-6` | The model selected for the agent turn. |
|
||||
| Agent runtime | `openclaw`, `codex`, `copilot`, `claude-cli` | The low level loop or backend that executes the prepared turn. |
|
||||
| Channel | Telegram, Discord, Slack, WhatsApp | Where messages enter and leave OpenClaw. |
|
||||
@@ -51,7 +51,7 @@ Most confusion comes from several different surfaces sharing the Codex name:
|
||||
| Surface | OpenClaw name/config | What it does |
|
||||
| ------------------------------------------------ | ------------------------------------ | -------------------------------------------------------------------------------------------------------------- |
|
||||
| Native Codex app-server runtime | `openai/*` model refs | Runs OpenAI embedded agent turns through Codex app-server. This is the usual ChatGPT/Codex subscription setup. |
|
||||
| Codex OAuth auth profiles | `openai-codex` auth provider | Stores ChatGPT/Codex subscription auth that the Codex app-server harness consumes. |
|
||||
| Codex OAuth auth profiles | `openai` OAuth profiles | Stores ChatGPT/Codex subscription auth that the Codex app-server harness consumes. |
|
||||
| Codex ACP adapter | `runtime: "acp"`, `agentId: "codex"` | Runs Codex through the external ACP/acpx control plane. Use only when ACP/acpx is explicitly asked. |
|
||||
| Native Codex chat-control command set | `/codex ...` | Binds, resumes, steers, stops, and inspects Codex app-server threads from chat. |
|
||||
| OpenAI Platform API route for non-agent surfaces | `openai/*` plus API-key auth | Used for direct OpenAI APIs such as images, embeddings, speech, and realtime. |
|
||||
@@ -95,7 +95,7 @@ This is the agent-facing decision tree:
|
||||
subscription-backed Codex agent experience, use `openai/<model>`.
|
||||
3. If the user explicitly chooses **OpenClaw for an OpenAI model**, keep the model ref
|
||||
as `openai/<model>` and set provider/model runtime policy to
|
||||
`agentRuntime.id: "openclaw"`. A selected `openai-codex` auth profile is routed
|
||||
`agentRuntime.id: "openclaw"`. A selected `openai` OAuth profile is routed
|
||||
internally through OpenClaw's Codex-auth transport.
|
||||
4. If legacy config still contains **`openai-codex/*` model refs**, repair it to
|
||||
`openai/<model>` with `openclaw doctor --fix`; doctor keeps the Codex auth
|
||||
@@ -112,7 +112,7 @@ This is the agent-facing decision tree:
|
||||
| --------------------------------------- | -------------------------------------------- |
|
||||
| Codex app-server chat/thread control | `/codex ...` from the bundled `codex` plugin |
|
||||
| Codex app-server embedded agent runtime | `openai/*` agent model refs |
|
||||
| OpenAI Codex OAuth | `openai-codex` auth profiles |
|
||||
| OpenAI Codex OAuth | `openai` OAuth profiles |
|
||||
| Claude Code or other external harness | ACP/acpx |
|
||||
|
||||
For the OpenAI-family prefix split, see [OpenAI](/providers/openai) and
|
||||
@@ -196,7 +196,7 @@ backend.
|
||||
`auto` mode is intentionally conservative for most providers. OpenAI agent
|
||||
models are the exception: unset runtime and `auto` both resolve to the Codex
|
||||
harness. Explicit OpenClaw runtime config remains an opt-in compatibility route for
|
||||
`openai/*` agent turns; when paired with a selected `openai-codex` auth profile,
|
||||
`openai/*` agent turns; when paired with a selected `openai` OAuth profile,
|
||||
OpenClaw routes that path internally through the Codex-auth transport while
|
||||
keeping the public model ref as `openai/*`. Stale OpenAI runtime session pins are
|
||||
ignored by runtime selection and can be cleaned with `openclaw doctor --fix`.
|
||||
|
||||
@@ -127,7 +127,7 @@ See [Sandboxing](/gateway/sandboxing) and [Multi-Agent Sandbox & Tools](/tools/m
|
||||
|
||||
Configure logging before the delegate handles any real data:
|
||||
|
||||
- Cron run history: `~/.openclaw/cron/runs/<jobId>.jsonl`
|
||||
- Cron run history: OpenClaw shared SQLite state database
|
||||
- Session transcripts: `~/.openclaw/agents/delegate/sessions`
|
||||
- Identity provider audit logs (Exchange, Google Workspace)
|
||||
|
||||
|
||||
@@ -156,15 +156,14 @@ Use `auth.order.openai` for the user-facing order:
|
||||
{
|
||||
auth: {
|
||||
order: {
|
||||
openai: ["openai-codex:user@example.com", "openai:api-key-backup"],
|
||||
openai: ["openai:user@example.com", "openai:api-key-backup"],
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Existing Codex subscription profiles may still use the legacy
|
||||
`openai-codex:*` profile id. The ordered API-key backup can be a normal
|
||||
`openai:*` API-key profile. When the subscription hits a Codex usage limit,
|
||||
Use `openai:*` for both ChatGPT/Codex OAuth profiles and OpenAI API-key
|
||||
profiles. When the subscription hits a Codex usage limit,
|
||||
OpenClaw records the exact reset time when Codex provides one, tries the next
|
||||
ordered auth profile, and keeps the run inside the Codex harness. Once the reset
|
||||
time passes, the subscription profile is eligible again and the next automatic
|
||||
|
||||
@@ -130,24 +130,24 @@ Anthropic staff told us OpenClaw-style Claude CLI usage is allowed again, so Ope
|
||||
}
|
||||
```
|
||||
|
||||
### OpenAI Codex OAuth
|
||||
### OpenAI ChatGPT/Codex OAuth
|
||||
|
||||
- Provider: `openai-codex`
|
||||
- Provider: `openai`
|
||||
- Auth: OAuth (ChatGPT)
|
||||
- Legacy OpenAI Codex model ref: `openai-codex/gpt-5.5`
|
||||
- Legacy OpenAI Codex model ref: `openai/gpt-5.5`
|
||||
- Native Codex app-server harness ref: `openai/gpt-5.5`
|
||||
- Native Codex app-server harness docs: [Codex harness](/plugins/codex-harness)
|
||||
- Legacy model refs: `codex/gpt-*`
|
||||
- Plugin boundary: `openai-codex/*` loads the OpenAI plugin; the native Codex app-server plugin is selected only by the Codex harness runtime or legacy `codex/*` refs.
|
||||
- CLI: `openclaw onboard --auth-choice openai-codex` or `openclaw models auth login --provider openai-codex`
|
||||
- Plugin boundary: `openai/*` loads the OpenAI plugin; the native Codex app-server plugin is selected by the Codex harness runtime.
|
||||
- CLI: `openclaw onboard --auth-choice openai` or `openclaw models auth login --provider openai`
|
||||
- Default transport is `auto` (WebSocket-first, SSE fallback)
|
||||
- Override per OpenAI Codex model via `agents.defaults.models["openai-codex/<model>"].params.transport` (`"sse"`, `"websocket"`, or `"auto"`)
|
||||
- Override per OpenAI Codex model via `agents.defaults.models["openai/<model>"].params.transport` (`"sse"`, `"websocket"`, or `"auto"`)
|
||||
- `params.serviceTier` is also forwarded on native Codex Responses requests (`chatgpt.com/backend-api`)
|
||||
- Hidden OpenClaw attribution headers (`originator`, `version`, `User-Agent`) are only attached on native Codex traffic to `chatgpt.com/backend-api`, not generic OpenAI-compatible proxies
|
||||
- Shares the same `/fast` toggle and `params.fastMode` config as direct `openai/*`; OpenClaw maps that to `service_tier=priority`
|
||||
- `openai-codex/gpt-5.5` uses the Codex catalog native `contextWindow = 400000` and default runtime `contextTokens = 272000`; override the runtime cap with `models.providers.openai-codex.models[].contextTokens`
|
||||
- `openai/gpt-5.5` uses the Codex catalog native `contextWindow = 400000` and default runtime `contextTokens = 272000`; override the runtime cap with `models.providers.openai.models[].contextTokens`
|
||||
- Policy note: OpenAI Codex OAuth is explicitly supported for external tools/workflows like OpenClaw.
|
||||
- For the common subscription plus native Codex runtime route, sign in with `openai-codex` auth but configure `openai/gpt-5.5`; OpenAI agent turns select Codex by default.
|
||||
- For the common subscription plus native Codex runtime route, sign in with `openai` auth and configure `openai/gpt-5.5`; OpenAI agent turns select Codex by default.
|
||||
- Use provider/model `agentRuntime.id: "openclaw"` only when you want the built-in OpenClaw route; otherwise keep `openai/gpt-5.5` on the default Codex harness.
|
||||
- `openai-codex/gpt-*` refs remain a legacy OpenAI Codex route. Prefer `openai/gpt-5.5` on the native Codex runtime for new agent config, and run `openclaw doctor --fix` when you want to migrate old `openai-codex/*` refs to canonical `openai/*` refs.
|
||||
|
||||
@@ -166,7 +166,7 @@ Anthropic staff told us OpenClaw-style Claude CLI usage is allowed again, so Ope
|
||||
{
|
||||
models: {
|
||||
providers: {
|
||||
"openai-codex": {
|
||||
openai: {
|
||||
models: [{ id: "gpt-5.5", contextTokens: 160000 }],
|
||||
},
|
||||
},
|
||||
@@ -290,32 +290,36 @@ See [/providers/kilocode](/providers/kilocode) for setup details.
|
||||
|
||||
### Other bundled provider plugins
|
||||
|
||||
| Provider | Id | Auth env | Example model |
|
||||
| ----------------------- | -------------------------------- | ------------------------------------------------------------ | -------------------------------------------------- |
|
||||
| BytePlus | `byteplus` / `byteplus-plan` | `BYTEPLUS_API_KEY` | `byteplus-plan/ark-code-latest` |
|
||||
| Cerebras | `cerebras` | `CEREBRAS_API_KEY` | `cerebras/zai-glm-4.7` |
|
||||
| Cloudflare AI Gateway | `cloudflare-ai-gateway` | `CLOUDFLARE_AI_GATEWAY_API_KEY` | - |
|
||||
| DeepInfra | `deepinfra` | `DEEPINFRA_API_KEY` | `deepinfra/deepseek-ai/DeepSeek-V4-Flash` |
|
||||
| DeepSeek | `deepseek` | `DEEPSEEK_API_KEY` | `deepseek/deepseek-v4-flash` |
|
||||
| GitHub Copilot | `github-copilot` | `COPILOT_GITHUB_TOKEN` / `GH_TOKEN` / `GITHUB_TOKEN` | - |
|
||||
| Groq | `groq` | `GROQ_API_KEY` | - |
|
||||
| Hugging Face Inference | `huggingface` | `HUGGINGFACE_HUB_TOKEN` or `HF_TOKEN` | `huggingface/deepseek-ai/DeepSeek-R1` |
|
||||
| Kilo Gateway | `kilocode` | `KILOCODE_API_KEY` | `kilocode/kilo/auto` |
|
||||
| Kimi Coding | `kimi` | `KIMI_API_KEY` or `KIMICODE_API_KEY` | `kimi/kimi-for-coding` |
|
||||
| MiniMax | `minimax` / `minimax-portal` | `MINIMAX_API_KEY` / `MINIMAX_OAUTH_TOKEN` | `minimax/MiniMax-M2.7` |
|
||||
| Mistral | `mistral` | `MISTRAL_API_KEY` | `mistral/mistral-large-latest` |
|
||||
| Moonshot | `moonshot` | `MOONSHOT_API_KEY` | `moonshot/kimi-k2.6` |
|
||||
| NVIDIA | `nvidia` | `NVIDIA_API_KEY` | `nvidia/nvidia/nemotron-3-super-120b-a12b` |
|
||||
| OpenRouter | `openrouter` | `OPENROUTER_API_KEY` | `openrouter/auto` |
|
||||
| Qianfan | `qianfan` | `QIANFAN_API_KEY` | `qianfan/deepseek-v3.2` |
|
||||
| Qwen Cloud | `qwen` | `QWEN_API_KEY` / `MODELSTUDIO_API_KEY` / `DASHSCOPE_API_KEY` | `qwen/qwen3.5-plus` |
|
||||
| StepFun | `stepfun` / `stepfun-plan` | `STEPFUN_API_KEY` | `stepfun/step-3.5-flash` |
|
||||
| Together | `together` | `TOGETHER_API_KEY` | `together/meta-llama/Llama-3.3-70B-Instruct-Turbo` |
|
||||
| Venice | `venice` | `VENICE_API_KEY` | - |
|
||||
| Vercel AI Gateway | `vercel-ai-gateway` | `AI_GATEWAY_API_KEY` | `vercel-ai-gateway/anthropic/claude-opus-4.6` |
|
||||
| Volcano Engine (Doubao) | `volcengine` / `volcengine-plan` | `VOLCANO_ENGINE_API_KEY` | `volcengine-plan/ark-code-latest` |
|
||||
| xAI | `xai` | SuperGrok/X Premium OAuth or `XAI_API_KEY` | `xai/grok-4.3` |
|
||||
| Xiaomi | `xiaomi` | `XIAOMI_API_KEY` | `xiaomi/mimo-v2-flash` |
|
||||
| Provider | Id | Auth env | Example model |
|
||||
| --------------------------------------- | -------------------------------- | ------------------------------------------------------------ | ---------------------------------------------------------- |
|
||||
| BytePlus | `byteplus` / `byteplus-plan` | `BYTEPLUS_API_KEY` | `byteplus-plan/ark-code-latest` |
|
||||
| Cerebras | `cerebras` | `CEREBRAS_API_KEY` | `cerebras/zai-glm-4.7` |
|
||||
| Cloudflare AI Gateway | `cloudflare-ai-gateway` | `CLOUDFLARE_AI_GATEWAY_API_KEY` | - |
|
||||
| DeepInfra | `deepinfra` | `DEEPINFRA_API_KEY` | `deepinfra/deepseek-ai/DeepSeek-V4-Flash` |
|
||||
| DeepSeek | `deepseek` | `DEEPSEEK_API_KEY` | `deepseek/deepseek-v4-flash` |
|
||||
| GitHub Copilot | `github-copilot` | `COPILOT_GITHUB_TOKEN` / `GH_TOKEN` / `GITHUB_TOKEN` | - |
|
||||
| GMI Cloud | `gmi` | `GMI_API_KEY` | `gmi/google/gemini-3.1-flash-lite` |
|
||||
| Groq | `groq` | `GROQ_API_KEY` | - |
|
||||
| Hugging Face Inference | `huggingface` | `HUGGINGFACE_HUB_TOKEN` or `HF_TOKEN` | `huggingface/deepseek-ai/DeepSeek-R1` |
|
||||
| Kilo Gateway | `kilocode` | `KILOCODE_API_KEY` | `kilocode/kilo/auto` |
|
||||
| Kimi Coding | `kimi` | `KIMI_API_KEY` or `KIMICODE_API_KEY` | `kimi/kimi-for-coding` |
|
||||
| MiniMax | `minimax` / `minimax-portal` | `MINIMAX_API_KEY` / `MINIMAX_OAUTH_TOKEN` | `minimax/MiniMax-M2.7` |
|
||||
| Mistral | `mistral` | `MISTRAL_API_KEY` | `mistral/mistral-large-latest` |
|
||||
| Moonshot | `moonshot` | `MOONSHOT_API_KEY` | `moonshot/kimi-k2.6` |
|
||||
| NVIDIA | `nvidia` | `NVIDIA_API_KEY` | `nvidia/nvidia/nemotron-3-super-120b-a12b` |
|
||||
| NovitaAI | `novita` | `NOVITA_API_KEY` | `novita/deepseek/deepseek-v3-0324` |
|
||||
| [Ollama Cloud](/providers/ollama-cloud) | `ollama-cloud` | `OLLAMA_API_KEY` | `ollama-cloud/kimi-k2.6` |
|
||||
| OpenRouter | `openrouter` | `OPENROUTER_API_KEY` | `openrouter/auto` |
|
||||
| Qianfan | `qianfan` | `QIANFAN_API_KEY` | `qianfan/deepseek-v3.2` |
|
||||
| Qwen Cloud | `qwen` | `QWEN_API_KEY` / `MODELSTUDIO_API_KEY` / `DASHSCOPE_API_KEY` | `qwen/qwen3.5-plus` |
|
||||
| [Qwen OAuth](/providers/qwen-oauth) | `qwen-oauth` | `QWEN_API_KEY` | `qwen-oauth/qwen3.5-plus` |
|
||||
| StepFun | `stepfun` / `stepfun-plan` | `STEPFUN_API_KEY` | `stepfun/step-3.5-flash` |
|
||||
| Together | `together` | `TOGETHER_API_KEY` | `together/meta-llama/Llama-3.3-70B-Instruct-Turbo` |
|
||||
| Venice | `venice` | `VENICE_API_KEY` | - |
|
||||
| Vercel AI Gateway | `vercel-ai-gateway` | `AI_GATEWAY_API_KEY` | `vercel-ai-gateway/anthropic/claude-opus-4.6` |
|
||||
| Volcano Engine (Doubao) | `volcengine` / `volcengine-plan` | `VOLCANO_ENGINE_API_KEY` | `volcengine-plan/ark-code-latest` |
|
||||
| xAI | `xai` | SuperGrok/X Premium OAuth or `XAI_API_KEY` | `xai/grok-4.3` |
|
||||
| Xiaomi | `xiaomi` / `xiaomi-token-plan` | `XIAOMI_API_KEY` / `XIAOMI_TOKEN_PLAN_API_KEY` | `xiaomi/mimo-v2-flash` / `xiaomi-token-plan/mimo-v2.5-pro` |
|
||||
|
||||
#### Quirks worth knowing
|
||||
|
||||
|
||||
@@ -23,7 +23,7 @@ sidebarTitle: "Models CLI"
|
||||
</Card>
|
||||
</CardGroup>
|
||||
|
||||
Model refs choose a provider and model. They do not usually choose the low-level agent runtime. OpenAI agent refs are the main exception: `openai/gpt-5.5` runs through the Codex app-server runtime by default on the official OpenAI provider. Subscription Copilot refs (`github-copilot/*`) can additionally be opted into the external GitHub Copilot agent runtime plugin — that path stays explicit (no `auto` fallback). Explicit runtime overrides belong on provider/model policy, not on the whole agent or session. In Codex runtime mode, the `openai/gpt-*` ref does not imply API-key billing; auth can come from a Codex account or `openai-codex` auth profile. See [Agent runtimes](/concepts/agent-runtimes) and [GitHub Copilot agent runtime](/plugins/copilot).
|
||||
Model refs choose a provider and model. They do not usually choose the low-level agent runtime. OpenAI agent refs are the main exception: `openai/gpt-5.5` runs through the Codex app-server runtime by default on the official OpenAI provider. Subscription Copilot refs (`github-copilot/*`) can additionally be opted into the external GitHub Copilot agent runtime plugin — that path stays explicit (no `auto` fallback). Explicit runtime overrides belong on provider/model policy, not on the whole agent or session. In Codex runtime mode, the `openai/gpt-*` ref does not imply API-key billing; auth can come from a Codex account or `openai` OAuth profile. See [Agent runtimes](/concepts/agent-runtimes) and [GitHub Copilot agent runtime](/plugins/copilot).
|
||||
|
||||
## How model selection works
|
||||
|
||||
@@ -150,7 +150,7 @@ If you want to limit providers without manually listing every model, add
|
||||
agents: {
|
||||
defaults: {
|
||||
models: {
|
||||
"openai-codex/*": {},
|
||||
"openai/*": {},
|
||||
"vllm/*": {},
|
||||
},
|
||||
},
|
||||
|
||||
@@ -45,7 +45,7 @@ To reduce that, OpenClaw treats `auth-profiles.json` as a **token sink**:
|
||||
- the runtime reads credentials from **one place**
|
||||
- we can keep multiple profiles and route them deterministically
|
||||
- external CLI reuse is provider-specific: Codex CLI can bootstrap an empty
|
||||
`openai-codex:default` profile, but once OpenClaw has a local OAuth profile,
|
||||
`openai:default` profile, but once OpenClaw has a local OAuth profile,
|
||||
the local refresh token is canonical. If that local refresh token is rejected,
|
||||
OpenClaw can use a usable same-account Codex CLI token as a runtime-only
|
||||
fallback; other integrations can remain externally managed and re-read their
|
||||
@@ -131,7 +131,7 @@ Flow shape (PKCE):
|
||||
5. exchange at `https://auth.openai.com/oauth/token`
|
||||
6. extract `accountId` from the access token and store `{ access, refresh, expires, accountId }`
|
||||
|
||||
Wizard path is `openclaw onboard` → auth choice `openai-codex`.
|
||||
Wizard path is `openclaw onboard` → auth choice `openai`.
|
||||
|
||||
## Refresh + expiry
|
||||
|
||||
@@ -147,7 +147,7 @@ At runtime:
|
||||
- exception: some external CLI credentials stay externally managed; OpenClaw
|
||||
re-reads those CLI auth stores instead of spending copied refresh tokens.
|
||||
Codex CLI bootstrap is intentionally narrower: it seeds an empty
|
||||
`openai-codex:default` profile, then OpenClaw-owned refreshes keep the local
|
||||
`openai:default` profile, then OpenClaw-owned refreshes keep the local
|
||||
profile canonical. If the local Codex refresh fails and Codex CLI has a
|
||||
usable token for the same account, OpenClaw may use that token for the current
|
||||
runtime request without writing it back to `auth-profiles.json`.
|
||||
|
||||
@@ -181,12 +181,14 @@ prompt surface that matches their lifetime:
|
||||
On the native Codex harness, OpenClaw avoids repeating stable workspace files
|
||||
in every user turn. Codex loads `AGENTS.md` through its own project-doc
|
||||
discovery. `SOUL.md`, `IDENTITY.md`, `TOOLS.md`, and `USER.md` are forwarded as
|
||||
Codex developer instructions. `HEARTBEAT.md` content is not injected; heartbeat
|
||||
turns get a collaboration-mode note pointing to the file when it exists and is
|
||||
non-empty. `MEMORY.md` content from the configured agent workspace is not pasted
|
||||
into every native Codex turn; when memory tools are available for that workspace,
|
||||
Codex turns get a small workspace-memory note and should use `memory_search` or
|
||||
`memory_get` when durable memory is relevant. If tools are disabled, memory
|
||||
Codex developer instructions. The compact OpenClaw skills list is also forwarded
|
||||
as turn-scoped collaboration developer instructions. `HEARTBEAT.md` content is
|
||||
not injected; heartbeat turns get a collaboration-mode note pointing to the file
|
||||
when it exists and is non-empty. `MEMORY.md` content from the configured agent
|
||||
workspace is not pasted into every native Codex turn; when memory tools are
|
||||
available for that workspace, Codex turns get a small workspace-memory note in
|
||||
turn-scoped collaboration developer instructions and should use `memory_search`
|
||||
or `memory_get` when durable memory is relevant. If tools are disabled, memory
|
||||
search is unavailable, or the active workspace differs from the agent memory
|
||||
workspace, `MEMORY.md` falls back to the normal bounded turn-context path. Active
|
||||
`BOOTSTRAP.md` content keeps the normal turn-context role for now.
|
||||
@@ -258,6 +260,11 @@ prompt instructs the model to use `read` to load the SKILL.md at the listed
|
||||
location (workspace, managed, or bundled). If no skills are eligible, the
|
||||
Skills section is omitted.
|
||||
|
||||
Native Codex turns receive this list as turn-scoped collaboration developer
|
||||
instructions instead of per-turn user input, except lightweight cron turns that
|
||||
preserve the exact scheduled prompt. Other harnesses keep the normal prompt
|
||||
section.
|
||||
|
||||
The location can point at a nested skill, such as
|
||||
`skills/personal/foo/SKILL.md`. Nesting is only organizational; the prompt still
|
||||
uses the flat skill name from `SKILL.md` frontmatter.
|
||||
|
||||
@@ -1235,7 +1235,6 @@
|
||||
"plugins/memory-wiki",
|
||||
"plugins/memory-lancedb",
|
||||
"plugins/oc-path",
|
||||
"plugins/skill-workshop",
|
||||
"plugins/zalouser"
|
||||
]
|
||||
},
|
||||
@@ -1405,6 +1404,7 @@
|
||||
"providers/fal",
|
||||
"providers/fireworks",
|
||||
"providers/github-copilot",
|
||||
"providers/gmi",
|
||||
"providers/google",
|
||||
"providers/gradium",
|
||||
"providers/groq",
|
||||
@@ -1417,8 +1417,10 @@
|
||||
"providers/minimax",
|
||||
"providers/mistral",
|
||||
"providers/moonshot",
|
||||
"providers/novita",
|
||||
"providers/nvidia",
|
||||
"providers/ollama",
|
||||
"providers/ollama-cloud",
|
||||
"providers/openai",
|
||||
"providers/opencode",
|
||||
"providers/opencode-go",
|
||||
@@ -1427,6 +1429,7 @@
|
||||
"providers/pixverse",
|
||||
"providers/qianfan",
|
||||
"providers/qwen",
|
||||
"providers/qwen-oauth",
|
||||
"providers/runway",
|
||||
"providers/senseaudio",
|
||||
"providers/sglang",
|
||||
|
||||
@@ -199,8 +199,8 @@ Use `openclaw models auth login --provider <id> --profile-id <profileId>` for
|
||||
providers that support named auth profiles during login.
|
||||
|
||||
```bash
|
||||
openclaw models auth login --provider openai-codex --profile-id openai-codex:ritsuko
|
||||
openclaw models auth login --provider openai-codex --profile-id openai-codex:lain
|
||||
openclaw models auth login --provider openai --profile-id openai:ritsuko
|
||||
openclaw models auth login --provider openai --profile-id openai:lain
|
||||
```
|
||||
|
||||
This is the easiest way to keep multiple OAuth logins for the same provider
|
||||
|
||||
@@ -450,7 +450,7 @@ Time format in system prompt. Default: `auto` (OS preference).
|
||||
- `elevatedDefault`: default elevated-output level for agents. Values: `"off"`, `"on"`, `"ask"`, `"full"`. Default: `"on"`.
|
||||
- `model.primary`: format `provider/model` (e.g. `openai/gpt-5.5` for OpenAI API-key or Codex OAuth access). If you omit the provider, OpenClaw tries an alias first, then a unique configured-provider match for that exact model id, and only then falls back to the configured default provider (deprecated compatibility behavior, so prefer explicit `provider/model`). If that provider no longer exposes the configured default model, OpenClaw falls back to the first configured provider/model instead of surfacing a stale removed-provider default.
|
||||
- `models`: the configured model catalog and allowlist for `/model`. Each entry can include `alias` (shortcut) and `params` (provider-specific, for example `temperature`, `maxTokens`, `cacheRetention`, `context1m`, `responsesServerCompaction`, `responsesCompactThreshold`, OpenRouter `provider` routing, `chat_template_kwargs`, `extra_body`/`extraBody`).
|
||||
- Use `provider/*` entries such as `"openai-codex/*": {}` or `"vllm/*": {}` to show all discovered models for selected providers without manually listing every model id.
|
||||
- Use `provider/*` entries such as `"openai/*": {}` or `"vllm/*": {}` to show all discovered models for selected providers without manually listing every model id.
|
||||
- Add `agentRuntime` to a `provider/*` entry when every dynamically discovered model for that provider should use the same runtime. Exact `provider/model` runtime policy still wins over the wildcard.
|
||||
- Safe edits: use `openclaw config set agents.defaults.models '<json>' --strict-json --merge` to add entries. `config set` refuses replacements that would remove existing allowlist entries unless you pass `--replace`.
|
||||
- Provider-scoped configure/onboarding flows merge selected provider models into this map and preserve unrelated providers already configured.
|
||||
|
||||
@@ -82,12 +82,11 @@ Save to `~/.openclaw/openclaw.json` and you can DM the bot from that number.
|
||||
"anthropic:default": { provider: "anthropic", mode: "api_key" },
|
||||
"anthropic:work": { provider: "anthropic", mode: "api_key" },
|
||||
"openai:default": { provider: "openai", mode: "api_key" },
|
||||
"openai-codex:personal": { provider: "openai-codex", mode: "oauth" },
|
||||
"openai:personal": { provider: "openai", mode: "oauth" },
|
||||
},
|
||||
order: {
|
||||
anthropic: ["anthropic:default", "anthropic:work"],
|
||||
openai: ["openai:default"],
|
||||
"openai-codex": ["openai-codex:personal"],
|
||||
openai: ["openai:personal", "openai:default"],
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
@@ -109,6 +109,10 @@ target server during config edits.
|
||||
headers: {
|
||||
Authorization: "Bearer ${MCP_REMOTE_TOKEN}",
|
||||
},
|
||||
toolFilter: {
|
||||
include: ["search_*"],
|
||||
exclude: ["admin_*"],
|
||||
},
|
||||
// Optional Codex app-server projection controls.
|
||||
codex: {
|
||||
agents: ["main"],
|
||||
@@ -125,6 +129,12 @@ target server during config edits.
|
||||
Remote entries use `transport: "streamable-http"` or `transport: "sse"`;
|
||||
`type: "http"` is a CLI-native alias that `openclaw mcp set` and
|
||||
`openclaw doctor --fix` normalize into the canonical `transport` field.
|
||||
- `mcp.servers.<name>.toolFilter`: optional per-server tool selection. `include`
|
||||
limits the discovered MCP tools to matching names; `exclude` hides matching
|
||||
names. Entries are exact MCP tool names or simple `*` globs. Servers with
|
||||
resources or prompts also generate utility tool names (`resources_list`,
|
||||
`resources_read`, `prompts_list`, `prompts_get`), and those names use the
|
||||
same filter.
|
||||
- `mcp.servers.<name>.codex`: optional Codex app-server projection controls.
|
||||
This block is OpenClaw metadata for Codex app-server threads only; it does not
|
||||
affect ACP sessions, generic Codex harness config, or other runtime adapters.
|
||||
@@ -142,6 +152,11 @@ target server during config edits.
|
||||
- Changes under `mcp.*` hot-apply by disposing cached session MCP runtimes.
|
||||
The next tool discovery/use recreates them from the new config, so removed
|
||||
`mcp.servers` entries are reaped immediately instead of waiting for idle TTL.
|
||||
- Runtime discovery also honors MCP tool-list change notifications by dropping
|
||||
the cached catalog for that session. Servers that advertise resources or
|
||||
prompts get utility tools for listing/reading resources and listing/fetching
|
||||
prompts. Repeated tool-call failures pause the affected server briefly before
|
||||
another call is attempted.
|
||||
|
||||
See [MCP](/cli/mcp#openclaw-as-an-mcp-client-registry) and
|
||||
[CLI backends](/gateway/cli-backends#bundle-mcp-overlays) for runtime behavior.
|
||||
@@ -214,7 +229,8 @@ See [MCP](/cli/mcp#openclaw-as-an-mcp-client-registry) and
|
||||
}
|
||||
```
|
||||
|
||||
- Loaded from `~/.openclaw/extensions`, `<workspace>/.openclaw/extensions`, plus `plugins.load.paths`.
|
||||
- Loaded from package or bundle directories under `~/.openclaw/extensions` and `<workspace>/.openclaw/extensions`, plus files or directories listed in `plugins.load.paths`.
|
||||
- Put standalone plugin files in `plugins.load.paths`; auto-discovered extension roots ignore top-level `.js`, `.mjs`, and `.ts` files so helper scripts in those roots do not block startup.
|
||||
- Discovery accepts native OpenClaw plugins plus compatible Codex bundles and Claude bundles, including manifestless Claude default-layout bundles.
|
||||
- **Config changes require a gateway restart.**
|
||||
- `allow`: optional allowlist (only listed plugins load). `deny` wins.
|
||||
@@ -935,11 +951,11 @@ Notes:
|
||||
profiles: {
|
||||
"anthropic:default": { provider: "anthropic", mode: "api_key" },
|
||||
"anthropic:work": { provider: "anthropic", mode: "api_key" },
|
||||
"openai-codex:personal": { provider: "openai-codex", mode: "oauth" },
|
||||
"openai:personal": { provider: "openai", mode: "oauth" },
|
||||
},
|
||||
order: {
|
||||
anthropic: ["anthropic:default", "anthropic:work"],
|
||||
"openai-codex": ["openai-codex:personal"],
|
||||
openai: ["openai:personal"],
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -1249,8 +1265,8 @@ Current builds no longer include the TCP bridge. Nodes connect over the Gateway
|
||||
```
|
||||
|
||||
- `sessionRetention`: how long to keep completed isolated cron run sessions before pruning from `sessions.json`. Also controls cleanup of archived deleted cron transcripts. Default: `24h`; set `false` to disable.
|
||||
- `runLog.maxBytes`: max size per run log file (`cron/runs/<jobId>.jsonl`) before pruning. Default: `2_000_000` bytes.
|
||||
- `runLog.keepLines`: newest lines retained when run-log pruning is triggered. Default: `2000`.
|
||||
- `runLog.maxBytes`: accepted for compatibility with older file-backed cron run logs. Default: `2_000_000` bytes.
|
||||
- `runLog.keepLines`: newest SQLite run-history rows retained per job. Default: `2000`.
|
||||
- `webhookToken`: bearer token used for cron webhook POST delivery (`delivery.mode = "webhook"`), if omitted no auth header is sent.
|
||||
- `webhook`: deprecated legacy fallback webhook URL (http/https) used only for stored jobs that still have `notify: true`.
|
||||
|
||||
|
||||
@@ -431,7 +431,7 @@ candidate contains redacted secret placeholders such as `***`.
|
||||
```
|
||||
|
||||
- `sessionRetention`: prune completed isolated run sessions from `sessions.json` (default `24h`; set `false` to disable).
|
||||
- `runLog`: prune `cron/runs/<jobId>.jsonl` by size and retained lines.
|
||||
- `runLog`: prune retained cron run-history rows per job. `maxBytes` remains accepted for older file-backed run logs.
|
||||
- See [Cron jobs](/automation/cron-jobs) for feature overview and CLI examples.
|
||||
|
||||
</Accordion>
|
||||
|
||||
@@ -143,7 +143,7 @@ must be paired with `--lint`; regular doctor and repair runs reject them.
|
||||
- Talk config migration from legacy flat `talk.*` fields into `talk.provider` + `talk.providers.<provider>`.
|
||||
- Browser migration checks for legacy Chrome extension configs and Chrome MCP readiness.
|
||||
- OpenCode provider override warnings (`models.providers.opencode` / `models.providers.opencode-go`).
|
||||
- Codex OAuth shadowing warnings (`models.providers.openai-codex`).
|
||||
- Legacy OpenAI Codex provider/profile migration (`openai-codex` → `openai`) and shadowing warnings for stale `models.providers.openai-codex`.
|
||||
- OAuth TLS prerequisites check for OpenAI Codex OAuth profiles.
|
||||
- Plugin/tool allowlist warnings when `plugins.allow` is restrictive but tool policy still asks for wildcard or plugin-owned tools.
|
||||
- Legacy on-disk state migration (sessions/agent dir/WhatsApp auth).
|
||||
@@ -171,7 +171,7 @@ must be paired with `--lint`; regular doctor and repair runs reject them.
|
||||
- Channel status warnings (probed from the running gateway).
|
||||
- Channel-specific permission checks live under `openclaw channels capabilities`; for example, Discord voice channel permissions are audited with `openclaw channels capabilities --channel discord --target channel:<channel-id>`.
|
||||
- WhatsApp responsiveness checks for degraded Gateway event-loop health with local TUI clients still running; `--fix` stops only verified local TUI clients.
|
||||
- Codex route repair for legacy `openai-codex/*` model refs in primary models, fallbacks, heartbeat/subagent/compaction overrides, hooks, channel model overrides, and session route pins; `--fix` rewrites them to `openai/*`, removes stale session/whole-agent runtime pins, and leaves canonical OpenAI agent refs on the default Codex harness.
|
||||
- Codex route repair for legacy `openai-codex/*` model refs in primary models, fallbacks, image/video generation models, heartbeat/subagent/compaction overrides, hooks, channel model overrides, and session route pins; `--fix` rewrites them to `openai/*`, migrates `openai-codex:*` auth profiles/order to `openai:*`, removes stale session/whole-agent runtime pins, and leaves canonical OpenAI agent refs on the default Codex harness.
|
||||
- Supervisor config audit (launchd/systemd/schtasks) with optional repair.
|
||||
- Embedded proxy environment cleanup for gateway services that captured shell `HTTP_PROXY` / `HTTPS_PROXY` / `NO_PROXY` values during install or update.
|
||||
- Gateway runtime best-practice checks (Node vs Bun, version-manager paths).
|
||||
@@ -327,10 +327,10 @@ That stages grounded durable candidates into the short-term dreaming store while
|
||||
<Accordion title="2f. Codex route repair">
|
||||
Doctor checks for legacy `openai-codex/*` model refs. Native Codex harness routing uses canonical `openai/*` model refs; OpenAI agent turns go through the Codex app-server harness instead of the OpenClaw OpenAI provider path.
|
||||
|
||||
In `--fix` / `--repair` mode, doctor rewrites affected default-agent and per-agent refs, including primary models, fallbacks, heartbeat/subagent/compaction overrides, hooks, channel model overrides, and stale persisted session route state:
|
||||
In `--fix` / `--repair` mode, doctor rewrites affected default-agent and per-agent refs, including primary models, fallbacks, image/video generation models, heartbeat/subagent/compaction overrides, hooks, channel model overrides, and stale persisted session route state:
|
||||
|
||||
- `openai-codex/gpt-*` becomes `openai/gpt-*`.
|
||||
- Codex intent moves to provider/model-scoped `agentRuntime.id: "codex"` entries for repaired agent model refs so `openai-codex:...` auth profiles can still be selected after the model ref becomes `openai/*`.
|
||||
- Codex intent moves to provider/model-scoped `agentRuntime.id: "codex"` entries for repaired agent model refs.
|
||||
- Stale whole-agent runtime config and persisted session runtime pins are removed because runtime selection is provider/model-scoped.
|
||||
- Existing provider/model runtime policy is preserved unless the repaired legacy model ref needs Codex routing to keep the old auth path.
|
||||
- Existing model fallback lists are preserved with their legacy entries rewritten; copied per-model settings move from the legacy key to the canonical `openai/*` key.
|
||||
|
||||
@@ -19,7 +19,7 @@ At startup, the Gateway logs the resolved default agent model together with the
|
||||
mode defaults that affect new sessions, for example:
|
||||
|
||||
```text
|
||||
agent model: openai-codex/gpt-5.5 (thinking=medium, fast=on)
|
||||
agent model: openai/gpt-5.5 (thinking=medium, fast=on)
|
||||
```
|
||||
|
||||
`thinking` comes from the default agent, model params, or global agent default;
|
||||
|
||||
@@ -222,8 +222,9 @@ Set `stream: true` to receive Server-Sent Events (SSE):
|
||||
- `frequency_penalty`: number; best-effort frequency penalty forwarded to the upstream provider via the agent stream-param channel. Validated range: -2.0 to 2.0. Returns `400 invalid_request_error` for out-of-range values.
|
||||
- `presence_penalty`: number; best-effort presence penalty forwarded to the upstream provider via the agent stream-param channel. Validated range: -2.0 to 2.0. Returns `400 invalid_request_error` for out-of-range values.
|
||||
- `seed`: number (integer); best-effort seed forwarded to the upstream provider via the agent stream-param channel. Returns `400 invalid_request_error` for non-integer values.
|
||||
- `stop`: string or array of up to 4 strings; best-effort stop sequences forwarded to the upstream provider via the agent stream-param channel. Returns `400 invalid_request_error` for more than 4 sequences or non-string/empty entries.
|
||||
|
||||
When either token-cap field is set, the value is forwarded to the upstream provider via the agent stream-param channel. The actual wire field name sent to the upstream provider is chosen by the provider transport: `max_completion_tokens` for OpenAI-family endpoints, and `max_tokens` for providers that only accept the legacy name (such as Mistral and Chutes). Sampling fields (`temperature`, `top_p`, `frequency_penalty`, `presence_penalty`, `seed`) follow the same stream-param channel; the ChatGPT-based Codex Responses backend strips them server-side since it uses fixed sampling.
|
||||
When either token-cap field is set, the value is forwarded to the upstream provider via the agent stream-param channel. The actual wire field name sent to the upstream provider is chosen by the provider transport: `max_completion_tokens` for OpenAI-family endpoints, and `max_tokens` for providers that only accept the legacy name (such as Mistral and Chutes). Sampling fields (`temperature`, `top_p`, `frequency_penalty`, `presence_penalty`, `seed`) follow the same stream-param channel; the ChatGPT-based Codex Responses backend strips them server-side since it uses fixed sampling. `stop` also rides the stream-param channel and maps to the transport's stop field (`stop` for Chat Completions backends, `stop_sequences` for Anthropic); the OpenAI Responses API has no stop parameter, so `stop` is not applied on Responses-backed models.
|
||||
|
||||
### Unsupported variants
|
||||
|
||||
|
||||
@@ -348,7 +348,8 @@ enumeration of `src/gateway/server-methods/*.ts`.
|
||||
- `usage.status` returns provider usage windows/remaining quota summaries.
|
||||
- `usage.cost` returns aggregated cost usage summaries for a date range.
|
||||
Pass `agentId` for one agent, or `agentScope: "all"` to aggregate configured agents.
|
||||
- `doctor.memory.status` returns vector-memory / cached embedding readiness for the active default agent workspace. Pass `{ "probe": true }` or `{ "deep": true }` only when the caller explicitly wants a live embedding provider ping.
|
||||
- `doctor.memory.status` returns vector-memory / cached embedding readiness for the active default agent workspace. Pass `{ "probe": true }` or `{ "deep": true }` only when the caller explicitly wants a live embedding provider ping. Dreaming-aware clients may also pass `{ "agentId": "agent-id" }` to scope Dreaming store stats to a selected agent workspace; omitting `agentId` keeps the default-agent fallback and aggregates configured Dreaming workspaces.
|
||||
- `doctor.memory.dreamDiary`, `doctor.memory.backfillDreamDiary`, `doctor.memory.resetDreamDiary`, `doctor.memory.resetGroundedShortTerm`, `doctor.memory.repairDreamingArtifacts`, and `doctor.memory.dedupeDreamDiary` accept optional `{ "agentId": "agent-id" }` params for selected-agent Dreaming views/actions. When `agentId` is omitted, they operate on the configured default agent workspace.
|
||||
- `doctor.memory.remHarness` returns a bounded, read-only REM harness preview for remote control-plane clients. It can include workspace paths, memory snippets, rendered grounded markdown, and deep promotion candidates, so callers need `operator.read`.
|
||||
- `sessions.usage` returns per-session usage summaries. Pass `agentId` for one
|
||||
agent, or `agentScope: "all"` to list configured agents together.
|
||||
|
||||
@@ -599,22 +599,24 @@ and troubleshooting see the main [FAQ](/help/faq).
|
||||
native Codex app-server execution. `openai-codex/gpt-*` model refs are
|
||||
legacy config repaired by `openclaw doctor --fix`. Direct OpenAI API-key
|
||||
access remains available for non-agent OpenAI API surfaces and for agent
|
||||
models through an ordered `openai-codex` API-key profile.
|
||||
models through an ordered `openai` API-key profile.
|
||||
See [Model providers](/concepts/model-providers) and [Onboarding (CLI)](/start/wizard).
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Why does OpenClaw still mention openai-codex?">
|
||||
`openai-codex` is the provider and auth-profile id for ChatGPT/Codex OAuth.
|
||||
`openai` is the provider and auth-profile id for both OpenAI API keys and
|
||||
ChatGPT/Codex OAuth. You may still see `openai-codex` in legacy config and
|
||||
migration warnings.
|
||||
Older configs also used it as a model prefix:
|
||||
|
||||
- `openai/gpt-5.5` = ChatGPT/Codex subscription auth with native Codex runtime for agent turns
|
||||
- `openai-codex/gpt-5.5` = legacy model route repaired by `openclaw doctor --fix`
|
||||
- `openai/gpt-5.5` plus an ordered `openai-codex` API-key profile = API-key auth for an OpenAI agent model
|
||||
- `openai-codex:...` = auth profile id, not a model ref
|
||||
- `openai/gpt-5.5` plus an ordered `openai` API-key profile = API-key auth for an OpenAI agent model
|
||||
- `openai-codex:...` = legacy auth profile id migrated by `openclaw doctor --fix`
|
||||
|
||||
If you want the direct OpenAI Platform billing/limit path, set
|
||||
`OPENAI_API_KEY`. If you want ChatGPT/Codex subscription auth, sign in with
|
||||
`openclaw models auth login --provider openai-codex`. Keep the model ref as
|
||||
`openclaw models auth login --provider openai`. Keep the model ref as
|
||||
`openai/gpt-5.5`; `openai-codex/*` model refs are legacy config that
|
||||
`openclaw doctor --fix` rewrites.
|
||||
|
||||
|
||||
@@ -160,9 +160,9 @@ troubleshooting, see the main [FAQ](/help/faq).
|
||||
<Accordion title="Can I use GPT 5.5 for daily tasks and Codex 5.5 for coding?">
|
||||
Yes. Treat model choice and runtime choice separately:
|
||||
|
||||
- **Native Codex coding agent:** set `agents.defaults.model.primary` to `openai/gpt-5.5`. Sign in with `openclaw models auth login --provider openai-codex` when you want ChatGPT/Codex subscription auth.
|
||||
- **Native Codex coding agent:** set `agents.defaults.model.primary` to `openai/gpt-5.5`. Sign in with `openclaw models auth login --provider openai` when you want ChatGPT/Codex subscription auth.
|
||||
- **Direct OpenAI API tasks outside the agent loop:** configure `OPENAI_API_KEY` for images, embeddings, speech, realtime, and other non-agent OpenAI API surfaces.
|
||||
- **OpenAI agent API-key auth:** use `/model openai/gpt-5.5` with an ordered `openai-codex` API-key profile.
|
||||
- **OpenAI agent API-key auth:** use `/model openai/gpt-5.5` with an ordered `openai` API-key profile.
|
||||
- **Sub-agents:** route coding tasks to a Codex-focused agent with its own `openai/gpt-5.5` model.
|
||||
|
||||
See [Models](/concepts/models) and [Slash commands](/tools/slash-commands).
|
||||
|
||||
@@ -76,7 +76,7 @@ Live tests are split into two layers so we can isolate failures:
|
||||
- `OPENCLAW_LIVE_MODELS=modern` to run the modern allowlist (Opus/Sonnet 4.6+, GPT-5.2 + Codex, Gemini 3, DeepSeek V4, GLM 4.7, MiniMax M2.7, Grok 4.3)
|
||||
- `OPENCLAW_LIVE_MODELS=small` to run the constrained small-model allowlist (Qwen 8B/9B local-compatible routes, OpenRouter Qwen/GLM, and Z.AI GLM)
|
||||
- `OPENCLAW_LIVE_MODELS=all` is an alias for the modern allowlist
|
||||
- or `OPENCLAW_LIVE_MODELS="openai/gpt-5.5,openai-codex/gpt-5.5,anthropic/claude-opus-4-6,..."` (comma allowlist)
|
||||
- or `OPENCLAW_LIVE_MODELS="openai/gpt-5.5,anthropic/claude-opus-4-6,..."` (comma allowlist)
|
||||
- Modern/all and small sweeps default to their curated caps; set `OPENCLAW_LIVE_MAX_MODELS=0` for an exhaustive selected-profile sweep or a positive number for a smaller cap.
|
||||
- Exhaustive sweeps use `OPENCLAW_LIVE_TEST_TIMEOUT_MS` for the whole direct-model test timeout. Default: 60 minutes.
|
||||
- Direct-model probes run with 20-way parallelism by default; set `OPENCLAW_LIVE_MODEL_CONCURRENCY` to override.
|
||||
@@ -350,7 +350,7 @@ Narrow, explicit allowlists are fastest and least flaky:
|
||||
- `OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.5" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts`
|
||||
|
||||
- Tool calling across several providers:
|
||||
- `OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.5,openai-codex/gpt-5.5,anthropic/claude-opus-4-6,google/gemini-3-flash-preview,deepseek/deepseek-v4-flash,zai/glm-5.1,minimax/MiniMax-M2.7" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts`
|
||||
- `OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.5,anthropic/claude-opus-4-6,google/gemini-3-flash-preview,deepseek/deepseek-v4-flash,zai/glm-5.1,minimax/MiniMax-M2.7" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts`
|
||||
|
||||
- Google focus (Gemini API key + Antigravity):
|
||||
- Gemini (API key): `OPENCLAW_LIVE_GATEWAY_MODELS="google/gemini-3-flash-preview" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts`
|
||||
@@ -378,7 +378,7 @@ There is no fixed "CI model list" (live is opt-in), but these are the **recommen
|
||||
This is the "common models" run we expect to keep working:
|
||||
|
||||
- OpenAI (non-Codex): `openai/gpt-5.5`
|
||||
- OpenAI Codex OAuth: `openai-codex/gpt-5.5`
|
||||
- OpenAI ChatGPT/Codex OAuth: `openai/gpt-5.5`
|
||||
- Anthropic: `anthropic/claude-opus-4-6` (or `anthropic/claude-sonnet-4-6`)
|
||||
- Google (Gemini API): `google/gemini-3.1-pro-preview` and `google/gemini-3-flash-preview` (avoid older Gemini 2.x models)
|
||||
- Google (Antigravity): `google-antigravity/claude-opus-4-6-thinking` and `google-antigravity/gemini-3-flash`
|
||||
@@ -387,7 +387,7 @@ This is the "common models" run we expect to keep working:
|
||||
- MiniMax: `minimax/MiniMax-M2.7`
|
||||
|
||||
Run gateway smoke with tools + image:
|
||||
`OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.5,openai-codex/gpt-5.5,anthropic/claude-opus-4-6,google/gemini-3.1-pro-preview,google/gemini-3-flash-preview,google-antigravity/claude-opus-4-6-thinking,google-antigravity/gemini-3-flash,deepseek/deepseek-v4-flash,zai/glm-5.1,minimax/MiniMax-M2.7" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts`
|
||||
`OPENCLAW_LIVE_GATEWAY_MODELS="openai/gpt-5.5,anthropic/claude-opus-4-6,google/gemini-3.1-pro-preview,google/gemini-3-flash-preview,google-antigravity/claude-opus-4-6-thinking,google-antigravity/gemini-3-flash,deepseek/deepseek-v4-flash,zai/glm-5.1,minimax/MiniMax-M2.7" pnpm test:live src/gateway/gateway-models.profiles.live.test.ts`
|
||||
|
||||
### Baseline: tool calling (Read + optional Exec)
|
||||
|
||||
@@ -420,7 +420,7 @@ If you have keys enabled, we also support testing via:
|
||||
|
||||
More providers you can include in the live matrix (if you have creds/config):
|
||||
|
||||
- Built-in: `openai`, `openai-codex`, `anthropic`, `google`, `google-vertex`, `google-antigravity`, `google-gemini-cli`, `zai`, `openrouter`, `opencode`, `opencode-go`, `xai`, `groq`, `cerebras`, `mistral`, `github-copilot`
|
||||
- Built-in: `openai`, `anthropic`, `google`, `google-vertex`, `google-antigravity`, `google-gemini-cli`, `zai`, `openrouter`, `opencode`, `opencode-go`, `xai`, `groq`, `cerebras`, `mistral`, `github-copilot`
|
||||
- Via `models.providers` (custom endpoints): `minimax` (cloud/API), plus any OpenAI/Anthropic-compatible proxy (LM Studio, vLLM, LiteLLM, etc.)
|
||||
|
||||
<Tip>
|
||||
|
||||
@@ -296,8 +296,8 @@ replacement. Gateway startup does not generate bundled-plugin dependency trees.
|
||||
For full persistence details on VM deployments, see
|
||||
[Docker VM Runtime - What persists where](/install/docker-vm-runtime#what-persists-where).
|
||||
|
||||
**Disk growth hotspots:** watch `media/`, session JSONL files,
|
||||
`cron/runs/*.jsonl`, installed plugin package roots, and rolling file logs
|
||||
**Disk growth hotspots:** watch `media/`, session JSONL files, the shared
|
||||
SQLite state database, installed plugin package roots, and rolling file logs
|
||||
under `/tmp/openclaw/`.
|
||||
|
||||
### Shell helpers (optional)
|
||||
|
||||
@@ -277,11 +277,11 @@ For CLI entries, **set `capabilities` explicitly** to avoid surprising matches.
|
||||
|
||||
## Provider support matrix (OpenClaw integrations)
|
||||
|
||||
| Capability | Provider integration | Notes |
|
||||
| ---------- | ---------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Image | OpenAI, OpenAI Codex OAuth, Codex app-server, OpenRouter, Anthropic, Google, MiniMax, Moonshot, Qwen, Z.AI, config providers | Vendor plugins register image support; `openai-codex/*` uses OAuth provider plumbing; `codex/*` uses a bounded Codex app-server turn; MiniMax and MiniMax OAuth both use `MiniMax-VL-01`; image-capable config providers auto-register. |
|
||||
| Audio | OpenAI, Groq, xAI, Deepgram, OpenRouter, Google, SenseAudio, ElevenLabs, Mistral | Provider transcription (Whisper/Groq/xAI/Deepgram/OpenRouter STT/Gemini/SenseAudio/Scribe/Voxtral). |
|
||||
| Video | Google, Qwen, Moonshot | Provider video understanding via vendor plugins; Qwen video understanding uses the Standard DashScope endpoints. |
|
||||
| Capability | Provider integration | Notes |
|
||||
| ---------- | ---------------------------------------------------------------------------------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Image | OpenAI, OpenAI Codex OAuth, Codex app-server, OpenRouter, Anthropic, Google, MiniMax, Moonshot, Qwen, Z.AI, config providers | Vendor plugins register image support; `openai/*` can use API-key or Codex OAuth routing; `codex/*` uses a bounded Codex app-server turn; MiniMax and MiniMax OAuth both use `MiniMax-VL-01`; image-capable config providers auto-register. |
|
||||
| Audio | OpenAI, Groq, xAI, Deepgram, OpenRouter, Google, SenseAudio, ElevenLabs, Mistral | Provider transcription (Whisper/Groq/xAI/Deepgram/OpenRouter STT/Gemini/SenseAudio/Scribe/Voxtral). |
|
||||
| Video | Google, Qwen, Moonshot | Provider video understanding via vendor plugins; Qwen video understanding uses the Standard DashScope endpoints. |
|
||||
|
||||
<Note>
|
||||
**MiniMax note**
|
||||
|
||||
@@ -7,7 +7,7 @@ read_when:
|
||||
title: "iOS app"
|
||||
---
|
||||
|
||||
Availability: internal preview. The iOS app is not publicly distributed yet.
|
||||
Availability: iPhone app builds are distributed through Apple channels when enabled for a release. Local development builds can also run from source.
|
||||
|
||||
## What it does
|
||||
|
||||
|
||||
@@ -85,25 +85,25 @@ For an already-running app-server, use WebSocket transport:
|
||||
|
||||
Supported `appServer` fields:
|
||||
|
||||
| Field | Default | Meaning |
|
||||
| --------------------------------------------- | ------------------------------------------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `transport` | `"stdio"` | `"stdio"` spawns Codex; `"websocket"` connects to `url`. |
|
||||
| `command` | managed Codex binary | Executable for stdio transport. Leave unset to use the managed binary. |
|
||||
| `args` | `["app-server", "--listen", "stdio://"]` | Arguments for stdio transport. |
|
||||
| `url` | unset | WebSocket app-server URL. |
|
||||
| `authToken` | unset | Bearer token for WebSocket transport. |
|
||||
| `headers` | `{}` | Extra WebSocket headers. |
|
||||
| `clearEnv` | `[]` | Extra environment variable names removed from the spawned stdio app-server process after OpenClaw builds its inherited environment. |
|
||||
| `requestTimeoutMs` | `60000` | Timeout for app-server control-plane calls. |
|
||||
| `turnCompletionIdleTimeoutMs` | `60000` | Quiet window after Codex accepts a turn or after a turn-scoped app-server request while OpenClaw waits for `turn/completed`. |
|
||||
| `postToolRawAssistantCompletionIdleTimeoutMs` | `300000` | Completion-idle guard used after a tool handoff when Codex emits raw assistant completion or progress but does not send `turn/completed`. Use this for trusted or heavy workloads where post-tool synthesis can legitimately stay quiet longer than the final assistant release budget. |
|
||||
| `mode` | `"yolo"` unless local Codex requirements disallow YOLO | Preset for YOLO or guardian-reviewed execution. |
|
||||
| `approvalPolicy` | `"never"` or an allowed guardian approval policy | Native Codex approval policy sent to thread start, resume, and turn. |
|
||||
| `sandbox` | `"danger-full-access"` or an allowed guardian sandbox | Native Codex sandbox mode sent to thread start and resume. Active OpenClaw sandboxes narrow `danger-full-access` turns to Codex `workspace-write`; the turn network flag follows OpenClaw sandbox egress. |
|
||||
| `approvalsReviewer` | `"user"` or an allowed guardian reviewer | Use `"auto_review"` to let Codex review native approval prompts when allowed. |
|
||||
| `defaultWorkspaceDir` | current process directory | Workspace used by `/codex bind` when `--cwd` is omitted. |
|
||||
| `serviceTier` | unset | Optional Codex app-server service tier. `"priority"` enables fast-mode routing, `"flex"` requests flex processing, and `null` clears the override. Legacy `"fast"` is accepted as `"priority"`. |
|
||||
| `experimental.sandboxExecServer` | `false` | Preview opt-in that registers an OpenClaw sandbox-backed Codex environment with Codex app-server 0.132.0 or newer so native Codex execution can run inside the active OpenClaw sandbox. |
|
||||
| Field | Default | Meaning |
|
||||
| --------------------------------------------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `transport` | `"stdio"` | `"stdio"` spawns Codex; `"websocket"` connects to `url`. |
|
||||
| `command` | managed Codex binary | Executable for stdio transport. Leave unset to use the managed binary. |
|
||||
| `args` | `["app-server", "--listen", "stdio://"]` | Arguments for stdio transport. |
|
||||
| `url` | unset | WebSocket app-server URL. |
|
||||
| `authToken` | unset | Bearer token for WebSocket transport. |
|
||||
| `headers` | `{}` | Extra WebSocket headers. |
|
||||
| `clearEnv` | `[]` | Extra environment variable names removed from the spawned stdio app-server process after OpenClaw builds its inherited environment. |
|
||||
| `requestTimeoutMs` | `60000` | Timeout for app-server control-plane calls. |
|
||||
| `turnCompletionIdleTimeoutMs` | `60000` | Quiet window after Codex accepts a turn or after a turn-scoped app-server request while OpenClaw waits for `turn/completed`. |
|
||||
| `postToolRawAssistantCompletionIdleTimeoutMs` | `300000` | Completion-idle and progress guard used after a tool handoff, native tool completion, or post-tool raw assistant progress while OpenClaw waits for `turn/completed`. Use this for trusted or heavy workloads where post-tool synthesis can legitimately stay quiet longer than the final assistant release budget. |
|
||||
| `mode` | `"yolo"` unless local Codex requirements disallow YOLO | Preset for YOLO or guardian-reviewed execution. |
|
||||
| `approvalPolicy` | `"never"` or an allowed guardian approval policy | Native Codex approval policy sent to thread start, resume, and turn. |
|
||||
| `sandbox` | `"danger-full-access"` or an allowed guardian sandbox | Native Codex sandbox mode sent to thread start and resume. Active OpenClaw sandboxes narrow `danger-full-access` turns to Codex `workspace-write`; the turn network flag follows OpenClaw sandbox egress. |
|
||||
| `approvalsReviewer` | `"user"` or an allowed guardian reviewer | Use `"auto_review"` to let Codex review native approval prompts when allowed. |
|
||||
| `defaultWorkspaceDir` | current process directory | Workspace used by `/codex bind` when `--cwd` is omitted. |
|
||||
| `serviceTier` | unset | Optional Codex app-server service tier. `"priority"` enables fast-mode routing, `"flex"` requests flex processing, and `null` clears the override. Legacy `"fast"` is accepted as `"priority"`. |
|
||||
| `experimental.sandboxExecServer` | `false` | Preview opt-in that registers an OpenClaw sandbox-backed Codex environment with Codex app-server 0.132.0 or newer so native Codex execution can run inside the active OpenClaw sandbox. |
|
||||
|
||||
The plugin blocks older or unversioned app-server handshakes. Codex app-server
|
||||
must report stable version `0.125.0` or newer.
|
||||
@@ -329,23 +329,29 @@ OpenClaw session lane so follow-up chat messages are not queued behind a stale
|
||||
native turn.
|
||||
|
||||
Most non-terminal notifications for the same turn disarm that short watchdog
|
||||
because Codex has proven the turn is still alive. Raw `custom_tool_call_output`
|
||||
completions keep the short post-tool watchdog armed because they are the
|
||||
turn-scoped tool-result handoff. Completed `agentMessage` items and pre-tool raw
|
||||
assistant `rawResponseItem/completed` items arm the assistant-output release: if
|
||||
Codex then goes quiet without `turn/completed`, OpenClaw best-effort interrupts
|
||||
the native turn and releases the session lane. Post-tool raw assistant progress
|
||||
keeps waiting for `turn/completed` while a completion-idle guard stays armed; the
|
||||
guard uses `appServer.postToolRawAssistantCompletionIdleTimeoutMs` when
|
||||
configured and defaults to five minutes otherwise. Replay-safe stdio app-server
|
||||
failures, including turn-completion idle timeouts without assistant, tool,
|
||||
active-item, or side-effect evidence, are retried once on a fresh app-server
|
||||
attempt. Unsafe timeouts still retire the stuck app-server client and release
|
||||
the OpenClaw session lane. They also clear the stale native thread binding and
|
||||
surface a recoverable timeout message for user or maintainer judgment instead of
|
||||
being replayed automatically. Timeout diagnostics include the last
|
||||
app-server notification method and, for raw assistant response items, the item
|
||||
type, role, id, and a bounded assistant text preview.
|
||||
because Codex has proven the turn is still alive. Tool handoffs use a longer
|
||||
post-tool idle budget: after OpenClaw returns an `item/tool/call` response, after
|
||||
native tool items such as `commandExecution` complete, after raw
|
||||
`custom_tool_call_output` completions, and after post-tool raw assistant
|
||||
progress. The guard uses `appServer.postToolRawAssistantCompletionIdleTimeoutMs`
|
||||
when configured and defaults to five minutes otherwise. That same post-tool
|
||||
budget also extends the progress watchdog for the silent synthesis window before
|
||||
Codex emits the next current-turn event. Reasoning completions, commentary
|
||||
`agentMessage` completions, and pre-tool raw reasoning or assistant progress can
|
||||
be followed by an automatic final reply, so they use the post-progress reply
|
||||
guard instead of releasing the session lane immediately. Only
|
||||
final/non-commentary completed `agentMessage` items and pre-tool raw assistant
|
||||
completions arm the assistant-output release: if Codex then goes quiet without
|
||||
`turn/completed`, OpenClaw best-effort interrupts the native turn and releases
|
||||
the session lane. Replay-safe stdio app-server failures, including
|
||||
turn-completion idle timeouts without assistant, tool, active-item, or
|
||||
side-effect evidence, are retried once on a fresh app-server attempt. Unsafe
|
||||
timeouts still retire the stuck app-server client and release the OpenClaw
|
||||
session lane. They also clear the stale native thread binding and surface a
|
||||
recoverable timeout message for user or maintainer judgment instead of being
|
||||
replayed automatically. Timeout diagnostics include the last app-server
|
||||
notification method and, for raw assistant response items, the item type, role,
|
||||
id, and a bounded assistant text preview.
|
||||
|
||||
## Model discovery
|
||||
|
||||
@@ -427,15 +433,17 @@ filenames for persona files, because Codex fallbacks only apply when
|
||||
For OpenClaw workspace parity, the Codex harness resolves the other bootstrap
|
||||
files. `SOUL.md`, `IDENTITY.md`, `TOOLS.md`, and `USER.md` are forwarded as
|
||||
OpenClaw Codex developer instructions because they define the active agent,
|
||||
available workspace guidance, and user profile. `HEARTBEAT.md` content is not
|
||||
injected; heartbeat turns get a collaboration-mode pointer to read the file when
|
||||
it exists and is non-empty. `MEMORY.md` content from the configured agent
|
||||
workspace is not pasted into native Codex turn input when memory tools are
|
||||
available for that workspace; when it exists, the harness adds a small
|
||||
workspace-memory pointer and Codex should use `memory_search` or `memory_get`
|
||||
when durable memory is relevant. If tools are disabled, memory search is
|
||||
unavailable, or the active workspace differs from the agent memory workspace,
|
||||
`MEMORY.md` uses the normal bounded turn-context path.
|
||||
available workspace guidance, and user profile. The compact OpenClaw skills
|
||||
list is forwarded as turn-scoped collaboration developer instructions.
|
||||
`HEARTBEAT.md` content is not injected; heartbeat turns get a collaboration-mode
|
||||
pointer to read the file when it exists and is non-empty. `MEMORY.md` content
|
||||
from the configured agent workspace is not pasted into native Codex turn input
|
||||
when memory tools are available for that workspace; when it exists, the harness
|
||||
adds a small workspace-memory pointer to turn-scoped collaboration developer
|
||||
instructions and Codex should use `memory_search` or `memory_get` when durable
|
||||
memory is relevant. If tools are disabled, memory search is unavailable, or the
|
||||
active workspace differs from the agent memory workspace, `MEMORY.md` uses the
|
||||
normal bounded turn-context path.
|
||||
`BOOTSTRAP.md` when present is forwarded as OpenClaw turn input reference
|
||||
context.
|
||||
|
||||
|
||||
@@ -34,9 +34,10 @@ personality files and OpenClaw agent identity stay authoritative. Lightweight
|
||||
OpenClaw runs still preserve their existing project-doc suppression. OpenClaw
|
||||
developer instructions cover OpenClaw runtime concerns such as source-channel
|
||||
delivery, OpenClaw dynamic tools, ACP delegation, adapter context, and the
|
||||
active agent workspace profile files. OpenClaw skill catalogs plus `MEMORY.md`
|
||||
and active `BOOTSTRAP.md` content are projected as turn input reference context
|
||||
for native Codex.
|
||||
active agent workspace profile files. OpenClaw skill catalogs and tool-routed
|
||||
`MEMORY.md` pointers are projected as turn-scoped collaboration developer
|
||||
instructions for native Codex. Active `BOOTSTRAP.md` content and full
|
||||
`MEMORY.md` fallback injection still use turn input reference context.
|
||||
|
||||
## Thread bindings and model changes
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ Discord, Slack, or another channel remains the communication surface.
|
||||
- Codex app-server `0.125.0` or newer. The bundled plugin manages a compatible
|
||||
Codex app-server binary by default, so local `codex` commands on `PATH` do not
|
||||
affect normal harness startup.
|
||||
- Codex auth available through `openclaw models auth login --provider openai-codex`,
|
||||
- Codex auth available through `openclaw models auth login --provider openai`,
|
||||
an app-server account in the agent's Codex home, or an explicit Codex API-key
|
||||
auth profile.
|
||||
|
||||
@@ -61,7 +61,7 @@ canonical `openai/gpt-*` model ref.
|
||||
Sign in with Codex OAuth:
|
||||
|
||||
```bash
|
||||
openclaw models auth login --provider openai-codex
|
||||
openclaw models auth login --provider openai
|
||||
```
|
||||
|
||||
Enable the bundled `codex` plugin and select an OpenAI agent model:
|
||||
@@ -112,7 +112,7 @@ harness options in OpenClaw config, and use the CLI only for Codex auth:
|
||||
| Enable the harness | `plugins.entries.codex.enabled: true` | OpenClaw config |
|
||||
| Keep an allowlisted plugin install | Include `codex` in `plugins.allow` | OpenClaw config |
|
||||
| Route OpenAI agent turns through Codex | `agents.defaults.model` or `agents.list[].model` as `openai/gpt-*` | OpenClaw agent config |
|
||||
| Sign in with Codex OAuth | `openclaw models auth login --provider openai-codex` | CLI auth profile |
|
||||
| Sign in with ChatGPT/Codex OAuth | `openclaw models auth login --provider openai` | CLI auth profile |
|
||||
| Add API-key backup for Codex runs | `openai:*` API-key profile listed after subscription auth in `auth.order.openai` | CLI auth profile + OpenClaw config |
|
||||
| Fail closed when Codex is unavailable | Provider or model `agentRuntime.id: "codex"` | OpenClaw model/provider config |
|
||||
| Use direct OpenAI API traffic | Provider or model `agentRuntime.id: "openclaw"` with normal OpenAI auth | OpenClaw model/provider config |
|
||||
@@ -153,7 +153,7 @@ instead of silently switching compaction backends.
|
||||
{
|
||||
auth: {
|
||||
order: {
|
||||
openai: ["openai-codex:user@example.com", "openai:api-key-backup"],
|
||||
openai: ["openai:user@example.com", "openai:api-key-backup"],
|
||||
},
|
||||
},
|
||||
}
|
||||
@@ -444,7 +444,8 @@ For upload mechanics and runtime-level diagnostics boundaries, see
|
||||
Auth is selected in this order:
|
||||
|
||||
1. Ordered OpenAI auth profiles for the agent, preferably under
|
||||
`auth.order.openai`. Existing `openai-codex:*` profile ids remain valid.
|
||||
`auth.order.openai`. Run `openclaw doctor --fix` to migrate older
|
||||
`openai-codex:*` profile ids and `auth.order.openai-codex`.
|
||||
2. The app-server's existing account in that agent's Codex home.
|
||||
3. For local stdio app-server launches only, `CODEX_API_KEY`, then
|
||||
`OPENAI_API_KEY`, when no app-server account is present and OpenAI auth is
|
||||
@@ -525,25 +526,25 @@ Supported top-level Codex plugin fields:
|
||||
|
||||
Supported `appServer` fields:
|
||||
|
||||
| Field | Default | Meaning |
|
||||
| --------------------------------------------- | ------------------------------------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `transport` | `"stdio"` | `"stdio"` spawns Codex; `"websocket"` connects to `url`. |
|
||||
| `command` | managed Codex binary | Executable for stdio transport. Leave unset to use the managed binary; set it only for an explicit override. |
|
||||
| `args` | `["app-server", "--listen", "stdio://"]` | Arguments for stdio transport. |
|
||||
| `url` | unset | WebSocket app-server URL. |
|
||||
| `authToken` | unset | Bearer token for WebSocket transport. |
|
||||
| `headers` | `{}` | Extra WebSocket headers. |
|
||||
| `clearEnv` | `[]` | Extra environment variable names removed from the spawned stdio app-server process after OpenClaw builds its inherited environment. OpenClaw keeps per-agent `CODEX_HOME` and inherited `HOME` for local launches. |
|
||||
| `codeModeOnly` | `false` | Opt into Codex's code-mode-only tool surface. OpenClaw dynamic tools remain registered with Codex so nested `tools.*` calls return through the app-server `item/tool/call` bridge. |
|
||||
| `requestTimeoutMs` | `60000` | Timeout for app-server control-plane calls. |
|
||||
| `turnCompletionIdleTimeoutMs` | `60000` | Quiet window after Codex accepts a turn or after a turn-scoped app-server request while OpenClaw waits for `turn/completed`. Raise this for slow post-tool or status-only synthesis phases. |
|
||||
| `postToolRawAssistantCompletionIdleTimeoutMs` | `300000` | Completion-idle guard used after a tool handoff when Codex emits raw assistant completion or progress but does not send `turn/completed`. Use this for trusted or heavy workloads where post-tool synthesis can legitimately stay quiet longer than the final assistant release budget. |
|
||||
| `mode` | `"yolo"` unless local Codex requirements disallow YOLO | Preset for YOLO or guardian-reviewed execution. Local stdio requirements that omit `danger-full-access`, `never` approval, or the `user` reviewer make the implicit default guardian. |
|
||||
| `approvalPolicy` | `"never"` or an allowed guardian approval policy | Native Codex approval policy sent to thread start/resume/turn. Guardian defaults prefer `"on-request"` when allowed. |
|
||||
| `sandbox` | `"danger-full-access"` or an allowed guardian sandbox | Native Codex sandbox mode sent to thread start/resume. Guardian defaults prefer `"workspace-write"` when allowed, otherwise `"read-only"`. When an OpenClaw sandbox is active, `danger-full-access` turns use Codex `workspace-write` with network access derived from the OpenClaw sandbox egress setting. |
|
||||
| `approvalsReviewer` | `"user"` or an allowed guardian reviewer | Use `"auto_review"` to let Codex review native approval prompts when allowed, otherwise `guardian_subagent` or `user`. `guardian_subagent` remains a legacy alias. |
|
||||
| `serviceTier` | unset | Optional Codex app-server service tier. `"priority"` enables fast-mode routing, `"flex"` requests flex processing, `null` clears the override, and legacy `"fast"` is accepted as `"priority"`. |
|
||||
| `experimental.sandboxExecServer` | `false` | Preview opt-in that registers an OpenClaw sandbox-backed Codex environment with Codex app-server 0.132.0 or newer so native Codex execution can run inside the active OpenClaw sandbox. |
|
||||
| Field | Default | Meaning |
|
||||
| --------------------------------------------- | ------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||
| `transport` | `"stdio"` | `"stdio"` spawns Codex; `"websocket"` connects to `url`. |
|
||||
| `command` | managed Codex binary | Executable for stdio transport. Leave unset to use the managed binary; set it only for an explicit override. |
|
||||
| `args` | `["app-server", "--listen", "stdio://"]` | Arguments for stdio transport. |
|
||||
| `url` | unset | WebSocket app-server URL. |
|
||||
| `authToken` | unset | Bearer token for WebSocket transport. |
|
||||
| `headers` | `{}` | Extra WebSocket headers. |
|
||||
| `clearEnv` | `[]` | Extra environment variable names removed from the spawned stdio app-server process after OpenClaw builds its inherited environment. OpenClaw keeps per-agent `CODEX_HOME` and inherited `HOME` for local launches. |
|
||||
| `codeModeOnly` | `false` | Opt into Codex's code-mode-only tool surface. OpenClaw dynamic tools remain registered with Codex so nested `tools.*` calls return through the app-server `item/tool/call` bridge. |
|
||||
| `requestTimeoutMs` | `60000` | Timeout for app-server control-plane calls. |
|
||||
| `turnCompletionIdleTimeoutMs` | `60000` | Quiet window after Codex accepts a turn or after a turn-scoped app-server request while OpenClaw waits for `turn/completed`. |
|
||||
| `postToolRawAssistantCompletionIdleTimeoutMs` | `300000` | Completion-idle and progress guard used after a tool handoff, native tool completion, or post-tool raw assistant progress while OpenClaw waits for `turn/completed`. Use this for trusted or heavy workloads where post-tool synthesis can legitimately stay quiet longer than the final assistant release budget. |
|
||||
| `mode` | `"yolo"` unless local Codex requirements disallow YOLO | Preset for YOLO or guardian-reviewed execution. Local stdio requirements that omit `danger-full-access`, `never` approval, or the `user` reviewer make the implicit default guardian. |
|
||||
| `approvalPolicy` | `"never"` or an allowed guardian approval policy | Native Codex approval policy sent to thread start/resume/turn. Guardian defaults prefer `"on-request"` when allowed. |
|
||||
| `sandbox` | `"danger-full-access"` or an allowed guardian sandbox | Native Codex sandbox mode sent to thread start/resume. Guardian defaults prefer `"workspace-write"` when allowed, otherwise `"read-only"`. When an OpenClaw sandbox is active, `danger-full-access` turns use Codex `workspace-write` with network access derived from the OpenClaw sandbox egress setting. |
|
||||
| `approvalsReviewer` | `"user"` or an allowed guardian reviewer | Use `"auto_review"` to let Codex review native approval prompts when allowed, otherwise `guardian_subagent` or `user`. `guardian_subagent` remains a legacy alias. |
|
||||
| `serviceTier` | unset | Optional Codex app-server service tier. `"priority"` enables fast-mode routing, `"flex"` requests flex processing, `null` clears the override, and legacy `"fast"` is accepted as `"priority"`. |
|
||||
| `experimental.sandboxExecServer` | `false` | Preview opt-in that registers an OpenClaw sandbox-backed Codex environment with Codex app-server 0.132.0 or newer so native Codex execution can run inside the active OpenClaw sandbox. |
|
||||
|
||||
OpenClaw-owned dynamic tool calls are bounded independently from
|
||||
`appServer.requestTimeoutMs`: Codex `item/tool/call` requests use a 90 second
|
||||
@@ -564,18 +565,23 @@ quiet for `appServer.turnCompletionIdleTimeoutMs`, OpenClaw best-effort
|
||||
interrupts the Codex turn, records a diagnostic timeout, and releases the
|
||||
OpenClaw session lane so follow-up chat messages are not queued behind a stale
|
||||
native turn. Most non-terminal notifications for the same turn disarm that short
|
||||
watchdog because Codex has proven the turn is still alive; raw
|
||||
`custom_tool_call_output` completions keep the short post-tool watchdog armed
|
||||
because they are the turn-scoped tool-result handoff. Global app-server
|
||||
notifications, such as rate-limit updates, do not reset turn-idle progress.
|
||||
Completed `agentMessage` items and pre-tool raw assistant
|
||||
`rawResponseItem/completed` items arm the assistant-output release: if Codex then
|
||||
goes quiet without `turn/completed`, OpenClaw best-effort interrupts the native
|
||||
turn and releases the session lane. Post-tool raw assistant progress keeps
|
||||
waiting for `turn/completed` while a completion-idle guard stays armed; the guard
|
||||
uses `appServer.postToolRawAssistantCompletionIdleTimeoutMs` when configured and
|
||||
defaults to five minutes otherwise. Replay-safe stdio app-server failures,
|
||||
including turn-completion idle timeouts without assistant, tool, active-item, or
|
||||
watchdog because Codex has proven the turn is still alive. Tool handoffs use a
|
||||
longer post-tool idle budget: after OpenClaw returns an `item/tool/call`
|
||||
response, after native tool items such as `commandExecution` complete, after raw
|
||||
`custom_tool_call_output` completions, and after post-tool raw assistant
|
||||
progress. The guard uses `appServer.postToolRawAssistantCompletionIdleTimeoutMs`
|
||||
when configured and defaults to five minutes otherwise. That same post-tool
|
||||
budget also extends the progress watchdog for the silent synthesis window before
|
||||
Codex emits the next current-turn event. Global app-server notifications, such
|
||||
as rate-limit updates, do not reset turn-idle progress. Reasoning completions,
|
||||
commentary `agentMessage` completions, and pre-tool raw reasoning or assistant
|
||||
progress can be followed by an automatic final reply, so they use the
|
||||
post-progress reply guard instead of releasing the session lane immediately.
|
||||
Only final/non-commentary completed `agentMessage` items and pre-tool raw
|
||||
assistant completions arm the assistant-output release: if Codex then goes quiet
|
||||
without `turn/completed`, OpenClaw best-effort interrupts the native turn and
|
||||
releases the session lane. Replay-safe stdio app-server failures, including
|
||||
turn-completion idle timeouts without assistant, tool, active-item, or
|
||||
side-effect evidence, are retried once on a fresh app-server attempt. Unsafe
|
||||
timeouts still retire the stuck app-server client and release the OpenClaw
|
||||
session lane. They also clear the stale native thread binding and surface a
|
||||
@@ -720,7 +726,7 @@ Ask affected collaborators to run this read-only command on their OpenClaw host:
|
||||
Useful excerpts usually include `openai/gpt-5.5` or `openai/gpt-5.4`,
|
||||
`Runtime: OpenAI Codex`, `agentRuntime.id` or `harnessRuntime`,
|
||||
`candidateProvider: "openai"`, and a `401`, `Incorrect API key`, or
|
||||
`No API key` result. A corrected run should show the `openai-codex` OAuth
|
||||
`No API key` result. A corrected run should show the OpenAI OAuth
|
||||
path instead of a plain OpenAI API-key failure.
|
||||
|
||||
**Legacy `openai-codex/*` config remains:** run `openclaw doctor --fix`.
|
||||
|
||||
@@ -141,7 +141,10 @@ observation-only.
|
||||
|
||||
**Subagents**
|
||||
|
||||
- `subagent_spawning` / `subagent_delivery_target` / `subagent_spawned` / `subagent_ended` - coordinate subagent routing and completion delivery
|
||||
- `subagent_spawned` / `subagent_ended` - observe subagent launch and completion.
|
||||
- `subagent_delivery_target` - compatibility hook for completion delivery when no core session binding can project a route.
|
||||
- `subagent_spawning` - deprecated compatibility hook. Core now prepares `thread: true` subagent bindings through channel session-binding adapters before `subagent_spawned` fires.
|
||||
- `subagent_spawned` includes `resolvedModel` and `resolvedProvider` when OpenClaw has resolved the child session's native model before launch.
|
||||
|
||||
**Lifecycle**
|
||||
|
||||
@@ -463,6 +466,10 @@ before the next major release:
|
||||
- **`before_agent_start`** remains for compatibility. New plugins should use
|
||||
`before_model_resolve` and `before_prompt_build` instead of the combined
|
||||
phase.
|
||||
- **`subagent_spawning`** remains for compatibility with older plugins, but
|
||||
new plugins should not return thread routing from it. Core prepares
|
||||
`thread: true` subagent bindings through channel session-binding adapters
|
||||
before `subagent_spawned` fires.
|
||||
- **`deactivate`** remains as a deprecated cleanup compatibility alias until
|
||||
after 2026-08-16. New plugins should use `gateway_stop`.
|
||||
- **`onResolution` in `before_tool_call`** now uses the typed
|
||||
|
||||
@@ -636,7 +636,7 @@ read without importing the plugin runtime.
|
||||
"realtimeTranscriptionProviders": ["openai"],
|
||||
"realtimeVoiceProviders": ["openai"],
|
||||
"memoryEmbeddingProviders": ["local"],
|
||||
"mediaUnderstandingProviders": ["openai", "openai-codex"],
|
||||
"mediaUnderstandingProviders": ["openai"],
|
||||
"imageGenerationProviders": ["openai"],
|
||||
"videoGenerationProviders": ["qwen"],
|
||||
"webFetchProviders": ["firecrawl"],
|
||||
|
||||
@@ -125,8 +125,8 @@ embeddings:
|
||||
}
|
||||
```
|
||||
|
||||
OpenAI Codex / ChatGPT OAuth (`openai-codex`) is not an OpenAI Platform
|
||||
embeddings credential. For OpenAI embeddings, use an OpenAI API key auth profile,
|
||||
OpenAI Codex / ChatGPT OAuth is not an OpenAI Platform embeddings credential.
|
||||
For OpenAI embeddings, use an OpenAI API key auth profile,
|
||||
`OPENAI_API_KEY`, or `models.providers.openai.apiKey`. OAuth-only users can use
|
||||
another embedding-capable provider such as GitHub Copilot or Ollama.
|
||||
|
||||
|
||||
@@ -79,6 +79,7 @@ commands.
|
||||
| [firecrawl](/plugins/reference/firecrawl) | Adds agent-callable tools. Adds web fetch provider support. Adds web search provider support. | `@openclaw/firecrawl-plugin`<br />included in OpenClaw | contracts: tools, webFetchProviders, webSearchProviders |
|
||||
| [fireworks](/plugins/reference/fireworks) | Adds Fireworks model provider support to OpenClaw. | `@openclaw/fireworks-provider`<br />included in OpenClaw | providers: fireworks |
|
||||
| [github-copilot](/plugins/reference/github-copilot) | Adds GitHub Copilot model provider support to OpenClaw. | `@openclaw/github-copilot-provider`<br />included in OpenClaw | providers: github-copilot; contracts: memoryEmbeddingProviders |
|
||||
| [gmi](/plugins/reference/gmi) | Adds Gmi, Gmi Cloud, Gmicloud model provider support to OpenClaw. | `@openclaw/gmi-provider`<br />included in OpenClaw | providers: gmi, gmi-cloud, gmicloud |
|
||||
| [google](/plugins/reference/google) | Adds Google, Google Gemini CLI, Google Vertex model provider support to OpenClaw. | `@openclaw/google-plugin`<br />included in OpenClaw | providers: google, google-gemini-cli, google-vertex; contracts: imageGenerationProviders, mediaUnderstandingProviders, memoryEmbeddingProviders, musicGenerationProviders, realtimeVoiceProviders, speechProviders, videoGenerationProviders, webSearchProviders |
|
||||
| [gradium](/plugins/reference/gradium) | Adds text-to-speech provider support. | `@openclaw/gradium-speech`<br />included in OpenClaw | contracts: speechProviders |
|
||||
| [groq](/plugins/reference/groq) | Adds Groq model provider support to OpenClaw. | `@openclaw/groq-provider`<br />included in OpenClaw | providers: groq; contracts: mediaUnderstandingProviders |
|
||||
@@ -101,24 +102,24 @@ commands.
|
||||
| [minimax](/plugins/reference/minimax) | Adds MiniMax, MiniMax Portal model provider support to OpenClaw. | `@openclaw/minimax-provider`<br />included in OpenClaw | providers: minimax, minimax-portal; contracts: imageGenerationProviders, mediaUnderstandingProviders, musicGenerationProviders, speechProviders, videoGenerationProviders, webSearchProviders |
|
||||
| [mistral](/plugins/reference/mistral) | Adds Mistral model provider support to OpenClaw. | `@openclaw/mistral-provider`<br />included in OpenClaw | providers: mistral; contracts: mediaUnderstandingProviders, memoryEmbeddingProviders, realtimeTranscriptionProviders |
|
||||
| [moonshot](/plugins/reference/moonshot) | Adds Moonshot model provider support to OpenClaw. | `@openclaw/moonshot-provider`<br />included in OpenClaw | providers: moonshot; contracts: mediaUnderstandingProviders, webSearchProviders |
|
||||
| [novita](/plugins/reference/novita) | Adds Novita, Novita AI, Novitaai model provider support to OpenClaw. | `@openclaw/novita-provider`<br />included in OpenClaw | providers: novita, novita-ai, novitaai |
|
||||
| [nvidia](/plugins/reference/nvidia) | Adds NVIDIA model provider support to OpenClaw. | `@openclaw/nvidia-provider`<br />included in OpenClaw | providers: nvidia |
|
||||
| [oc-path](/plugins/reference/oc-path) | Adds the openclaw path CLI for oc:// workspace file addressing. | `@openclaw/oc-path`<br />included in OpenClaw | plugin |
|
||||
| [ollama](/plugins/reference/ollama) | Adds Ollama model provider support to OpenClaw. | `@openclaw/ollama-provider`<br />included in OpenClaw | providers: ollama; contracts: memoryEmbeddingProviders, webSearchProviders |
|
||||
| [ollama](/plugins/reference/ollama) | Adds Ollama, Ollama Cloud model provider support to OpenClaw. | `@openclaw/ollama-provider`<br />included in OpenClaw | providers: ollama, ollama-cloud; contracts: memoryEmbeddingProviders, webSearchProviders |
|
||||
| [open-prose](/plugins/reference/open-prose) | OpenProse VM skill pack with a /prose slash command. | `@openclaw/open-prose`<br />included in OpenClaw | skills |
|
||||
| [openai](/plugins/reference/openai) | Adds OpenAI, OpenAI Codex model provider support to OpenClaw. | `@openclaw/openai-provider`<br />included in OpenClaw | providers: openai, openai-codex; contracts: imageGenerationProviders, mediaUnderstandingProviders, memoryEmbeddingProviders, realtimeTranscriptionProviders, realtimeVoiceProviders, speechProviders, videoGenerationProviders |
|
||||
| [openai](/plugins/reference/openai) | Adds OpenAI model provider support to OpenClaw, including ChatGPT/Codex OAuth. | `@openclaw/openai-provider`<br />included in OpenClaw | providers: openai; contracts: imageGenerationProviders, mediaUnderstandingProviders, memoryEmbeddingProviders, realtimeTranscriptionProviders, realtimeVoiceProviders, speechProviders, videoGenerationProviders |
|
||||
| [opencode](/plugins/reference/opencode) | Adds OpenCode model provider support to OpenClaw. | `@openclaw/opencode-provider`<br />included in OpenClaw | providers: opencode; contracts: mediaUnderstandingProviders |
|
||||
| [opencode-go](/plugins/reference/opencode-go) | Adds OpenCode Go model provider support to OpenClaw. | `@openclaw/opencode-go-provider`<br />included in OpenClaw | providers: opencode-go; contracts: mediaUnderstandingProviders |
|
||||
| [openrouter](/plugins/reference/openrouter) | Adds OpenRouter model provider support to OpenClaw. | `@openclaw/openrouter-provider`<br />included in OpenClaw | providers: openrouter; contracts: imageGenerationProviders, mediaUnderstandingProviders, musicGenerationProviders, speechProviders, videoGenerationProviders |
|
||||
| [perplexity](/plugins/reference/perplexity) | Adds web search provider support. | `@openclaw/perplexity-plugin`<br />included in OpenClaw | contracts: webSearchProviders |
|
||||
| [policy](/plugins/reference/policy) | Adds policy-backed doctor checks for workspace conformance. | `@openclaw/policy`<br />included in OpenClaw | plugin |
|
||||
| [qianfan](/plugins/reference/qianfan) | Adds Qianfan model provider support to OpenClaw. | `@openclaw/qianfan-provider`<br />included in OpenClaw | providers: qianfan |
|
||||
| [qwen](/plugins/reference/qwen) | Adds Qwen, Qwen Cloud, Model Studio, DashScope model provider support to OpenClaw. | `@openclaw/qwen-provider`<br />included in OpenClaw | providers: qwen, qwencloud, modelstudio, dashscope; contracts: mediaUnderstandingProviders, videoGenerationProviders |
|
||||
| [qwen](/plugins/reference/qwen) | Adds Qwen, Qwen Cloud, Model Studio, DashScope, Qwen Oauth, Qwen Portal, Qwen CLI model provider support to OpenClaw. | `@openclaw/qwen-provider`<br />included in OpenClaw | providers: qwen, qwencloud, modelstudio, dashscope, qwen-oauth, qwen-portal, qwen-cli; contracts: mediaUnderstandingProviders, videoGenerationProviders |
|
||||
| [runway](/plugins/reference/runway) | Adds video generation provider support. | `@openclaw/runway-provider`<br />included in OpenClaw | contracts: videoGenerationProviders |
|
||||
| [searxng](/plugins/reference/searxng) | Adds web search provider support. | `@openclaw/searxng-plugin`<br />included in OpenClaw | contracts: webSearchProviders |
|
||||
| [senseaudio](/plugins/reference/senseaudio) | Adds media understanding provider support. | `@openclaw/senseaudio-provider`<br />included in OpenClaw | contracts: mediaUnderstandingProviders |
|
||||
| [sglang](/plugins/reference/sglang) | Adds SGLang model provider support to OpenClaw. | `@openclaw/sglang-provider`<br />included in OpenClaw | providers: sglang |
|
||||
| [signal](/plugins/reference/signal) | Adds the Signal channel surface for sending and receiving OpenClaw messages. | `@openclaw/signal`<br />included in OpenClaw | channels: signal |
|
||||
| [skill-workshop](/plugins/reference/skill-workshop) | Captures repeatable workflows as workspace skills, with pending review, safe writes, and skill prompt refresh. | `@openclaw/skill-workshop`<br />included in OpenClaw | contracts: tools |
|
||||
| [stepfun](/plugins/reference/stepfun) | Adds StepFun, StepFun Plan model provider support to OpenClaw. | `@openclaw/stepfun-provider`<br />included in OpenClaw | providers: stepfun, stepfun-plan |
|
||||
| [synthetic](/plugins/reference/synthetic) | Adds Synthetic model provider support to OpenClaw. | `@openclaw/synthetic-provider`<br />included in OpenClaw | providers: synthetic |
|
||||
| [tavily](/plugins/reference/tavily) | Adds agent-callable tools. Adds web search provider support. | `@openclaw/tavily-plugin`<br />included in OpenClaw | contracts: tools, webSearchProviders; skills |
|
||||
@@ -136,7 +137,7 @@ commands.
|
||||
| [webhooks](/plugins/reference/webhooks) | Authenticated inbound webhooks that bind external automation to OpenClaw TaskFlows. | `@openclaw/webhooks`<br />included in OpenClaw | plugin |
|
||||
| [workboard](/plugins/reference/workboard) | Dashboard workboard for agent-owned issues and sessions. | `@openclaw/workboard`<br />included in OpenClaw | contracts: tools |
|
||||
| [xai](/plugins/reference/xai) | Adds xAI model provider support to OpenClaw. | `@openclaw/xai-plugin`<br />included in OpenClaw | providers: xai; contracts: imageGenerationProviders, mediaUnderstandingProviders, realtimeTranscriptionProviders, speechProviders, tools, videoGenerationProviders, webSearchProviders |
|
||||
| [xiaomi](/plugins/reference/xiaomi) | Adds Xiaomi model provider support to OpenClaw. | `@openclaw/xiaomi-provider`<br />included in OpenClaw | providers: xiaomi; contracts: speechProviders |
|
||||
| [xiaomi](/plugins/reference/xiaomi) | Adds Xiaomi MiMo pay-as-you-go and Token Plan provider support to OpenClaw. | `@openclaw/xiaomi-provider`<br />included in OpenClaw | providers: xiaomi, xiaomi-token-plan; contracts: speechProviders |
|
||||
| [zai](/plugins/reference/zai) | Adds Z.AI model provider support to OpenClaw. | `@openclaw/zai-provider`<br />included in OpenClaw | providers: zai; contracts: mediaUnderstandingProviders |
|
||||
|
||||
## Official external packages
|
||||
|
||||
@@ -58,6 +58,7 @@ pnpm plugins:inventory:gen
|
||||
| [firecrawl](/plugins/reference/firecrawl) | Adds agent-callable tools. Adds web fetch provider support. Adds web search provider support. | `@openclaw/firecrawl-plugin`<br />included in OpenClaw | contracts: tools, webFetchProviders, webSearchProviders |
|
||||
| [fireworks](/plugins/reference/fireworks) | Adds Fireworks model provider support to OpenClaw. | `@openclaw/fireworks-provider`<br />included in OpenClaw | providers: fireworks |
|
||||
| [github-copilot](/plugins/reference/github-copilot) | Adds GitHub Copilot model provider support to OpenClaw. | `@openclaw/github-copilot-provider`<br />included in OpenClaw | providers: github-copilot; contracts: memoryEmbeddingProviders |
|
||||
| [gmi](/plugins/reference/gmi) | Adds Gmi, Gmi Cloud, Gmicloud model provider support to OpenClaw. | `@openclaw/gmi-provider`<br />included in OpenClaw | providers: gmi, gmi-cloud, gmicloud |
|
||||
| [google](/plugins/reference/google) | Adds Google, Google Gemini CLI, Google Vertex model provider support to OpenClaw. | `@openclaw/google-plugin`<br />included in OpenClaw | providers: google, google-gemini-cli, google-vertex; contracts: imageGenerationProviders, mediaUnderstandingProviders, memoryEmbeddingProviders, musicGenerationProviders, realtimeVoiceProviders, speechProviders, videoGenerationProviders, webSearchProviders |
|
||||
| [google-meet](/plugins/reference/google-meet) | OpenClaw Google Meet participant plugin for joining calls through Chrome or Twilio transports. | `@openclaw/google-meet`<br />npm; ClawHub | contracts: tools |
|
||||
| [googlechat](/plugins/reference/googlechat) | OpenClaw Google Chat channel plugin for spaces and direct messages. | `@openclaw/googlechat`<br />npm; ClawHub | channels: googlechat |
|
||||
@@ -89,11 +90,12 @@ pnpm plugins:inventory:gen
|
||||
| [msteams](/plugins/reference/msteams) | OpenClaw Microsoft Teams channel plugin for bot conversations. | `@openclaw/msteams`<br />npm; ClawHub | channels: msteams |
|
||||
| [nextcloud-talk](/plugins/reference/nextcloud-talk) | OpenClaw Nextcloud Talk channel plugin for conversations. | `@openclaw/nextcloud-talk`<br />npm; ClawHub | channels: nextcloud-talk |
|
||||
| [nostr](/plugins/reference/nostr) | OpenClaw Nostr channel plugin for NIP-04 encrypted direct messages. | `@openclaw/nostr`<br />npm; ClawHub | channels: nostr |
|
||||
| [novita](/plugins/reference/novita) | Adds Novita, Novita AI, Novitaai model provider support to OpenClaw. | `@openclaw/novita-provider`<br />included in OpenClaw | providers: novita, novita-ai, novitaai |
|
||||
| [nvidia](/plugins/reference/nvidia) | Adds NVIDIA model provider support to OpenClaw. | `@openclaw/nvidia-provider`<br />included in OpenClaw | providers: nvidia |
|
||||
| [oc-path](/plugins/reference/oc-path) | Adds the openclaw path CLI for oc:// workspace file addressing. | `@openclaw/oc-path`<br />included in OpenClaw | plugin |
|
||||
| [ollama](/plugins/reference/ollama) | Adds Ollama model provider support to OpenClaw. | `@openclaw/ollama-provider`<br />included in OpenClaw | providers: ollama; contracts: memoryEmbeddingProviders, webSearchProviders |
|
||||
| [ollama](/plugins/reference/ollama) | Adds Ollama, Ollama Cloud model provider support to OpenClaw. | `@openclaw/ollama-provider`<br />included in OpenClaw | providers: ollama, ollama-cloud; contracts: memoryEmbeddingProviders, webSearchProviders |
|
||||
| [open-prose](/plugins/reference/open-prose) | OpenProse VM skill pack with a /prose slash command. | `@openclaw/open-prose`<br />included in OpenClaw | skills |
|
||||
| [openai](/plugins/reference/openai) | Adds OpenAI, OpenAI Codex model provider support to OpenClaw. | `@openclaw/openai-provider`<br />included in OpenClaw | providers: openai, openai-codex; contracts: imageGenerationProviders, mediaUnderstandingProviders, memoryEmbeddingProviders, realtimeTranscriptionProviders, realtimeVoiceProviders, speechProviders, videoGenerationProviders |
|
||||
| [openai](/plugins/reference/openai) | Adds OpenAI model provider support to OpenClaw, including ChatGPT/Codex OAuth. | `@openclaw/openai-provider`<br />included in OpenClaw | providers: openai; contracts: imageGenerationProviders, mediaUnderstandingProviders, memoryEmbeddingProviders, realtimeTranscriptionProviders, realtimeVoiceProviders, speechProviders, videoGenerationProviders |
|
||||
| [opencode](/plugins/reference/opencode) | Adds OpenCode model provider support to OpenClaw. | `@openclaw/opencode-provider`<br />included in OpenClaw | providers: opencode; contracts: mediaUnderstandingProviders |
|
||||
| [opencode-go](/plugins/reference/opencode-go) | Adds OpenCode Go model provider support to OpenClaw. | `@openclaw/opencode-go-provider`<br />included in OpenClaw | providers: opencode-go; contracts: mediaUnderstandingProviders |
|
||||
| [openrouter](/plugins/reference/openrouter) | Adds OpenRouter model provider support to OpenClaw. | `@openclaw/openrouter-provider`<br />included in OpenClaw | providers: openrouter; contracts: imageGenerationProviders, mediaUnderstandingProviders, musicGenerationProviders, speechProviders, videoGenerationProviders |
|
||||
@@ -106,13 +108,12 @@ pnpm plugins:inventory:gen
|
||||
| [qa-matrix](/plugins/reference/qa-matrix) | Matrix QA transport runner and substrate. | `@openclaw/qa-matrix`<br />source checkout only | plugin |
|
||||
| [qianfan](/plugins/reference/qianfan) | Adds Qianfan model provider support to OpenClaw. | `@openclaw/qianfan-provider`<br />included in OpenClaw | providers: qianfan |
|
||||
| [qqbot](/plugins/reference/qqbot) | OpenClaw QQ Bot channel plugin for group and direct-message workflows. | `@openclaw/qqbot`<br />npm; ClawHub | channels: qqbot; contracts: tools; skills |
|
||||
| [qwen](/plugins/reference/qwen) | Adds Qwen, Qwen Cloud, Model Studio, DashScope model provider support to OpenClaw. | `@openclaw/qwen-provider`<br />included in OpenClaw | providers: qwen, qwencloud, modelstudio, dashscope; contracts: mediaUnderstandingProviders, videoGenerationProviders |
|
||||
| [qwen](/plugins/reference/qwen) | Adds Qwen, Qwen Cloud, Model Studio, DashScope, Qwen Oauth, Qwen Portal, Qwen CLI model provider support to OpenClaw. | `@openclaw/qwen-provider`<br />included in OpenClaw | providers: qwen, qwencloud, modelstudio, dashscope, qwen-oauth, qwen-portal, qwen-cli; contracts: mediaUnderstandingProviders, videoGenerationProviders |
|
||||
| [runway](/plugins/reference/runway) | Adds video generation provider support. | `@openclaw/runway-provider`<br />included in OpenClaw | contracts: videoGenerationProviders |
|
||||
| [searxng](/plugins/reference/searxng) | Adds web search provider support. | `@openclaw/searxng-plugin`<br />included in OpenClaw | contracts: webSearchProviders |
|
||||
| [senseaudio](/plugins/reference/senseaudio) | Adds media understanding provider support. | `@openclaw/senseaudio-provider`<br />included in OpenClaw | contracts: mediaUnderstandingProviders |
|
||||
| [sglang](/plugins/reference/sglang) | Adds SGLang model provider support to OpenClaw. | `@openclaw/sglang-provider`<br />included in OpenClaw | providers: sglang |
|
||||
| [signal](/plugins/reference/signal) | Adds the Signal channel surface for sending and receiving OpenClaw messages. | `@openclaw/signal`<br />included in OpenClaw | channels: signal |
|
||||
| [skill-workshop](/plugins/reference/skill-workshop) | Captures repeatable workflows as workspace skills, with pending review, safe writes, and skill prompt refresh. | `@openclaw/skill-workshop`<br />included in OpenClaw | contracts: tools |
|
||||
| [slack](/plugins/reference/slack) | OpenClaw Slack channel plugin for channels, DMs, commands, and app events. | `@openclaw/slack`<br />npm; ClawHub | channels: slack |
|
||||
| [stepfun](/plugins/reference/stepfun) | Adds StepFun, StepFun Plan model provider support to OpenClaw. | `@openclaw/stepfun-provider`<br />included in OpenClaw | providers: stepfun, stepfun-plan |
|
||||
| [synology-chat](/plugins/reference/synology-chat) | Synology Chat channel plugin for OpenClaw channels and direct messages. | `@openclaw/synology-chat`<br />npm; ClawHub | channels: synology-chat |
|
||||
@@ -137,7 +138,7 @@ pnpm plugins:inventory:gen
|
||||
| [whatsapp](/plugins/reference/whatsapp) | OpenClaw WhatsApp channel plugin for WhatsApp Web chats. | `@openclaw/whatsapp`<br />ClawHub: `clawhub:@openclaw/whatsapp`; npm | channels: whatsapp |
|
||||
| [workboard](/plugins/reference/workboard) | Dashboard workboard for agent-owned issues and sessions. | `@openclaw/workboard`<br />included in OpenClaw | contracts: tools |
|
||||
| [xai](/plugins/reference/xai) | Adds xAI model provider support to OpenClaw. | `@openclaw/xai-plugin`<br />included in OpenClaw | providers: xai; contracts: imageGenerationProviders, mediaUnderstandingProviders, realtimeTranscriptionProviders, speechProviders, tools, videoGenerationProviders, webSearchProviders |
|
||||
| [xiaomi](/plugins/reference/xiaomi) | Adds Xiaomi model provider support to OpenClaw. | `@openclaw/xiaomi-provider`<br />included in OpenClaw | providers: xiaomi; contracts: speechProviders |
|
||||
| [xiaomi](/plugins/reference/xiaomi) | Adds Xiaomi MiMo pay-as-you-go and Token Plan provider support to OpenClaw. | `@openclaw/xiaomi-provider`<br />included in OpenClaw | providers: xiaomi, xiaomi-token-plan; contracts: speechProviders |
|
||||
| [zai](/plugins/reference/zai) | Adds Z.AI model provider support to OpenClaw. | `@openclaw/zai-provider`<br />included in OpenClaw | providers: zai; contracts: mediaUnderstandingProviders |
|
||||
| [zalo](/plugins/reference/zalo) | OpenClaw Zalo channel plugin for bot and webhook chats. | `@openclaw/zalo`<br />npm; ClawHub | channels: zalo |
|
||||
| [zalouser](/plugins/reference/zalouser) | OpenClaw Zalo Personal Account plugin via native zca-js integration. | `@openclaw/zalouser`<br />npm; ClawHub | channels: zalouser; contracts: tools |
|
||||
|
||||
@@ -18,6 +18,10 @@ Supervise Codex app-server sessions from OpenClaw.
|
||||
|
||||
contracts: tools
|
||||
|
||||
<!-- openclaw-plugin-reference:manual-start -->
|
||||
|
||||
## Session Listing
|
||||
|
||||
`codex_sessions_list` defaults to loaded Codex sessions only. Set `include_stored` to include stored history; the plugin uses Codex app-server's state-DB-only listing path and caps stored results at 200 by default. Pass `max_stored_sessions` to lower or raise that cap, up to 1000.
|
||||
|
||||
<!-- openclaw-plugin-reference:manual-end -->
|
||||
|
||||
23
docs/plugins/reference/gmi.md
Normal file
23
docs/plugins/reference/gmi.md
Normal file
@@ -0,0 +1,23 @@
|
||||
---
|
||||
summary: "Adds Gmi, Gmi Cloud, Gmicloud model provider support to OpenClaw."
|
||||
read_when:
|
||||
- You are installing, configuring, or auditing the gmi plugin
|
||||
title: "Gmi plugin"
|
||||
---
|
||||
|
||||
# Gmi plugin
|
||||
|
||||
Adds Gmi, Gmi Cloud, Gmicloud model provider support to OpenClaw.
|
||||
|
||||
## Distribution
|
||||
|
||||
- Package: `@openclaw/gmi-provider`
|
||||
- Install route: included in OpenClaw
|
||||
|
||||
## Surface
|
||||
|
||||
providers: gmi, gmi-cloud, gmicloud
|
||||
|
||||
## Related docs
|
||||
|
||||
- [gmi](/providers/gmi)
|
||||
23
docs/plugins/reference/novita.md
Normal file
23
docs/plugins/reference/novita.md
Normal file
@@ -0,0 +1,23 @@
|
||||
---
|
||||
summary: "Adds Novita, Novita AI, Novitaai model provider support to OpenClaw."
|
||||
read_when:
|
||||
- You are installing, configuring, or auditing the novita plugin
|
||||
title: "Novita plugin"
|
||||
---
|
||||
|
||||
# Novita plugin
|
||||
|
||||
Adds Novita, Novita AI, Novitaai model provider support to OpenClaw.
|
||||
|
||||
## Distribution
|
||||
|
||||
- Package: `@openclaw/novita-provider`
|
||||
- Install route: included in OpenClaw
|
||||
|
||||
## Surface
|
||||
|
||||
providers: novita, novita-ai, novitaai
|
||||
|
||||
## Related docs
|
||||
|
||||
- [novita](/providers/novita)
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
summary: "Adds Ollama model provider support to OpenClaw."
|
||||
summary: "Adds Ollama, Ollama Cloud model provider support to OpenClaw."
|
||||
read_when:
|
||||
- You are installing, configuring, or auditing the ollama plugin
|
||||
title: "Ollama plugin"
|
||||
@@ -7,7 +7,7 @@ title: "Ollama plugin"
|
||||
|
||||
# Ollama plugin
|
||||
|
||||
Adds Ollama model provider support to OpenClaw.
|
||||
Adds Ollama, Ollama Cloud model provider support to OpenClaw.
|
||||
|
||||
## Distribution
|
||||
|
||||
@@ -16,7 +16,7 @@ Adds Ollama model provider support to OpenClaw.
|
||||
|
||||
## Surface
|
||||
|
||||
providers: ollama; contracts: memoryEmbeddingProviders, webSearchProviders
|
||||
providers: ollama, ollama-cloud; contracts: memoryEmbeddingProviders, webSearchProviders
|
||||
|
||||
## Related docs
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ Adds OpenAI, OpenAI Codex model provider support to OpenClaw.
|
||||
|
||||
## Surface
|
||||
|
||||
providers: openai, openai-codex; contracts: imageGenerationProviders, mediaUnderstandingProviders, memoryEmbeddingProviders, realtimeTranscriptionProviders, realtimeVoiceProviders, speechProviders, videoGenerationProviders
|
||||
providers: openai; contracts: imageGenerationProviders, mediaUnderstandingProviders, memoryEmbeddingProviders, realtimeTranscriptionProviders, realtimeVoiceProviders, speechProviders, videoGenerationProviders
|
||||
|
||||
## Related docs
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
summary: "Adds Qwen, Qwen Cloud, Model Studio, DashScope model provider support to OpenClaw."
|
||||
summary: "Adds Qwen, Qwen Cloud, Model Studio, DashScope, Qwen Oauth, Qwen Portal, Qwen CLI model provider support to OpenClaw."
|
||||
read_when:
|
||||
- You are installing, configuring, or auditing the qwen plugin
|
||||
title: "Qwen plugin"
|
||||
@@ -7,7 +7,7 @@ title: "Qwen plugin"
|
||||
|
||||
# Qwen plugin
|
||||
|
||||
Adds Qwen, Qwen Cloud, Model Studio, DashScope model provider support to OpenClaw.
|
||||
Adds Qwen, Qwen Cloud, Model Studio, DashScope, Qwen Oauth, Qwen Portal, Qwen CLI model provider support to OpenClaw.
|
||||
|
||||
## Distribution
|
||||
|
||||
@@ -16,7 +16,7 @@ Adds Qwen, Qwen Cloud, Model Studio, DashScope model provider support to OpenCla
|
||||
|
||||
## Surface
|
||||
|
||||
providers: qwen, qwencloud, modelstudio, dashscope; contracts: mediaUnderstandingProviders, videoGenerationProviders
|
||||
providers: qwen, qwencloud, modelstudio, dashscope, qwen-oauth, qwen-portal, qwen-cli; contracts: mediaUnderstandingProviders, videoGenerationProviders
|
||||
|
||||
## Related docs
|
||||
|
||||
|
||||
@@ -1,23 +0,0 @@
|
||||
---
|
||||
summary: "Captures repeatable workflows as workspace skills, with pending review, safe writes, and skill prompt refresh."
|
||||
read_when:
|
||||
- You are installing, configuring, or auditing the skill-workshop plugin
|
||||
title: "Skill Workshop plugin"
|
||||
---
|
||||
|
||||
# Skill Workshop plugin
|
||||
|
||||
Captures repeatable workflows as workspace skills, with pending review, safe writes, and skill prompt refresh.
|
||||
|
||||
## Distribution
|
||||
|
||||
- Package: `@openclaw/skill-workshop`
|
||||
- Install route: included in OpenClaw
|
||||
|
||||
## Surface
|
||||
|
||||
contracts: tools
|
||||
|
||||
## Related docs
|
||||
|
||||
- [skill-workshop](/plugins/skill-workshop)
|
||||
@@ -1,5 +1,5 @@
|
||||
---
|
||||
summary: "Adds Xiaomi model provider support to OpenClaw."
|
||||
summary: "Adds Xiaomi MiMo pay-as-you-go and Token Plan provider support to OpenClaw."
|
||||
read_when:
|
||||
- You are installing, configuring, or auditing the xiaomi plugin
|
||||
title: "Xiaomi plugin"
|
||||
@@ -7,7 +7,7 @@ title: "Xiaomi plugin"
|
||||
|
||||
# Xiaomi plugin
|
||||
|
||||
Adds Xiaomi model provider support to OpenClaw.
|
||||
Adds Xiaomi MiMo pay-as-you-go and Token Plan provider support to OpenClaw.
|
||||
|
||||
## Distribution
|
||||
|
||||
@@ -16,7 +16,7 @@ Adds Xiaomi model provider support to OpenClaw.
|
||||
|
||||
## Surface
|
||||
|
||||
providers: xiaomi; contracts: speechProviders
|
||||
providers: xiaomi, xiaomi-token-plan; contracts: speechProviders
|
||||
|
||||
## Related docs
|
||||
|
||||
|
||||
@@ -792,6 +792,35 @@ canonical replacement.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="subagent_spawning hook → core thread binding">
|
||||
**Old**: `api.on("subagent_spawning", handler)` returning
|
||||
`threadBindingReady` or `deliveryOrigin`.
|
||||
|
||||
**New**: let core prepare `thread: true` subagent bindings through the
|
||||
channel session-binding adapter. Use `api.on("subagent_spawned", handler)`
|
||||
only for post-launch observation.
|
||||
|
||||
```typescript
|
||||
// Before
|
||||
api.on("subagent_spawning", async () => ({
|
||||
status: "ok",
|
||||
threadBindingReady: true,
|
||||
deliveryOrigin: { channel: "discord", to: "channel:123", threadId: "456" },
|
||||
}));
|
||||
|
||||
// After
|
||||
api.on("subagent_spawned", async (event) => {
|
||||
await observeSubagentLaunch(event);
|
||||
});
|
||||
```
|
||||
|
||||
`subagent_spawning`, `PluginHookSubagentSpawningEvent`,
|
||||
`PluginHookSubagentSpawningResult`, and
|
||||
`SubagentLifecycleHookRunner.runSubagentSpawning(...)` remain only as
|
||||
deprecated compatibility surfaces while external plugins migrate.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Provider discovery types → provider catalog types">
|
||||
Four discovery type aliases are now thin wrappers over the
|
||||
catalog-era types:
|
||||
|
||||
@@ -365,7 +365,7 @@ API key auth, and dynamic model resolution.
|
||||
| `kilocode-thinking` | Kilo reasoning wrapper on the shared proxy stream path, with `kilo/auto` and unsupported proxy reasoning ids skipping injected thinking | `kilocode` |
|
||||
| `moonshot-thinking` | Moonshot binary native-thinking payload mapping from config + `/think` level | `moonshot` |
|
||||
| `minimax-fast-mode` | MiniMax fast-mode model rewrite on the shared stream path | `minimax`, `minimax-portal` |
|
||||
| `openai-responses-defaults` | Shared native OpenAI/Codex Responses wrappers: attribution headers, `/fast`/`serviceTier`, text verbosity, native Codex web search, reasoning-compat payload shaping, and Responses context management | `openai`, `openai-codex` |
|
||||
| `openai-responses-defaults` | Shared native OpenAI/Codex Responses wrappers: attribution headers, `/fast`/`serviceTier`, text verbosity, native Codex web search, reasoning-compat payload shaping, and Responses context management | `openai` |
|
||||
| `openrouter-thinking` | OpenRouter reasoning wrapper for proxy routes, with unsupported-model/`auto` skips handled centrally | `openrouter` |
|
||||
| `tool-stream-default-on` | Default-on `tool_stream` wrapper for providers like Z.AI that want tool streaming unless explicitly disabled | `zai` |
|
||||
|
||||
|
||||
@@ -144,11 +144,11 @@ and pairing-path families.
|
||||
| `plugin-sdk/self-hosted-provider-setup` | Focused OpenAI-compatible self-hosted provider setup helpers |
|
||||
| `plugin-sdk/cli-backend` | CLI backend defaults + watchdog constants |
|
||||
| `plugin-sdk/provider-auth-runtime` | Runtime API-key resolution helpers for provider plugins |
|
||||
| `plugin-sdk/provider-oauth-runtime` | Generic provider OAuth callback types, callback-page rendering, PKCE/state helpers, and abort helpers |
|
||||
| `plugin-sdk/provider-oauth-runtime` | Generic provider OAuth callback types, callback-page rendering, PKCE/state helpers, authorization-input parsing, token-expiry helpers, and abort helpers |
|
||||
| `plugin-sdk/provider-auth-api-key` | API-key onboarding/profile-write helpers such as `upsertApiKeyProfile` |
|
||||
| `plugin-sdk/provider-auth-result` | Standard OAuth auth-result builder |
|
||||
| `plugin-sdk/provider-env-vars` | Provider auth env-var lookup helpers |
|
||||
| `plugin-sdk/provider-auth` | `createProviderApiKeyAuthMethod`, `ensureApiKeyFromOptionEnvOrPrompt`, `upsertAuthProfile`, `upsertApiKeyProfile`, `writeOAuthCredentials`, deprecated `resolveOpenClawAgentDir` compatibility export |
|
||||
| `plugin-sdk/provider-auth` | `createProviderApiKeyAuthMethod`, `ensureApiKeyFromOptionEnvOrPrompt`, `upsertAuthProfile`, `upsertApiKeyProfile`, `writeOAuthCredentials`, OpenAI Codex auth-import helpers, deprecated `resolveOpenClawAgentDir` compatibility export |
|
||||
| `plugin-sdk/provider-model-shared` | `ProviderReplayFamily`, `buildProviderReplayFamilyHooks`, `normalizeModelCompat`, shared replay-policy builders, provider-endpoint helpers, and shared model-id normalization helpers |
|
||||
| `plugin-sdk/provider-catalog-runtime` | Provider catalog augmentation runtime hook and plugin-provider registry seams for contract tests |
|
||||
| `plugin-sdk/provider-catalog-shared` | `findCatalogTemplate`, `buildSingleProviderApiKeyCatalog`, `buildManifestModelProviderConfig`, `supportsNativeStreamingUsageCompat`, `applyProviderNativeStreamingUsageCompat` |
|
||||
@@ -292,6 +292,7 @@ and pairing-path families.
|
||||
| `plugin-sdk/error-runtime` | Error graph, formatting, shared error classification helpers, `isApprovalNotFoundError` |
|
||||
| `plugin-sdk/fetch-runtime` | Wrapped fetch, proxy, EnvHttpProxyAgent option, and pinned lookup helpers |
|
||||
| `plugin-sdk/runtime-fetch` | Dispatcher-aware runtime fetch without proxy/guarded-fetch imports |
|
||||
| `plugin-sdk/inline-image-data-url-runtime` | Inline image data URL sanitizer and signature sniffing helpers without the broad media runtime surface |
|
||||
| `plugin-sdk/response-limit-runtime` | Bounded response-body reader without the broad media runtime surface |
|
||||
| `plugin-sdk/session-binding-runtime` | Current conversation binding state without configured binding routing or pairing stores |
|
||||
| `plugin-sdk/session-store-runtime` | Session-store helpers without broad config writes/maintenance imports |
|
||||
|
||||
@@ -1,713 +0,0 @@
|
||||
---
|
||||
summary: "Experimental capture of reusable procedures as workspace skills with review, approval, quarantine, and hot skill refresh"
|
||||
title: "Skill workshop plugin"
|
||||
read_when:
|
||||
- You want agents to turn corrections or reusable procedures into workspace skills
|
||||
- You are configuring procedural skill memory
|
||||
- You are debugging skill_workshop tool behavior
|
||||
- You are deciding whether to enable automatic skill creation
|
||||
---
|
||||
|
||||
Skill Workshop is **experimental**. It is disabled by default, its capture
|
||||
heuristics and reviewer prompts may change between releases, and automatic
|
||||
writes should be used only in trusted workspaces after reviewing pending-mode
|
||||
output first.
|
||||
|
||||
Skill Workshop is procedural memory for workspace skills. It lets an agent turn
|
||||
reusable workflows, user corrections, hard-won fixes, and recurring pitfalls
|
||||
into `SKILL.md` files under:
|
||||
|
||||
```text
|
||||
<workspace>/skills/<skill-name>/SKILL.md
|
||||
```
|
||||
|
||||
This is different from long-term memory:
|
||||
|
||||
- **Memory** stores facts, preferences, entities, and past context.
|
||||
- **Skills** store reusable procedures the agent should follow on future tasks.
|
||||
- **Skill Workshop** is the bridge from a useful turn to a durable workspace
|
||||
skill, with safety checks and optional approval.
|
||||
|
||||
Skill Workshop is useful when the agent learns a procedure such as:
|
||||
|
||||
- how to validate externally sourced animated GIF assets
|
||||
- how to replace screenshot assets and verify dimensions
|
||||
- how to run a repo-specific QA scenario
|
||||
- how to debug a recurring provider failure
|
||||
- how to repair a stale local workflow note
|
||||
|
||||
It is not intended for:
|
||||
|
||||
- facts like "the user likes blue"
|
||||
- broad autobiographical memory
|
||||
- raw transcript archiving
|
||||
- secrets, credentials, or hidden prompt text
|
||||
- one-off instructions that will not repeat
|
||||
|
||||
## Default state
|
||||
|
||||
The bundled plugin is **experimental** and **disabled by default** unless it is
|
||||
explicitly enabled in `plugins.entries.skill-workshop`.
|
||||
|
||||
The plugin manifest does not set `enabledByDefault: true`. The `enabled: true`
|
||||
default inside the plugin config schema applies only after the plugin entry has
|
||||
already been selected and loaded.
|
||||
|
||||
Experimental means:
|
||||
|
||||
- the plugin is supported enough for opt-in testing and dogfooding
|
||||
- proposal storage, reviewer thresholds, and capture heuristics can evolve
|
||||
- pending approval is the recommended starting mode
|
||||
- auto apply is for trusted personal/workspace setups, not shared or hostile
|
||||
input-heavy environments
|
||||
|
||||
## Enable
|
||||
|
||||
Minimal safe config:
|
||||
|
||||
```json5
|
||||
{
|
||||
plugins: {
|
||||
entries: {
|
||||
"skill-workshop": {
|
||||
enabled: true,
|
||||
config: {
|
||||
autoCapture: true,
|
||||
approvalPolicy: "pending",
|
||||
reviewMode: "hybrid",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
With this config:
|
||||
|
||||
- the `skill_workshop` tool is available
|
||||
- explicit reusable corrections are queued as pending proposals
|
||||
- threshold-based reviewer passes can propose skill updates
|
||||
- no skill file is written until a pending proposal is applied
|
||||
|
||||
Use automatic writes only in trusted workspaces:
|
||||
|
||||
```json5
|
||||
{
|
||||
plugins: {
|
||||
entries: {
|
||||
"skill-workshop": {
|
||||
enabled: true,
|
||||
config: {
|
||||
autoCapture: true,
|
||||
approvalPolicy: "auto",
|
||||
reviewMode: "hybrid",
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
`approvalPolicy: "auto"` still uses the same scanner and quarantine path. It
|
||||
does not apply proposals with critical findings.
|
||||
|
||||
## Configuration
|
||||
|
||||
| Key | Default | Range / values | Meaning |
|
||||
| -------------------- | ----------- | ------------------------------------------- | -------------------------------------------------------------------- |
|
||||
| `enabled` | `true` | boolean | Enables the plugin after the plugin entry is loaded. |
|
||||
| `autoCapture` | `true` | boolean | Enables post-turn capture/review on successful agent turns. |
|
||||
| `approvalPolicy` | `"pending"` | `"pending"`, `"auto"` | Queue proposals or write safe proposals automatically. |
|
||||
| `reviewMode` | `"hybrid"` | `"off"`, `"heuristic"`, `"llm"`, `"hybrid"` | Chooses explicit correction capture, LLM reviewer, both, or neither. |
|
||||
| `reviewInterval` | `15` | `1..200` | Run reviewer after this many successful turns. |
|
||||
| `reviewMinToolCalls` | `8` | `1..500` | Run reviewer after this many observed tool calls. |
|
||||
| `reviewTimeoutMs` | `45000` | `5000..180000` | Timeout for the embedded reviewer run. |
|
||||
| `maxPending` | `50` | `1..200` | Max pending/quarantined proposals kept per workspace. |
|
||||
| `maxSkillBytes` | `40000` | `1024..200000` | Max generated skill/support file size. |
|
||||
|
||||
Recommended profiles:
|
||||
|
||||
```json5
|
||||
// Conservative: explicit tool use only, no automatic capture.
|
||||
{
|
||||
autoCapture: false,
|
||||
approvalPolicy: "pending",
|
||||
reviewMode: "off",
|
||||
}
|
||||
```
|
||||
|
||||
```json5
|
||||
// Review-first: capture automatically, but require approval.
|
||||
{
|
||||
autoCapture: true,
|
||||
approvalPolicy: "pending",
|
||||
reviewMode: "hybrid",
|
||||
}
|
||||
```
|
||||
|
||||
```json5
|
||||
// Trusted automation: write safe proposals immediately.
|
||||
{
|
||||
autoCapture: true,
|
||||
approvalPolicy: "auto",
|
||||
reviewMode: "hybrid",
|
||||
}
|
||||
```
|
||||
|
||||
```json5
|
||||
// Low-cost: no reviewer LLM call, only explicit correction phrases.
|
||||
{
|
||||
autoCapture: true,
|
||||
approvalPolicy: "pending",
|
||||
reviewMode: "heuristic",
|
||||
}
|
||||
```
|
||||
|
||||
## Capture paths
|
||||
|
||||
Skill Workshop has three capture paths.
|
||||
|
||||
### Tool suggestions
|
||||
|
||||
The model can call `skill_workshop` directly when it sees a reusable procedure
|
||||
or when the user asks it to save/update a skill.
|
||||
|
||||
This is the most explicit path and works even with `autoCapture: false`.
|
||||
|
||||
### Heuristic capture
|
||||
|
||||
When `autoCapture` is enabled and `reviewMode` is `heuristic` or `hybrid`, the
|
||||
plugin scans successful turns for explicit user correction phrases:
|
||||
|
||||
- `next time`
|
||||
- `from now on`
|
||||
- `remember to`
|
||||
- `make sure to`
|
||||
- `always ... use/check/verify/record/save/prefer`
|
||||
- `prefer ... when/for/instead/use`
|
||||
- `when asked`
|
||||
|
||||
The heuristic creates a proposal from the latest matching user instruction. It
|
||||
uses topic hints to choose skill names for common workflows:
|
||||
|
||||
- animated GIF tasks -> `animated-gif-workflow`
|
||||
- screenshot or asset tasks -> `screenshot-asset-workflow`
|
||||
- QA or scenario tasks -> `qa-scenario-workflow`
|
||||
- GitHub PR tasks -> `github-pr-workflow`
|
||||
- fallback -> `learned-workflows`
|
||||
|
||||
Heuristic capture is intentionally narrow. It is for clear corrections and
|
||||
repeatable process notes, not for general transcript summarization.
|
||||
|
||||
### LLM reviewer
|
||||
|
||||
When `autoCapture` is enabled and `reviewMode` is `llm` or `hybrid`, the plugin
|
||||
runs a compact embedded reviewer after thresholds are reached.
|
||||
|
||||
The reviewer receives:
|
||||
|
||||
- the recent transcript text, capped to the last 12,000 characters
|
||||
- up to 12 existing workspace skills
|
||||
- up to 2,000 characters from each existing skill
|
||||
- JSON-only instructions
|
||||
|
||||
The reviewer has no tools:
|
||||
|
||||
- `disableTools: true`
|
||||
- `toolsAllow: []`
|
||||
- `disableMessageTool: true`
|
||||
|
||||
The reviewer returns either `{ "action": "none" }` or one proposal. The `action` field is `create`, `append`, or `replace` - prefer `append`/`replace` when a relevant skill already exists; use `create` only when no existing skill fits.
|
||||
|
||||
Example `create`:
|
||||
|
||||
```json
|
||||
{
|
||||
"action": "create",
|
||||
"skillName": "media-asset-qa",
|
||||
"title": "Media Asset QA",
|
||||
"reason": "Reusable animated media acceptance workflow",
|
||||
"description": "Validate externally sourced animated media before product use.",
|
||||
"body": "## Workflow\n\n- Verify true animation.\n- Record attribution.\n- Store a local approved copy.\n- Verify in product UI before final reply."
|
||||
}
|
||||
```
|
||||
|
||||
`append` adds `section` + `body`. `replace` swaps `oldText` for `newText` in the named skill.
|
||||
|
||||
## Proposal lifecycle
|
||||
|
||||
Every generated update becomes a proposal with:
|
||||
|
||||
- `id`
|
||||
- `createdAt`
|
||||
- `updatedAt`
|
||||
- `workspaceDir`
|
||||
- optional `agentId`
|
||||
- optional `sessionId`
|
||||
- `skillName`
|
||||
- `title`
|
||||
- `reason`
|
||||
- `source`: `tool`, `agent_end`, or `reviewer`
|
||||
- `status`
|
||||
- `change`
|
||||
- optional `scanFindings`
|
||||
- optional `quarantineReason`
|
||||
|
||||
Proposal statuses:
|
||||
|
||||
- `pending` - waiting for approval
|
||||
- `applied` - written to `<workspace>/skills`
|
||||
- `rejected` - rejected by operator/model
|
||||
- `quarantined` - blocked by critical scanner findings
|
||||
|
||||
State is stored per workspace under the Gateway state directory:
|
||||
|
||||
```text
|
||||
<stateDir>/skill-workshop/<workspace-hash>.json
|
||||
```
|
||||
|
||||
Pending and quarantined proposals are deduplicated by skill name and change
|
||||
payload. The store keeps the newest pending/quarantined proposals up to
|
||||
`maxPending`.
|
||||
|
||||
## Tool reference
|
||||
|
||||
The plugin registers one agent tool:
|
||||
|
||||
```text
|
||||
skill_workshop
|
||||
```
|
||||
|
||||
### `status`
|
||||
|
||||
Count proposals by state for the active workspace.
|
||||
|
||||
```json
|
||||
{ "action": "status" }
|
||||
```
|
||||
|
||||
Result shape:
|
||||
|
||||
```json
|
||||
{
|
||||
"workspaceDir": "/path/to/workspace",
|
||||
"pending": 1,
|
||||
"quarantined": 0,
|
||||
"applied": 3,
|
||||
"rejected": 0
|
||||
}
|
||||
```
|
||||
|
||||
### `list_pending`
|
||||
|
||||
List pending proposals.
|
||||
|
||||
```json
|
||||
{ "action": "list_pending" }
|
||||
```
|
||||
|
||||
To list another status:
|
||||
|
||||
```json
|
||||
{ "action": "list_pending", "status": "applied" }
|
||||
```
|
||||
|
||||
Valid `status` values:
|
||||
|
||||
- `pending`
|
||||
- `applied`
|
||||
- `rejected`
|
||||
- `quarantined`
|
||||
|
||||
### `list_quarantine`
|
||||
|
||||
List quarantined proposals.
|
||||
|
||||
```json
|
||||
{ "action": "list_quarantine" }
|
||||
```
|
||||
|
||||
Use this when automatic capture appears to do nothing and the logs mention
|
||||
`skill-workshop: quarantined <skill>`.
|
||||
|
||||
### `inspect`
|
||||
|
||||
Fetch a proposal by id.
|
||||
|
||||
```json
|
||||
{
|
||||
"action": "inspect",
|
||||
"id": "proposal-id"
|
||||
}
|
||||
```
|
||||
|
||||
### `suggest`
|
||||
|
||||
Create a proposal. With `approvalPolicy: "pending"` (default), this queues instead of writing.
|
||||
|
||||
```json
|
||||
{
|
||||
"action": "suggest",
|
||||
"skillName": "animated-gif-workflow",
|
||||
"title": "Animated GIF Workflow",
|
||||
"reason": "User established reusable GIF validation rules.",
|
||||
"description": "Validate animated GIF assets before using them.",
|
||||
"body": "## Workflow\n\n- Verify the URL resolves to image/gif.\n- Confirm it has multiple frames.\n- Record attribution and license.\n- Avoid hotlinking when a local asset is needed."
|
||||
}
|
||||
```
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Request immediate write in auto mode (apply: true)">
|
||||
|
||||
```json
|
||||
{
|
||||
"action": "suggest",
|
||||
"apply": true,
|
||||
"skillName": "animated-gif-workflow",
|
||||
"description": "Validate animated GIF assets before using them.",
|
||||
"body": "## Workflow\n\n- Verify true animation.\n- Record attribution."
|
||||
}
|
||||
```
|
||||
|
||||
With `approvalPolicy: "pending"`, `apply: true` still queues the proposal. Review it, then use
|
||||
the `apply` action after approval.
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Force pending under auto policy (apply: false)">
|
||||
|
||||
```json
|
||||
{
|
||||
"action": "suggest",
|
||||
"apply": false,
|
||||
"skillName": "screenshot-asset-workflow",
|
||||
"description": "Screenshot replacement workflow.",
|
||||
"body": "## Workflow\n\n- Verify dimensions.\n- Optimize the PNG.\n- Run the relevant gate."
|
||||
}
|
||||
```
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Append to a named section">
|
||||
|
||||
```json
|
||||
{
|
||||
"action": "suggest",
|
||||
"skillName": "qa-scenario-workflow",
|
||||
"section": "Workflow",
|
||||
"description": "QA scenario workflow.",
|
||||
"body": "- For media QA, verify generated assets render and pass final assertions."
|
||||
}
|
||||
```
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Replace exact text">
|
||||
|
||||
```json
|
||||
{
|
||||
"action": "suggest",
|
||||
"skillName": "github-pr-workflow",
|
||||
"oldText": "- Check the PR.",
|
||||
"newText": "- Check unresolved review threads, CI status, linked issues, and changed files before deciding."
|
||||
}
|
||||
```
|
||||
|
||||
</Accordion>
|
||||
</AccordionGroup>
|
||||
|
||||
### `apply`
|
||||
|
||||
Apply a pending proposal.
|
||||
|
||||
With `approvalPolicy: "pending"`, this action asks for operator approval before writing the
|
||||
workspace skill.
|
||||
|
||||
```json
|
||||
{
|
||||
"action": "apply",
|
||||
"id": "proposal-id"
|
||||
}
|
||||
```
|
||||
|
||||
`apply` refuses quarantined proposals:
|
||||
|
||||
```text
|
||||
quarantined proposal cannot be applied
|
||||
```
|
||||
|
||||
### `reject`
|
||||
|
||||
Mark a proposal rejected.
|
||||
|
||||
```json
|
||||
{
|
||||
"action": "reject",
|
||||
"id": "proposal-id"
|
||||
}
|
||||
```
|
||||
|
||||
### `write_support_file`
|
||||
|
||||
Write a supporting file inside an existing or proposed skill directory.
|
||||
|
||||
Allowed top-level support directories:
|
||||
|
||||
- `references/`
|
||||
- `templates/`
|
||||
- `scripts/`
|
||||
- `assets/`
|
||||
|
||||
Example:
|
||||
|
||||
```json
|
||||
{
|
||||
"action": "write_support_file",
|
||||
"skillName": "release-workflow",
|
||||
"relativePath": "references/checklist.md",
|
||||
"body": "# Release Checklist\n\n- Run release docs.\n- Verify changelog.\n"
|
||||
}
|
||||
```
|
||||
|
||||
Support files are workspace-scoped, path-checked, byte-limited by
|
||||
`maxSkillBytes`, scanned, and written atomically.
|
||||
|
||||
## Skill writes
|
||||
|
||||
Skill Workshop writes only under:
|
||||
|
||||
```text
|
||||
<workspace>/skills/<normalized-skill-name>/
|
||||
```
|
||||
|
||||
Skill names are normalized:
|
||||
|
||||
- lowercased
|
||||
- non `[a-z0-9_-]` runs become `-`
|
||||
- leading/trailing non-alphanumerics are removed
|
||||
- max length is 80 characters
|
||||
- final name must match `[a-z0-9][a-z0-9_-]{1,79}`
|
||||
|
||||
For `create`:
|
||||
|
||||
- if the skill does not exist, Skill Workshop writes a new `SKILL.md`
|
||||
- if it already exists, Skill Workshop appends the body to `## Workflow`
|
||||
|
||||
For `append`:
|
||||
|
||||
- if the skill exists, Skill Workshop appends to the requested section
|
||||
- if it does not exist, Skill Workshop creates a minimal skill then appends
|
||||
|
||||
For `replace`:
|
||||
|
||||
- the skill must already exist
|
||||
- `oldText` must be present exactly
|
||||
- only the first exact match is replaced
|
||||
|
||||
All writes are atomic and refresh the in-memory skills snapshot immediately, so
|
||||
the new or updated skill can become visible without a Gateway restart.
|
||||
|
||||
## Safety model
|
||||
|
||||
Skill Workshop has a safety scanner on generated `SKILL.md` content and support
|
||||
files.
|
||||
|
||||
Critical findings quarantine proposals:
|
||||
|
||||
| Rule id | Blocks content that... |
|
||||
| -------------------------------------- | --------------------------------------------------------------------- |
|
||||
| `prompt-injection-ignore-instructions` | tells the agent to ignore prior/higher instructions |
|
||||
| `prompt-injection-system` | references system prompts, developer messages, or hidden instructions |
|
||||
| `prompt-injection-tool` | encourages bypassing tool permission/approval |
|
||||
| `shell-pipe-to-shell` | includes `curl`/`wget` piped into `sh`, `bash`, or `zsh` |
|
||||
| `secret-exfiltration` | appears to send env/process env data over the network |
|
||||
|
||||
Warn findings are retained but do not block by themselves:
|
||||
|
||||
| Rule id | Warns on... |
|
||||
| -------------------- | -------------------------------- |
|
||||
| `destructive-delete` | broad `rm -rf` style commands |
|
||||
| `unsafe-permissions` | `chmod 777` style permission use |
|
||||
|
||||
Quarantined proposals:
|
||||
|
||||
- keep `scanFindings`
|
||||
- keep `quarantineReason`
|
||||
- appear in `list_quarantine`
|
||||
- cannot be applied through `apply`
|
||||
|
||||
To recover from a quarantined proposal, create a new safe proposal with the
|
||||
unsafe content removed. Do not edit the store JSON by hand.
|
||||
|
||||
## Prompt guidance
|
||||
|
||||
When enabled, Skill Workshop injects a short prompt section that tells the agent
|
||||
to use `skill_workshop` for durable procedural memory.
|
||||
|
||||
The guidance emphasizes:
|
||||
|
||||
- procedures, not facts/preferences
|
||||
- user corrections
|
||||
- non-obvious successful procedures
|
||||
- recurring pitfalls
|
||||
- stale/thin/wrong skill repair through append/replace
|
||||
- saving reusable procedure after long tool loops or hard fixes
|
||||
- short imperative skill text
|
||||
- no transcript dumps
|
||||
|
||||
The write mode text changes with `approvalPolicy`:
|
||||
|
||||
- pending mode: queue suggestions; use `apply` after explicit approval
|
||||
- auto mode: apply safe workspace-skill updates unless `apply: false` queues instead
|
||||
|
||||
## Costs and runtime behavior
|
||||
|
||||
Heuristic capture does not call a model.
|
||||
|
||||
LLM review uses an embedded run on the active/default agent model. It is
|
||||
threshold-based so it does not run on every turn by default.
|
||||
|
||||
The reviewer:
|
||||
|
||||
- uses the same configured provider/model context when available
|
||||
- falls back to runtime agent defaults
|
||||
- has `reviewTimeoutMs`
|
||||
- uses lightweight bootstrap context
|
||||
- has no tools
|
||||
- writes nothing directly
|
||||
- can only emit a proposal that goes through the normal scanner and
|
||||
approval/quarantine path
|
||||
|
||||
If the reviewer fails, times out, or returns invalid JSON, the plugin logs a
|
||||
warning/debug message and skips that review pass.
|
||||
|
||||
## Operating patterns
|
||||
|
||||
Use Skill Workshop when the user says:
|
||||
|
||||
- "next time, do X"
|
||||
- "from now on, prefer Y"
|
||||
- "make sure to verify Z"
|
||||
- "save this as a workflow"
|
||||
- "this took a while; remember the process"
|
||||
- "update the local skill for this"
|
||||
|
||||
Good skill text:
|
||||
|
||||
```markdown
|
||||
## Workflow
|
||||
|
||||
- Verify the GIF URL resolves to `image/gif`.
|
||||
- Confirm the file has multiple frames.
|
||||
- Record source URL, license, and attribution.
|
||||
- Store a local copy when the asset will ship with the product.
|
||||
- Verify the local asset renders in the target UI before final reply.
|
||||
```
|
||||
|
||||
Poor skill text:
|
||||
|
||||
```markdown
|
||||
The user asked about a GIF and I searched two websites. Then one was blocked by
|
||||
Cloudflare. The final answer said to check attribution.
|
||||
```
|
||||
|
||||
Reasons the poor version should not be saved:
|
||||
|
||||
- transcript-shaped
|
||||
- not imperative
|
||||
- includes noisy one-off details
|
||||
- does not tell the next agent what to do
|
||||
|
||||
## Debugging
|
||||
|
||||
Check whether the plugin is loaded:
|
||||
|
||||
```bash
|
||||
openclaw plugins list --enabled
|
||||
```
|
||||
|
||||
Check proposal counts from an agent/tool context:
|
||||
|
||||
```json
|
||||
{ "action": "status" }
|
||||
```
|
||||
|
||||
Inspect pending proposals:
|
||||
|
||||
```json
|
||||
{ "action": "list_pending" }
|
||||
```
|
||||
|
||||
Inspect quarantined proposals:
|
||||
|
||||
```json
|
||||
{ "action": "list_quarantine" }
|
||||
```
|
||||
|
||||
Common symptoms:
|
||||
|
||||
| Symptom | Likely cause | Check |
|
||||
| ------------------------------------- | ----------------------------------------------------------------------------------- | -------------------------------------------------------------------- |
|
||||
| Tool is unavailable | Plugin entry is not enabled | `plugins.entries.skill-workshop.enabled` and `openclaw plugins list` |
|
||||
| No automatic proposal appears | `autoCapture: false`, `reviewMode: "off"`, or thresholds not met | Config, proposal status, Gateway logs |
|
||||
| Heuristic did not capture | User wording did not match correction patterns | Use explicit `skill_workshop.suggest` or enable LLM reviewer |
|
||||
| Reviewer did not create a proposal | Reviewer returned `none`, invalid JSON, or timed out | Gateway logs, `reviewTimeoutMs`, thresholds |
|
||||
| Proposal is not applied | `approvalPolicy: "pending"` | `list_pending`, then `apply` |
|
||||
| Proposal disappeared from pending | Duplicate proposal reused, max pending pruning, or was applied/rejected/quarantined | `status`, `list_pending` with status filters, `list_quarantine` |
|
||||
| Skill file exists but model misses it | Skill snapshot not refreshed or skill gating excludes it | `openclaw skills` status and workspace skill eligibility |
|
||||
|
||||
Relevant logs:
|
||||
|
||||
- `skill-workshop: queued <skill>`
|
||||
- `skill-workshop: applied <skill>`
|
||||
- `skill-workshop: quarantined <skill>`
|
||||
- `skill-workshop: heuristic capture skipped: ...`
|
||||
- `skill-workshop: reviewer skipped: ...`
|
||||
- `skill-workshop: reviewer found no update`
|
||||
|
||||
## QA scenarios
|
||||
|
||||
Repo-backed QA scenarios:
|
||||
|
||||
- `qa/scenarios/plugins/skill-workshop-animated-gif-autocreate.md`
|
||||
- `qa/scenarios/plugins/skill-workshop-pending-approval.md`
|
||||
- `qa/scenarios/plugins/skill-workshop-reviewer-autonomous.md`
|
||||
|
||||
Run the deterministic coverage:
|
||||
|
||||
```bash
|
||||
pnpm openclaw qa suite \
|
||||
--scenario skill-workshop-animated-gif-autocreate \
|
||||
--scenario skill-workshop-pending-approval \
|
||||
--concurrency 1
|
||||
```
|
||||
|
||||
Run reviewer coverage:
|
||||
|
||||
```bash
|
||||
pnpm openclaw qa suite \
|
||||
--scenario skill-workshop-reviewer-autonomous \
|
||||
--concurrency 1
|
||||
```
|
||||
|
||||
The reviewer scenario is intentionally separate because it enables
|
||||
`reviewMode: "llm"` and exercises the embedded reviewer pass.
|
||||
|
||||
## When not to enable auto apply
|
||||
|
||||
Avoid `approvalPolicy: "auto"` when:
|
||||
|
||||
- the workspace contains sensitive procedures
|
||||
- the agent is working on untrusted input
|
||||
- skills are shared across a broad team
|
||||
- you are still tuning prompts or scanner rules
|
||||
- the model frequently handles hostile web/email content
|
||||
|
||||
Use pending mode first. Switch to auto mode only after reviewing the kind of
|
||||
skills the agent proposes in that workspace.
|
||||
|
||||
## Related docs
|
||||
|
||||
- [Skills](/tools/skills)
|
||||
- [Plugins](/tools/plugin)
|
||||
- [Testing](/reference/test)
|
||||
@@ -42,14 +42,19 @@ view shows a plugin-unavailable state instead of local card data.
|
||||
Each card stores:
|
||||
|
||||
- title and notes
|
||||
- status: `backlog`, `todo`, `running`, `review`, `blocked`, or `done`
|
||||
- status: `triage`, `backlog`, `todo`, `scheduled`, `ready`, `running`,
|
||||
`review`, `blocked`, or `done`
|
||||
- priority: `low`, `normal`, `high`, or `urgent`
|
||||
- labels
|
||||
- optional agent id
|
||||
- optional linked session, run, task, or source URL
|
||||
- optional execution metadata for a Codex or Claude session started from the card
|
||||
- compact metadata for attempts, comments, links, proof, artifacts, claims, diagnostics, notifications, templates, archive state, and stale-session detection
|
||||
- recent card events such as created, moved, linked, claimed, heartbeat, attempt, proof, artifact, diagnostic, notification, archive, stale, or agent-updated changes
|
||||
- compact metadata for attempts, comments, links, proof, artifacts, automation,
|
||||
attachments, worker logs, worker protocol state, claims, diagnostics,
|
||||
notifications, templates, archive state, and stale-session detection
|
||||
- recent card events such as created, moved, linked, claimed, heartbeat,
|
||||
attempt, proof, artifact, diagnostic, notification, dispatch, archive, stale,
|
||||
or agent-updated changes
|
||||
|
||||
Cards are stored in the plugin's Gateway state. They are local to the Gateway
|
||||
state directory and move with the rest of that Gateway's OpenClaw state.
|
||||
@@ -84,27 +89,84 @@ and rolling failure count so repeated failures remain visible on the board.
|
||||
|
||||
Workboard also exposes optional agent tools for board-aware workflows:
|
||||
|
||||
- `workboard_list` lists compact cards with claim and diagnostic state.
|
||||
- `workboard_list` lists compact cards with claim and diagnostic state, with an
|
||||
optional board filter.
|
||||
- `workboard_read` returns one card plus bounded worker context built from notes,
|
||||
attempts, comments, links, proof, artifacts, and active diagnostics.
|
||||
- `workboard_claim` claims a card for the calling agent and moves backlog or todo
|
||||
cards into `running`.
|
||||
attempts, comments, links, proof, artifacts, parent results, recent assignee
|
||||
work, and active diagnostics.
|
||||
- `workboard_create` creates a card with optional parents, tenant, skills,
|
||||
board, workspace metadata, idempotency key, runtime limit, and retry budget.
|
||||
- `workboard_link` links a parent card to a child card. Children stay in `todo`
|
||||
until every parent reaches `done`; then dispatch promotion moves them to
|
||||
`ready`.
|
||||
- `workboard_claim` claims a card for the calling agent and moves backlog, todo,
|
||||
or ready cards into `running`.
|
||||
- `workboard_heartbeat` refreshes the claim heartbeat during longer runs.
|
||||
- `workboard_release` releases the claim after completion, pause, or handoff and
|
||||
can move the card to a next status.
|
||||
- `workboard_comment`, `workboard_proof`, and `workboard_unblock` let an agent
|
||||
add handoff notes, attach proof or artifact references, and move blocked work
|
||||
back to `todo`.
|
||||
- `workboard_complete` and `workboard_block` are structured lifecycle tools for
|
||||
final summaries, proof, artifacts, created-card manifests, and blocker
|
||||
reasons. Created-card manifests must reference cards linked back to the
|
||||
completed card, which keeps phantom children out of summaries.
|
||||
- `workboard_attachment_add`, `workboard_attachment_read`, and
|
||||
`workboard_attachment_delete` store small card attachments in plugin SQLite
|
||||
state, index them on the card, and expose them in worker context.
|
||||
- `workboard_worker_log` and `workboard_protocol_violation` record worker log
|
||||
lines and block cards when an automated worker stops without calling
|
||||
`workboard_complete` or `workboard_block`.
|
||||
- `workboard_board_create`, `workboard_board_archive`, and
|
||||
`workboard_board_delete` manage persisted board metadata such as display name,
|
||||
description, archive state, and default workspace.
|
||||
- `workboard_runs` returns the persisted run-attempt history stored on a card.
|
||||
- `workboard_specify` turns a rough triage or backlog card into a clarified
|
||||
`todo` card and records the specification summary on the card.
|
||||
- `workboard_decompose` fans a parent orchestration card into linked children,
|
||||
inherits board and tenant metadata, and can complete the parent with a
|
||||
created-card manifest.
|
||||
- `workboard_notify_subscribe`, `workboard_notify_list`,
|
||||
`workboard_notify_events`, `workboard_notify_advance`, and
|
||||
`workboard_notify_unsubscribe` manage notification subscriptions in plugin
|
||||
state. Event reads are replay-safe; the advance tool moves the durable cursor
|
||||
so callers can resume without losing or double-reading completed, failed, or
|
||||
stale card events.
|
||||
- `workboard_boards`, `workboard_stats`, `workboard_promote`,
|
||||
`workboard_reassign`, `workboard_reclaim`, `workboard_comment`,
|
||||
`workboard_proof`, `workboard_unblock`, and `workboard_dispatch` let an agent
|
||||
inspect board namespaces, view queue stats, recover stuck work, add handoff
|
||||
notes, attach proof or artifact references, move blocked work back to `todo`,
|
||||
and nudge dependency promotion or stale-claim cleanup.
|
||||
|
||||
Claimed cards reject agent-tool mutations from other agents unless the caller
|
||||
has the claim token returned by `workboard_claim`. Dashboard operators still use
|
||||
the normal Gateway RPC surface and can recover or reassign cards.
|
||||
|
||||
Workboard stores all durable board data through the plugin SQLite key-value
|
||||
store. Cards live in `workboard.cards`, board metadata in `workboard.boards`,
|
||||
notification subscriptions in `workboard.notify`, and attachment blobs in
|
||||
`workboard.attachments`. Run history, comments, proof, artifact references,
|
||||
attachment indexes, diagnostics, dependencies, lifecycle events, worker logs,
|
||||
protocol state, and automation metadata stay on the card record so a card export
|
||||
preserves the board narrative without inlining attachment blob contents. Each
|
||||
attachment blob must fit one 64 KiB plugin state value after JSON serialization.
|
||||
|
||||
Workboard diagnostics are computed from local card metadata. The built-in checks
|
||||
flag assigned cards that wait too long, running cards without recent heartbeat,
|
||||
blocked cards that need attention, repeated failures, done cards without proof,
|
||||
and running cards that only have a loose session link.
|
||||
|
||||
Dispatch is intentionally Gateway-local. It does not spawn arbitrary operating
|
||||
system processes; normal OpenClaw sessions still own execution. A dispatch nudge
|
||||
promotes dependency-ready cards, records dispatch metadata on ready cards,
|
||||
blocks expired claims or timed-out runs, marks board-configured triage cards as
|
||||
orchestration candidates, and leaves durable notification subscriptions for the
|
||||
caller that delivers notifications.
|
||||
|
||||
Board metadata can include orchestration settings such as `autoDecompose`,
|
||||
`autoDecomposePerDispatch`, `defaultAssignee`, and `orchestratorProfile`.
|
||||
OpenClaw records the orchestration intent and exposes it in worker context; the
|
||||
actual specification, decomposition, or session start still happens through the
|
||||
normal Workboard tools and dashboard session flow.
|
||||
|
||||
## Session lifecycle sync
|
||||
|
||||
Cards can be linked to existing dashboard sessions or to the session created
|
||||
@@ -163,8 +225,12 @@ The plugin registers Gateway RPC methods under the `workboard.*` namespace:
|
||||
- `workboard.cards.export` requires `operator.read`
|
||||
- `workboard.cards.diagnostics` requires `operator.read`
|
||||
- `workboard.cards.diagnostics.refresh` requires `operator.write`
|
||||
- create, update, move, delete, comment, link, proof, artifact, claim, heartbeat,
|
||||
release, unblock, bulk, and archive methods require `operator.write`
|
||||
- attachment list/get and notification event reads require `operator.read`
|
||||
- notification cursor advancement requires `operator.write`
|
||||
- create, update, move, delete, comment, link, dependency link, proof, artifact,
|
||||
attachment add/delete, worker log, protocol violation, claim, heartbeat,
|
||||
release, complete, block, unblock, dispatch, bulk, and archive methods require
|
||||
`operator.write`
|
||||
|
||||
Browsers connected with read-only operator access can inspect the board but
|
||||
cannot mutate cards.
|
||||
|
||||
92
docs/providers/gmi.md
Normal file
92
docs/providers/gmi.md
Normal file
@@ -0,0 +1,92 @@
|
||||
---
|
||||
summary: "Use GMI Cloud's OpenAI-compatible API with OpenClaw"
|
||||
read_when:
|
||||
- You want to run OpenClaw with GMI Cloud models
|
||||
- You need the GMI provider id, key, or endpoint
|
||||
title: "GMI Cloud"
|
||||
---
|
||||
|
||||
GMI Cloud is a hosted inference platform for frontier and open-weight models
|
||||
behind an OpenAI-compatible API. In OpenClaw it is a bundled model provider,
|
||||
which means you can select it with the provider id `gmi`, store credentials
|
||||
through normal model auth, and use model refs like
|
||||
`gmi/google/gemini-3.1-flash-lite`.
|
||||
|
||||
Use GMI when you want one API key for several hosted model families, including
|
||||
Google, Anthropic, OpenAI, DeepSeek, Moonshot, and Z.AI routes exposed by GMI's
|
||||
catalog. It is useful as a secondary provider for model fallback, for comparing
|
||||
hosted routes across vendors, or when GMI has a model available before your
|
||||
primary provider does.
|
||||
|
||||
This provider uses OpenAI-compatible chat semantics. OpenClaw owns the provider
|
||||
id, auth profile, aliases, model catalog seed, and base URL; GMI owns the live
|
||||
model availability, billing, rate limits, and any provider-side routing policy.
|
||||
|
||||
## Setup
|
||||
|
||||
Create an API key in GMI Cloud, then run:
|
||||
|
||||
```bash
|
||||
openclaw onboard --auth-choice gmi-api-key
|
||||
```
|
||||
|
||||
Or set:
|
||||
|
||||
```bash
|
||||
export GMI_API_KEY="<your-gmi-api-key>" # pragma: allowlist secret
|
||||
```
|
||||
|
||||
## Defaults
|
||||
|
||||
- Provider: `gmi`
|
||||
- Aliases: `gmi-cloud`, `gmicloud`
|
||||
- Base URL: `https://api.gmi-serving.com/v1`
|
||||
- Env var: `GMI_API_KEY`
|
||||
- Default model: `gmi/google/gemini-3.1-flash-lite`
|
||||
|
||||
## When to choose GMI
|
||||
|
||||
- You want a hosted OpenAI-compatible endpoint rather than a local model server.
|
||||
- You want to try several commercial and open-weight model families through one
|
||||
provider account.
|
||||
- You want a fallback provider with different upstream routing from OpenRouter,
|
||||
DeepInfra, Together, or the direct vendor APIs.
|
||||
- You need GMI-specific model ids, pricing, or account controls.
|
||||
|
||||
Choose the direct vendor provider instead when you need vendor-native features
|
||||
that GMI does not expose through its OpenAI-compatible route. Choose a local
|
||||
provider such as Ollama, LM Studio, vLLM, or SGLang when data locality or local
|
||||
GPU control matters more than hosted convenience.
|
||||
|
||||
## Models
|
||||
|
||||
The bundled catalog seeds commonly available GMI Cloud route ids, including:
|
||||
|
||||
- `gmi/zai-org/GLM-5.1-FP8`
|
||||
- `gmi/deepseek-ai/DeepSeek-V3.2`
|
||||
- `gmi/moonshotai/Kimi-K2.5`
|
||||
- `gmi/google/gemini-3.1-flash-lite`
|
||||
- `gmi/anthropic/claude-sonnet-4.6`
|
||||
- `gmi/openai/gpt-5.4`
|
||||
|
||||
The catalog is a seed, not a promise that every account can call every model at
|
||||
all times. Use OpenClaw's model listing command to see what the configured
|
||||
provider reports in your environment:
|
||||
|
||||
```bash
|
||||
openclaw models list --provider gmi
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- `401` or `403`: check that `GMI_API_KEY` is set for the process running
|
||||
OpenClaw, or re-run onboarding to store the key in the provider auth profile.
|
||||
- Unknown model errors: confirm the model exists in your GMI account and use the
|
||||
full `gmi/<route-id>` ref shown by `openclaw models list --provider gmi`.
|
||||
- Intermittent provider errors: try a different GMI route or configure GMI as a
|
||||
fallback rather than the only primary model provider.
|
||||
|
||||
## Related
|
||||
|
||||
- [Model providers](/concepts/model-providers)
|
||||
- [All providers](/providers/index)
|
||||
@@ -41,6 +41,7 @@ Looking for chat channel docs (WhatsApp/Telegram/Discord/Slack/Mattermost (plugi
|
||||
- [fal](/providers/fal)
|
||||
- [Fireworks](/providers/fireworks)
|
||||
- [GitHub Copilot](/providers/github-copilot)
|
||||
- [GMI Cloud](/providers/gmi)
|
||||
- [Google (Gemini)](/providers/google)
|
||||
- [Gradium](/providers/gradium)
|
||||
- [Groq (LPU inference)](/providers/groq)
|
||||
@@ -53,7 +54,9 @@ Looking for chat channel docs (WhatsApp/Telegram/Discord/Slack/Mattermost (plugi
|
||||
- [Mistral](/providers/mistral)
|
||||
- [Moonshot AI (Kimi + Kimi Coding)](/providers/moonshot)
|
||||
- [NVIDIA](/providers/nvidia)
|
||||
- [NovitaAI](/providers/novita)
|
||||
- [Ollama (cloud + local models)](/providers/ollama)
|
||||
- [Ollama Cloud](/providers/ollama-cloud)
|
||||
- [OpenAI (API + Codex)](/providers/openai)
|
||||
- [OpenCode](/providers/opencode)
|
||||
- [OpenCode Go](/providers/opencode-go)
|
||||
@@ -61,6 +64,7 @@ Looking for chat channel docs (WhatsApp/Telegram/Discord/Slack/Mattermost (plugi
|
||||
- [Perplexity (web search)](/providers/perplexity-provider)
|
||||
- [Qianfan](/providers/qianfan)
|
||||
- [Qwen Cloud](/providers/qwen)
|
||||
- [Qwen OAuth / Portal](/providers/qwen-oauth)
|
||||
- [Runway](/providers/runway)
|
||||
- [SenseAudio](/providers/senseaudio)
|
||||
- [SGLang (local models)](/providers/sglang)
|
||||
|
||||
92
docs/providers/novita.md
Normal file
92
docs/providers/novita.md
Normal file
@@ -0,0 +1,92 @@
|
||||
---
|
||||
summary: "Use NovitaAI's OpenAI-compatible API with OpenClaw"
|
||||
read_when:
|
||||
- You want to run OpenClaw with NovitaAI models
|
||||
- You need the Novita provider id, key, or endpoint
|
||||
title: "NovitaAI"
|
||||
---
|
||||
|
||||
NovitaAI is a hosted AI infrastructure provider with an OpenAI-compatible model
|
||||
API. In OpenClaw it is a bundled model provider, so the provider id is
|
||||
`novita`, credentials go through the normal model auth flow, and model refs look
|
||||
like `novita/deepseek/deepseek-v3-0324`.
|
||||
|
||||
Use Novita when you want hosted access to open-weight and third-party model
|
||||
routes without running your own inference server. The bundled catalog focuses on
|
||||
chat models that are practical for agent turns, including DeepSeek, Moonshot,
|
||||
MiniMax, GLM, and Qwen routes exposed by Novita.
|
||||
|
||||
This provider uses Novita's OpenAI-compatible endpoint. OpenClaw handles
|
||||
provider registration, auth, aliases, model ref normalization, and base URL
|
||||
selection; Novita controls live model availability, account permissions,
|
||||
pricing, and rate limits.
|
||||
|
||||
## Setup
|
||||
|
||||
Create an API key at [novita.ai/settings/key-management](https://novita.ai/settings/key-management), then run:
|
||||
|
||||
```bash
|
||||
openclaw onboard --auth-choice novita-api-key
|
||||
```
|
||||
|
||||
Or set:
|
||||
|
||||
```bash
|
||||
export NOVITA_API_KEY="<your-novita-api-key>" # pragma: allowlist secret
|
||||
```
|
||||
|
||||
## Defaults
|
||||
|
||||
- Provider: `novita`
|
||||
- Aliases: `novita-ai`, `novitaai`
|
||||
- Base URL: `https://api.novita.ai/openai/v1`
|
||||
- Env var: `NOVITA_API_KEY`
|
||||
- Default model: `novita/deepseek/deepseek-v3-0324`
|
||||
|
||||
## When to choose Novita
|
||||
|
||||
- You want hosted open-weight model access with an OpenAI-compatible API.
|
||||
- You want DeepSeek, Kimi, MiniMax, GLM, or Qwen-family routes through a single
|
||||
provider account.
|
||||
- You want another hosted fallback path beside OpenRouter, GMI, DeepInfra, or
|
||||
direct vendor APIs.
|
||||
- You prefer provider-side model hosting over maintaining vLLM, SGLang, LM
|
||||
Studio, or Ollama infrastructure.
|
||||
|
||||
Choose a direct vendor provider when you need vendor-native request parameters
|
||||
or support contracts. Choose a local provider when the model must run on your
|
||||
own hardware or behind your own network boundary.
|
||||
|
||||
## Models
|
||||
|
||||
The bundled catalog seeds commonly available NovitaAI route ids, including:
|
||||
|
||||
- `novita/moonshotai/kimi-k2.5`
|
||||
- `novita/minimax/minimax-m2.7`
|
||||
- `novita/zai-org/glm-5`
|
||||
- `novita/deepseek/deepseek-v3-0324`
|
||||
- `novita/deepseek/deepseek-r1-0528`
|
||||
- `novita/qwen/qwen3-235b-a22b-fp8`
|
||||
|
||||
The catalog is a starting point for OpenClaw model selection. Your account,
|
||||
region, or Novita's current catalog may add, remove, or restrict routes. Check
|
||||
the provider from the CLI before setting a long-lived default:
|
||||
|
||||
```bash
|
||||
openclaw models list --provider novita
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- `401` or `403`: verify the key in Novita's key management page and re-run
|
||||
`openclaw onboard --auth-choice novita-api-key` if the stored profile is
|
||||
stale.
|
||||
- Unknown model errors: use the exact `novita/<route-id>` returned by
|
||||
`openclaw models list --provider novita`.
|
||||
- Slow or failed routes: try another Novita model route or set Novita as a
|
||||
fallback provider for workloads that can tolerate provider-specific variance.
|
||||
|
||||
## Related
|
||||
|
||||
- [Model providers](/concepts/model-providers)
|
||||
- [All providers](/providers/index)
|
||||
115
docs/providers/ollama-cloud.md
Normal file
115
docs/providers/ollama-cloud.md
Normal file
@@ -0,0 +1,115 @@
|
||||
---
|
||||
summary: "Use Ollama Cloud directly with OpenClaw"
|
||||
read_when:
|
||||
- You want to use hosted Ollama models without a local Ollama server
|
||||
- You need the ollama-cloud provider id, key, or endpoint
|
||||
title: "Ollama Cloud"
|
||||
---
|
||||
|
||||
Ollama Cloud is Ollama's hosted model API. It lets OpenClaw call Ollama-hosted
|
||||
models directly, without installing a local Ollama server or signing a local
|
||||
Ollama app into cloud mode. Use provider id `ollama-cloud` and model refs like
|
||||
`ollama-cloud/kimi-k2.6`.
|
||||
|
||||
This page is for direct cloud-only routing. The provider uses Ollama's native
|
||||
`/api/chat` style, not the OpenAI-compatible `/v1` route. OpenClaw registers it
|
||||
as a separate provider id so cloud-only credentials, live catalog discovery, and
|
||||
model selection do not get mixed with a local `ollama` host.
|
||||
|
||||
Use this page when you want cloud-only routing. For local Ollama, hybrid
|
||||
cloud-plus-local routing, embeddings, and custom host details, see
|
||||
[Ollama](/providers/ollama).
|
||||
|
||||
## Setup
|
||||
|
||||
Create an Ollama Cloud API key at [ollama.com/settings/keys](https://ollama.com/settings/keys), then run:
|
||||
|
||||
```bash
|
||||
openclaw onboard --auth-choice ollama-cloud
|
||||
```
|
||||
|
||||
Or set:
|
||||
|
||||
```bash
|
||||
export OLLAMA_API_KEY="<your-ollama-cloud-api-key>" # pragma: allowlist secret
|
||||
```
|
||||
|
||||
## Defaults
|
||||
|
||||
- Provider: `ollama-cloud`
|
||||
- Base URL: `https://ollama.com`
|
||||
- Env var: `OLLAMA_API_KEY`
|
||||
- API style: Ollama native `/api/chat`
|
||||
- Example model: `ollama-cloud/kimi-k2.6`
|
||||
|
||||
## When to choose Ollama Cloud
|
||||
|
||||
- You want hosted Ollama models without running `ollama serve` locally.
|
||||
- You want the same native Ollama chat API shape OpenClaw uses for local
|
||||
Ollama, but pointed at `https://ollama.com`.
|
||||
- You want a simple cloud path for models that are already in Ollama's hosted
|
||||
catalog.
|
||||
- You do not need local model pulls, local GPU control, or LAN-only inference.
|
||||
|
||||
Use [Ollama](/providers/ollama) instead when you want local-only or
|
||||
cloud-plus-local routing through a signed-in Ollama host. Use an
|
||||
OpenAI-compatible provider instead when you need `/v1/chat/completions`
|
||||
semantics or provider-specific OpenAI-style features.
|
||||
|
||||
## Models
|
||||
|
||||
OpenClaw discovers Ollama Cloud models from the live hosted catalog. Commonly
|
||||
available hosted ids include:
|
||||
|
||||
- `ollama-cloud/gpt-oss:20b`
|
||||
- `ollama-cloud/kimi-k2.6`
|
||||
- `ollama-cloud/deepseek-v4-flash`
|
||||
- `ollama-cloud/minimax-m2.7`
|
||||
- `ollama-cloud/glm-5`
|
||||
|
||||
Use a model id from your current hosted catalog:
|
||||
|
||||
```bash
|
||||
openclaw models list --provider ollama-cloud
|
||||
openclaw models set ollama-cloud/kimi-k2.6
|
||||
```
|
||||
|
||||
Model ids are cloud catalog ids, not local pull names. If a model name works in
|
||||
a local Ollama host but is absent from the hosted catalog, use the `ollama`
|
||||
provider with that local host instead.
|
||||
|
||||
## Live test
|
||||
|
||||
For Ollama Cloud API-key smoke tests, point the Ollama live test at the hosted
|
||||
endpoint and choose a model from your current catalog:
|
||||
|
||||
```bash
|
||||
export OLLAMA_API_KEY="<your-ollama-cloud-api-key>" # pragma: allowlist secret
|
||||
|
||||
OPENCLAW_LIVE_TEST=1 \
|
||||
OPENCLAW_LIVE_OLLAMA=1 \
|
||||
OPENCLAW_LIVE_OLLAMA_BASE_URL=https://ollama.com \
|
||||
OPENCLAW_LIVE_OLLAMA_MODEL=kimi-k2.6 \
|
||||
OPENCLAW_LIVE_OLLAMA_WEB_SEARCH=1 \
|
||||
pnpm test:live -- extensions/ollama/ollama.live.test.ts
|
||||
```
|
||||
|
||||
The cloud smoke runs text, native stream, and web search. It skips embeddings by
|
||||
default for `https://ollama.com` because Ollama Cloud API keys may not authorize
|
||||
`/api/embed`.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- `Set OLLAMA_API_KEY` errors: provide a real cloud API key. The local
|
||||
`ollama-local` marker is only for local or private Ollama hosts.
|
||||
- Unknown model errors: run `openclaw models list --provider ollama-cloud` and
|
||||
copy the hosted model id exactly.
|
||||
- Tool-call or raw JSON issues on custom Ollama hosts: check whether you are
|
||||
accidentally using an OpenAI-compatible `/v1` URL. Ollama routes should use
|
||||
the native base URL with no `/v1` suffix.
|
||||
|
||||
## Related
|
||||
|
||||
- [Ollama](/providers/ollama)
|
||||
- [Model providers](/concepts/model-providers)
|
||||
- [All providers](/providers/index)
|
||||
@@ -9,6 +9,12 @@ title: "Ollama"
|
||||
|
||||
OpenClaw integrates with Ollama's native API (`/api/chat`) for hosted cloud models and local/self-hosted Ollama servers. You can use Ollama in three modes: `Cloud + Local` through a reachable Ollama host, `Cloud only` against `https://ollama.com`, or `Local only` against a reachable Ollama host.
|
||||
|
||||
OpenClaw also registers `ollama-cloud` as a first-class hosted provider id for
|
||||
direct Ollama Cloud use. Use refs like `ollama-cloud/kimi-k2.5:cloud` when you
|
||||
want cloud-only routing without sharing the local `ollama` provider id.
|
||||
|
||||
For the dedicated cloud-only setup page, see [Ollama Cloud](/providers/ollama-cloud).
|
||||
|
||||
<Warning>
|
||||
**Remote Ollama users**: Do not use the `/v1` OpenAI-compatible URL (`http://host:11434/v1`) with OpenClaw. This breaks tool calling and models may output raw tool JSON as plain text. Use the native Ollama API URL instead: `baseUrl: "http://host:11434"` (no `/v1`).
|
||||
</Warning>
|
||||
@@ -22,7 +28,7 @@ Ollama provider config uses `baseUrl` as the canonical key. OpenClaw also accept
|
||||
Local and LAN Ollama hosts do not need a real bearer token. OpenClaw uses the local `ollama-local` marker only for loopback, private-network, `.local`, and bare-hostname Ollama base URLs.
|
||||
</Accordion>
|
||||
<Accordion title="Remote and Ollama Cloud hosts">
|
||||
Remote public hosts and Ollama Cloud (`https://ollama.com`) require a real credential through `OLLAMA_API_KEY`, an auth profile, or the provider's `apiKey`.
|
||||
Remote public hosts and Ollama Cloud (`https://ollama.com`) require a real credential through `OLLAMA_API_KEY`, an auth profile, or the provider's `apiKey`. For direct hosted use, prefer provider `ollama-cloud`.
|
||||
</Accordion>
|
||||
<Accordion title="Custom provider ids">
|
||||
Custom provider ids that set `api: "ollama"` follow the same rules. For example, an `ollama-remote` provider that points at a private LAN Ollama host can use `apiKey: "ollama-local"` and sub-agents will resolve that marker through the Ollama provider hook instead of treating it as a missing credential. Memory search can also set `agents.defaults.memorySearch.provider` to that custom provider id so embeddings use the matching Ollama endpoint.
|
||||
@@ -167,6 +173,13 @@ Choose your preferred setup method and mode.
|
||||
|
||||
The cloud model list shown during `openclaw onboard` is populated live from `https://ollama.com/api/tags`, capped at 500 entries, so the picker reflects the current hosted catalog rather than a static seed. If `ollama.com` is unreachable or returns no models at setup time, OpenClaw falls back to the previous hardcoded suggestions so onboarding still completes.
|
||||
|
||||
You can also configure the first-class cloud provider directly:
|
||||
|
||||
```bash
|
||||
openclaw onboard --auth-choice ollama-cloud
|
||||
openclaw models set ollama-cloud/kimi-k2.5:cloud
|
||||
```
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab title="Local only">
|
||||
|
||||
@@ -8,8 +8,8 @@ title: "OpenAI"
|
||||
---
|
||||
|
||||
OpenAI provides developer APIs for GPT models, and Codex is also available as a
|
||||
ChatGPT-plan coding agent through OpenAI's Codex clients. OpenClaw keeps those
|
||||
surfaces separate so config stays predictable.
|
||||
ChatGPT-plan coding agent through OpenAI's Codex clients. OpenClaw uses one
|
||||
provider id, `openai`, for both auth shapes.
|
||||
|
||||
OpenClaw uses `openai/*` as the canonical OpenAI model route. Embedded agent
|
||||
turns on OpenAI models run through the native Codex app-server runtime by
|
||||
@@ -38,7 +38,7 @@ changing config.
|
||||
| Direct API-key billing for agent models | `openai/gpt-5.5` plus a Codex-compatible API-key profile | Use `auth.order.openai` to place the backup after subscription auth. |
|
||||
| Direct API-key billing through explicit OpenClaw | `openai/gpt-5.5` plus provider/model runtime `openclaw` | Select a normal `openai` API-key profile. |
|
||||
| Latest ChatGPT Instant API alias | `openai/chat-latest` | Direct API-key only. Moving alias for experiments, not the default. |
|
||||
| ChatGPT/Codex subscription auth through OpenClaw | `openai/gpt-5.5` plus provider/model runtime `openclaw` | Select an `openai-codex` auth profile for the compatibility route. |
|
||||
| ChatGPT/Codex subscription auth through OpenClaw | `openai/gpt-5.5` plus provider/model runtime `openclaw` | Select an `openai` OAuth profile for the compatibility route. |
|
||||
| Image generation or editing | `openai/gpt-image-2` | Works with either `OPENAI_API_KEY` or OpenAI Codex OAuth. |
|
||||
| Transparent-background images | `openai/gpt-image-1.5` | Use `outputFormat=png` or `webp` and `openai.background=transparent`. |
|
||||
|
||||
@@ -46,20 +46,20 @@ changing config.
|
||||
|
||||
The names are similar but not interchangeable:
|
||||
|
||||
| Name you see | Layer | Meaning |
|
||||
| --------------------------------------- | -------------------------- | -------------------------------------------------------------------------------------------------------------------- |
|
||||
| `openai` | Provider prefix | Canonical OpenAI model route; agent turns use the Codex runtime. |
|
||||
| `openai-codex` | Legacy auth/profile prefix | Older OpenAI Codex OAuth/subscription profile namespace. Existing profiles and `auth.order.openai-codex` still work. |
|
||||
| `codex` plugin | Plugin | Bundled OpenClaw plugin that provides native Codex app-server runtime and `/codex` chat controls. |
|
||||
| provider/model `agentRuntime.id: codex` | Agent runtime | Force the native Codex app-server harness for matching embedded turns. |
|
||||
| `/codex ...` | Chat command set | Bind/control Codex app-server threads from a conversation. |
|
||||
| `runtime: "acp", agentId: "codex"` | ACP session route | Explicit fallback path that runs Codex through ACP/acpx. |
|
||||
| Name you see | Layer | Meaning |
|
||||
| --------------------------------------- | ----------------- | ------------------------------------------------------------------------------------------------- |
|
||||
| `openai` | Provider prefix | Canonical OpenAI model route; agent turns use the Codex runtime. |
|
||||
| `openai-codex` | Legacy prefix | Older model/profile namespace. `openclaw doctor --fix` migrates it to `openai`. |
|
||||
| `codex` plugin | Plugin | Bundled OpenClaw plugin that provides native Codex app-server runtime and `/codex` chat controls. |
|
||||
| provider/model `agentRuntime.id: codex` | Agent runtime | Force the native Codex app-server harness for matching embedded turns. |
|
||||
| `/codex ...` | Chat command set | Bind/control Codex app-server threads from a conversation. |
|
||||
| `runtime: "acp", agentId: "codex"` | ACP session route | Explicit fallback path that runs Codex through ACP/acpx. |
|
||||
|
||||
This means a config can intentionally contain `openai/*` model refs while auth
|
||||
profiles still point at Codex-compatible credentials. Prefer `auth.order.openai`
|
||||
for new config; existing `openai-codex:*` profiles and `auth.order.openai-codex`
|
||||
remain supported. `openclaw doctor --fix` rewrites legacy `openai-codex/*` model
|
||||
refs to the canonical OpenAI model route.
|
||||
profiles point at either API-key or ChatGPT/Codex OAuth credentials. Use
|
||||
`auth.order.openai` for config; `openclaw doctor --fix` rewrites legacy
|
||||
`openai-codex/*` model refs, `openai-codex:*` profile ids, and
|
||||
`auth.order.openai-codex` to the canonical OpenAI route.
|
||||
|
||||
<Note>
|
||||
GPT-5.5 is available through both direct OpenAI Platform API-key access and
|
||||
@@ -72,7 +72,7 @@ direct API-key auth for an OpenAI agent model.
|
||||
<Note>
|
||||
OpenAI agent model turns require the bundled Codex app-server plugin. Explicit
|
||||
OpenClaw runtime config remains available as an opt-in compatibility route. When OpenClaw is
|
||||
explicitly selected with an `openai-codex` auth profile, OpenClaw keeps the
|
||||
explicitly selected with an `openai` OAuth profile, OpenClaw keeps the
|
||||
public model ref as `openai/*` and routes internally through the Codex-auth
|
||||
transport. Run `openclaw doctor --fix` to repair stale
|
||||
`openai-codex/*`, `codex-cli/*`, or old runtime session pins that do not come from
|
||||
@@ -84,7 +84,7 @@ explicit runtime config.
|
||||
| OpenAI capability | OpenClaw surface | Status |
|
||||
| ------------------------- | --------------------------------------------------------------------------------------------- | ---------------------------------------------------------------------- |
|
||||
| Chat / Responses | `openai/<model>` model provider | Yes |
|
||||
| Codex subscription models | `openai/<model>` with `openai-codex` OAuth | Yes |
|
||||
| Codex subscription models | `openai/<model>` with OpenAI OAuth | Yes |
|
||||
| Legacy Codex model refs | `openai-codex/<model>` or `codex-cli/<model>` | Repaired by doctor to `openai/<model>` |
|
||||
| Codex app-server harness | `openai/<model>` with omitted runtime or provider/model `agentRuntime.id: codex` | Yes |
|
||||
| Server-side web search | Native OpenAI Responses tool | Yes, when web search is enabled and no provider pinned |
|
||||
@@ -101,7 +101,7 @@ explicit runtime config.
|
||||
Control UI Talk with `talk.realtime.provider: "openai"`) goes through the
|
||||
public **OpenAI Platform Realtime API**, which is billed against OpenAI
|
||||
Platform credits rather than Codex/ChatGPT subscription quota. An account
|
||||
with healthy Codex OAuth that runs `openai-codex/*` chat models without
|
||||
with healthy OpenAI OAuth that runs Codex-backed chat models without
|
||||
issue can still hit `insufficient_quota` / "You exceeded your current
|
||||
quota" on the first Realtime turn if the same OpenAI organization has no
|
||||
Platform billing set up.
|
||||
@@ -111,10 +111,10 @@ Fix: top up Platform credits at
|
||||
for the organization backing your realtime credentials. Realtime accepts
|
||||
either a Platform `OPENAI_API_KEY` (configured via `talk.realtime.providers.openai.apiKey`
|
||||
for Control UI Talk, or `plugins.entries.voice-call.config.realtime.providers.openai.apiKey`
|
||||
for Voice Call) or an `openai-codex` OAuth profile whose underlying
|
||||
for Voice Call) or an `openai` OAuth profile whose underlying
|
||||
organization has Platform billing — both routes mint Realtime client secrets
|
||||
through the Platform API, so either way the org needs funded Platform
|
||||
credits. For chat turns you can still use `openai-codex/*` against the same
|
||||
credits. For chat turns you can still use Codex-backed `openai/*` models against the same
|
||||
OpenClaw install; Realtime is the one route that needs Platform billing.
|
||||
</Note>
|
||||
|
||||
@@ -178,14 +178,14 @@ Choose your preferred auth method and follow the setup steps.
|
||||
| ---------------------- | -------------------------- | --------------------------- | ---------------- |
|
||||
| `openai/gpt-5.5` | omitted / provider/model `agentRuntime.id: "codex"` | Codex app-server harness | Codex-compatible OpenAI profile |
|
||||
| `openai/gpt-5.4-mini` | omitted / provider/model `agentRuntime.id: "codex"` | Codex app-server harness | Codex-compatible OpenAI profile |
|
||||
| `openai/gpt-5.5` | provider/model `agentRuntime.id: "openclaw"` | OpenClaw embedded runtime | `openai` profile or selected `openai-codex` profile |
|
||||
| `openai/gpt-5.5` | provider/model `agentRuntime.id: "openclaw"` | OpenClaw embedded runtime | Selected `openai` profile |
|
||||
|
||||
<Note>
|
||||
`openai/*` agent models use the Codex app-server harness. To use API-key
|
||||
auth for an agent model, create a Codex-compatible API-key profile and order
|
||||
it with `auth.order.openai`; `OPENAI_API_KEY` remains the direct fallback for
|
||||
non-agent OpenAI API surfaces. Older `auth.order.openai-codex` entries still
|
||||
work.
|
||||
non-agent OpenAI API surfaces. Run `openclaw doctor --fix` to migrate older
|
||||
`auth.order.openai-codex` entries.
|
||||
</Note>
|
||||
|
||||
### Config example
|
||||
@@ -215,7 +215,7 @@ Choose your preferred auth method and follow the setup steps.
|
||||
model.
|
||||
|
||||
<Warning>
|
||||
OpenClaw does **not** expose `openai/gpt-5.3-codex-spark`. Live OpenAI API requests reject that direct provider route. Use `openai-codex/gpt-5.3-codex-spark` only when the Codex catalog exposes it for your signed-in account.
|
||||
OpenClaw does **not** expose `gpt-5.3-codex-spark` on the direct OpenAI API-key route. It is available only through Codex subscription catalog entries when your signed-in account exposes it.
|
||||
</Warning>
|
||||
|
||||
</Tab>
|
||||
@@ -226,19 +226,19 @@ Choose your preferred auth method and follow the setup steps.
|
||||
<Steps>
|
||||
<Step title="Run Codex OAuth">
|
||||
```bash
|
||||
openclaw onboard --auth-choice openai-codex
|
||||
openclaw onboard --auth-choice openai
|
||||
```
|
||||
|
||||
Or run OAuth directly:
|
||||
|
||||
```bash
|
||||
openclaw models auth login --provider openai-codex
|
||||
openclaw models auth login --provider openai
|
||||
```
|
||||
|
||||
For headless or callback-hostile setups, add `--device-code` to sign in with a ChatGPT device-code flow instead of the localhost browser callback:
|
||||
|
||||
```bash
|
||||
openclaw models auth login --provider openai-codex --device-code
|
||||
openclaw models auth login --provider openai --device-code
|
||||
```
|
||||
</Step>
|
||||
<Step title="Use the canonical OpenAI model route">
|
||||
@@ -252,7 +252,7 @@ Choose your preferred auth method and follow the setup steps.
|
||||
</Step>
|
||||
<Step title="Verify Codex auth is available">
|
||||
```bash
|
||||
openclaw models list --provider openai-codex
|
||||
openclaw models list --provider openai
|
||||
```
|
||||
|
||||
After the gateway is running, send `/codex status` or `/codex models`
|
||||
@@ -265,16 +265,16 @@ Choose your preferred auth method and follow the setup steps.
|
||||
| Model ref | Runtime config | Route | Auth |
|
||||
|-----------|----------------|-------|------|
|
||||
| `openai/gpt-5.5` | omitted / provider/model `agentRuntime.id: "codex"` | Native Codex app-server harness | Codex sign-in or ordered `openai` auth profile |
|
||||
| `openai/gpt-5.5` | provider/model `agentRuntime.id: "openclaw"` | OpenClaw embedded runtime with internal Codex-auth transport | Selected `openai-codex` profile |
|
||||
| `openai-codex/gpt-5.5` | repaired by doctor | Legacy route rewritten to `openai/gpt-5.5` | Existing `openai-codex` profile |
|
||||
| `openai/gpt-5.5` | provider/model `agentRuntime.id: "openclaw"` | OpenClaw embedded runtime with internal Codex-auth transport | Selected `openai` OAuth profile |
|
||||
| `openai-codex/gpt-5.5` | repaired by doctor | Legacy route rewritten to `openai/gpt-5.5` | Migrated OpenAI OAuth profile |
|
||||
| `codex-cli/gpt-5.5` | repaired by doctor | Legacy CLI route rewritten to `openai/gpt-5.5` | Codex app-server auth |
|
||||
|
||||
<Warning>
|
||||
Prefer `openai/gpt-5.5` for new subscription-backed agent config. Older
|
||||
`openai-codex/gpt-*` refs are legacy OpenClaw routes, not the native Codex runtime
|
||||
path; run `openclaw doctor --fix` when you want to migrate them to canonical
|
||||
`openai/*` refs. `openai-codex/gpt-5.3-codex-spark` is the exception for
|
||||
accounts whose Codex catalog advertises that model; direct `openai/*` and
|
||||
`openai/*` refs. `gpt-5.3-codex-spark` remains limited to accounts whose
|
||||
Codex subscription catalog advertises that model; direct OpenAI API-key and
|
||||
Azure refs for it remain suppressed.
|
||||
</Warning>
|
||||
|
||||
@@ -282,8 +282,8 @@ Choose your preferred auth method and follow the setup steps.
|
||||
The `openai-codex/*` model prefix is legacy config repaired by doctor. For
|
||||
the common subscription plus native runtime setup, sign in with Codex auth
|
||||
but keep the model ref as `openai/gpt-5.5`. New config should put OpenAI
|
||||
agent auth order under `auth.order.openai`; older `auth.order.openai-codex`
|
||||
entries remain valid.
|
||||
agent auth order under `auth.order.openai`; doctor migrates older
|
||||
`auth.order.openai-codex` entries.
|
||||
</Note>
|
||||
|
||||
### Config example
|
||||
@@ -314,7 +314,7 @@ Choose your preferred auth method and follow the setup steps.
|
||||
auth: {
|
||||
order: {
|
||||
openai: [
|
||||
"openai-codex:user@example.com",
|
||||
"openai:user@example.com",
|
||||
"openai:api-key-backup",
|
||||
],
|
||||
},
|
||||
@@ -333,7 +333,7 @@ Choose your preferred auth method and follow the setup steps.
|
||||
|
||||
```bash
|
||||
openclaw models status
|
||||
openclaw models auth list --provider openai-codex
|
||||
openclaw models auth list --provider openai
|
||||
openclaw config get agents.defaults.model --json
|
||||
openclaw config get models.providers.openai.agentRuntime --json
|
||||
```
|
||||
@@ -342,7 +342,7 @@ Choose your preferred auth method and follow the setup steps.
|
||||
|
||||
```bash
|
||||
openclaw models status --agent <id>
|
||||
openclaw models auth list --agent <id> --provider openai-codex
|
||||
openclaw models auth list --agent <id> --provider openai
|
||||
```
|
||||
|
||||
If an older config still has `openai-codex/gpt-*` or a stale OpenAI runtime
|
||||
@@ -353,25 +353,25 @@ Choose your preferred auth method and follow the setup steps.
|
||||
openclaw config validate
|
||||
```
|
||||
|
||||
If `models auth list --provider openai-codex` shows no usable profile, sign
|
||||
If `models auth list --provider openai` shows no usable profile, sign
|
||||
in again:
|
||||
|
||||
```bash
|
||||
openclaw models auth login --provider openai-codex
|
||||
openclaw models status --probe --probe-provider openai-codex
|
||||
openclaw models auth login --provider openai
|
||||
openclaw models status --probe --probe-provider openai
|
||||
```
|
||||
|
||||
Use `--profile-id` when you want multiple Codex OAuth logins in the same
|
||||
agent and later want to control them via auth ordering or `/model ...@<profileId>`:
|
||||
|
||||
```bash
|
||||
openclaw models auth login --provider openai-codex --profile-id openai-codex:ritsuko
|
||||
openclaw models auth login --provider openai-codex --profile-id openai-codex:lain
|
||||
openclaw models auth login --provider openai --profile-id openai:ritsuko
|
||||
openclaw models auth login --provider openai --profile-id openai:lain
|
||||
```
|
||||
|
||||
`openai/*` is the model route for OpenAI agent turns through Codex. The
|
||||
`openai-codex` auth/profile provider id remains accepted for existing
|
||||
profiles and CLI listing.
|
||||
`openai/*` is the model route for OpenAI agent turns through Codex. Run
|
||||
`openclaw doctor --fix` to migrate older `openai-codex` profile ids and
|
||||
order entries before relying on profile ordering.
|
||||
|
||||
### Status indicator
|
||||
|
||||
@@ -401,7 +401,7 @@ Choose your preferred auth method and follow the setup steps.
|
||||
{
|
||||
models: {
|
||||
providers: {
|
||||
"openai-codex": {
|
||||
openai: {
|
||||
models: [{ id: "gpt-5.5", contextTokens: 160000 }],
|
||||
},
|
||||
},
|
||||
@@ -431,8 +431,8 @@ runtime config or provider/model `agentRuntime.id: "codex"`, but its auth is
|
||||
still account-based. OpenClaw selects auth in this order:
|
||||
|
||||
1. Ordered OpenAI auth profiles for the agent, preferably under
|
||||
`auth.order.openai`. Existing `openai-codex:*` profiles and
|
||||
`auth.order.openai-codex` remain valid for older installs.
|
||||
`auth.order.openai`. Run `openclaw doctor --fix` to migrate older
|
||||
`openai-codex:*` profiles and `auth.order.openai-codex`.
|
||||
2. The app-server's existing account, such as a local Codex CLI ChatGPT sign-in.
|
||||
3. For local stdio app-server launches only, `CODEX_API_KEY`, then
|
||||
`OPENAI_API_KEY`, when the app-server reports no account and still requires
|
||||
@@ -509,8 +509,8 @@ Use the same `--output-format` and `--background` flags with
|
||||
`openclaw infer image edit` when starting from an input file.
|
||||
`--openai-background` remains available as an OpenAI-specific alias.
|
||||
|
||||
For Codex OAuth installs, keep the same `openai/gpt-image-2` ref. When an
|
||||
`openai-codex` OAuth profile is configured, OpenClaw resolves that stored OAuth
|
||||
For ChatGPT/Codex OAuth installs, keep the same `openai/gpt-image-2` ref. When an
|
||||
`openai` OAuth profile is configured, OpenClaw resolves that stored OAuth
|
||||
access token and sends image requests through the Codex Responses backend. It
|
||||
does not first try `OPENAI_API_KEY` or silently fall back to an API key for that
|
||||
request. Configure `models.providers.openai` explicitly with an API key,
|
||||
@@ -697,10 +697,10 @@ Legacy `plugins.entries.openai.config.personality` is still read as a compatibil
|
||||
| Prompt | `...openai.prompt` | (unset) |
|
||||
| Silence duration | `...openai.silenceDurationMs` | `800` |
|
||||
| VAD threshold | `...openai.vadThreshold` | `0.5` |
|
||||
| Auth | `...openai.apiKey`, `OPENAI_API_KEY`, or `openai-codex` OAuth | API keys connect directly; OAuth mints a Realtime transcription client secret |
|
||||
| Auth | `...openai.apiKey`, `OPENAI_API_KEY`, or `openai` OAuth | API keys connect directly; OAuth mints a Realtime transcription client secret |
|
||||
|
||||
<Note>
|
||||
Uses a WebSocket connection to `wss://api.openai.com/v1/realtime` with G.711 u-law (`g711_ulaw` / `audio/pcmu`) audio. When only `openai-codex` OAuth is configured, the Gateway mints an ephemeral Realtime transcription client secret before opening the WebSocket. This streaming provider is for Voice Call's realtime transcription path; Discord voice currently records short segments and uses the batch `tools.media.audio` transcription path instead.
|
||||
Uses a WebSocket connection to `wss://api.openai.com/v1/realtime` with G.711 u-law (`g711_ulaw` / `audio/pcmu`) audio. When only `openai` OAuth is configured, the Gateway mints an ephemeral Realtime transcription client secret before opening the WebSocket. This streaming provider is for Voice Call's realtime transcription path; Discord voice currently records short segments and uses the batch `tools.media.audio` transcription path instead.
|
||||
</Note>
|
||||
|
||||
</Accordion>
|
||||
@@ -717,7 +717,7 @@ Legacy `plugins.entries.openai.config.personality` is still read as a compatibil
|
||||
| Silence duration | `...openai.silenceDurationMs` | `500` |
|
||||
| Prefix padding | `...openai.prefixPaddingMs` | `300` |
|
||||
| Reasoning effort | `...openai.reasoningEffort` | (unset) |
|
||||
| Auth | `...openai.apiKey`, `OPENAI_API_KEY`, or `openai-codex` OAuth | Browser Talk and non-Azure backend bridges can use Codex OAuth |
|
||||
| Auth | `...openai.apiKey`, `OPENAI_API_KEY`, or `openai` OAuth | Browser Talk and non-Azure backend bridges can use OpenAI OAuth |
|
||||
|
||||
Available built-in Realtime voices for `gpt-realtime-2`: `alloy`, `ash`,
|
||||
`ballad`, `coral`, `echo`, `sage`, `shimmer`, `verse`, `marin`, `cedar`.
|
||||
@@ -740,7 +740,7 @@ Legacy `plugins.entries.openai.config.personality` is still read as a compatibil
|
||||
Control UI Talk uses OpenAI browser realtime sessions with a Gateway-minted
|
||||
ephemeral client secret and a direct browser WebRTC SDP exchange against the
|
||||
OpenAI Realtime API. When no direct OpenAI API key is configured, the
|
||||
Gateway can mint that client secret with the selected `openai-codex` OAuth
|
||||
Gateway can mint that client secret with the selected `openai` OAuth
|
||||
profile. Gateway relay and Voice Call backend realtime WebSocket bridges use
|
||||
the same OAuth fallback for native OpenAI endpoints. Maintainer live
|
||||
verification is available with
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user