mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-18 12:02:02 +08:00
Compare commits
420 Commits
v2026.5.28
...
feat/code-
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
f2f893c14a | ||
|
|
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 | ||
|
|
43658872d9 | ||
|
|
bd04d2db0d | ||
|
|
c8a733eae5 | ||
|
|
3e35f599bc | ||
|
|
914f313740 | ||
|
|
4efc48a80d | ||
|
|
ecc5601b2a | ||
|
|
14795dc0cc | ||
|
|
05dee6760d | ||
|
|
582aa1ceb2 | ||
|
|
f6e1bc393b | ||
|
|
c91d1048e4 | ||
|
|
90994a38a0 | ||
|
|
c01a0f5588 | ||
|
|
8ff61be8d6 | ||
|
|
90d569e896 | ||
|
|
d8bc71f222 | ||
|
|
f3ea2982f5 | ||
|
|
8f389de88f | ||
|
|
2bcba64906 | ||
|
|
cbd492d680 | ||
|
|
fadd275e7b | ||
|
|
35a3c064a7 | ||
|
|
91adfa1582 | ||
|
|
f3f85ae5f7 | ||
|
|
69550a9d3d | ||
|
|
5b8472b0b9 | ||
|
|
73dd36626c | ||
|
|
83905c9169 | ||
|
|
d92a0292a9 | ||
|
|
0e6937cc1b | ||
|
|
b1e5c9d7fa | ||
|
|
ba3eae5518 | ||
|
|
60673b03bc | ||
|
|
d5e8da8499 | ||
|
|
5f89fbe669 | ||
|
|
bc848b367f | ||
|
|
a6a99b923e | ||
|
|
ccad5d7b63 | ||
|
|
42b4715124 | ||
|
|
465c4cb580 | ||
|
|
37ccec0dc7 | ||
|
|
cb4d2e7bb9 | ||
|
|
41a92ae445 | ||
|
|
d7354d61b2 | ||
|
|
c57671176e | ||
|
|
44e31f7c6a | ||
|
|
63a06e312d | ||
|
|
ed9e9aab3d | ||
|
|
dfe99e9cd7 | ||
|
|
9331ac2cb0 | ||
|
|
7f28c8bd07 | ||
|
|
bafa6de76d | ||
|
|
6037a74660 | ||
|
|
f1235477de | ||
|
|
526925c509 | ||
|
|
3204efc195 | ||
|
|
2860da8cd5 | ||
|
|
8f2e520abb | ||
|
|
fe3f2bee3f | ||
|
|
a51e8a21b6 | ||
|
|
260e8e26fd | ||
|
|
196ea61ec4 | ||
|
|
49cc613021 | ||
|
|
347486a4c4 | ||
|
|
1517fe2c32 | ||
|
|
fe69df6b3a | ||
|
|
dac67b3978 | ||
|
|
a6c694da7e | ||
|
|
259d6aada8 | ||
|
|
de6aaf8e23 | ||
|
|
496e1e071f | ||
|
|
112939df60 | ||
|
|
e8cece82ef | ||
|
|
93c68c4432 | ||
|
|
2009bec87a | ||
|
|
f382a36458 | ||
|
|
45b12c0085 | ||
|
|
0b86591d9d | ||
|
|
1221414709 | ||
|
|
1c8de09ba9 | ||
|
|
7cd93f8e5c | ||
|
|
1dbde826f2 | ||
|
|
1d84255581 | ||
|
|
e1c88d4425 | ||
|
|
e69fedc8cf | ||
|
|
a841778b7b | ||
|
|
522d0f7ef5 | ||
|
|
50378c01e4 | ||
|
|
3416edf740 | ||
|
|
040f14b641 | ||
|
|
8c53d100ca | ||
|
|
5230a23202 | ||
|
|
6443d06764 | ||
|
|
6fd8cfd5bb | ||
|
|
95f9231136 | ||
|
|
e6b011823e | ||
|
|
31169ff3b4 | ||
|
|
7f09d6ae48 | ||
|
|
a7820b2f54 | ||
|
|
150673a734 | ||
|
|
b7e9272dbe | ||
|
|
0b86decf94 | ||
|
|
61e7b042b6 | ||
|
|
d10fd6b8f4 | ||
|
|
a509c48f0e | ||
|
|
057be10e5b | ||
|
|
b832975f3e | ||
|
|
26ea53cc68 |
@@ -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:]))
|
||||
@@ -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
|
||||
|
||||
@@ -21,6 +21,30 @@ function jsonGh(args) {
|
||||
return JSON.parse(gh(args));
|
||||
}
|
||||
|
||||
function githubRestJson(pathSuffix) {
|
||||
const result = execFileSync(
|
||||
"bash",
|
||||
[
|
||||
"-lc",
|
||||
[
|
||||
"set -euo pipefail",
|
||||
'token="$(gh auth token)"',
|
||||
'curl -fsS -H "Authorization: Bearer ${token}" -H "Accept: application/vnd.github+json" -H "X-GitHub-Api-Version: 2022-11-28" "${OPENCLAW_GITHUB_REST_URL}"',
|
||||
].join("\n"),
|
||||
],
|
||||
{
|
||||
encoding: "utf8",
|
||||
env: {
|
||||
...process.env,
|
||||
OPENCLAW_GITHUB_REST_URL: `https://api.github.com/repos/${repo}/${pathSuffix}`,
|
||||
},
|
||||
maxBuffer: 16 * 1024 * 1024,
|
||||
stdio: ["ignore", "pipe", "pipe"],
|
||||
},
|
||||
);
|
||||
return JSON.parse(result);
|
||||
}
|
||||
|
||||
function rate() {
|
||||
try {
|
||||
return jsonGh(["api", "rate_limit"]).resources.core;
|
||||
@@ -59,12 +83,30 @@ for (const job of parent.jobs ?? []) {
|
||||
}
|
||||
|
||||
const since = parent.createdAt;
|
||||
const runList = gh([
|
||||
"api",
|
||||
`repos/${repo}/actions/runs?per_page=100`,
|
||||
"--jq",
|
||||
`.workflow_runs[] | select(.created_at >= "${since}") | select(.name=="CI" or .name=="OpenClaw Release Checks" or .name=="Plugin Prerelease" or .name=="NPM Telegram Beta E2E" or .name=="Full Release Validation") | [.id,.name,.status,.conclusion,.head_sha,.html_url] | @tsv`,
|
||||
]).trim();
|
||||
const runsQuery = new URLSearchParams({
|
||||
per_page: "100",
|
||||
created: `>=${since}`,
|
||||
exclude_pull_requests: "true",
|
||||
});
|
||||
const childWorkflowNames = new Set([
|
||||
"CI",
|
||||
"OpenClaw Release Checks",
|
||||
"Plugin Prerelease",
|
||||
"NPM Telegram Beta E2E",
|
||||
"Full Release Validation",
|
||||
]);
|
||||
const runs = githubRestJson(`actions/runs?${runsQuery.toString()}`).workflow_runs ?? [];
|
||||
const runList = runs
|
||||
.filter(
|
||||
(run) =>
|
||||
run.created_at >= since &&
|
||||
run.head_sha === parent.headSha &&
|
||||
childWorkflowNames.has(run.name),
|
||||
)
|
||||
.map((run) =>
|
||||
[run.id, run.name, run.status, run.conclusion ?? "", run.head_sha, run.html_url].join("\t"),
|
||||
)
|
||||
.join("\n");
|
||||
|
||||
if (!runList) {
|
||||
console.log("children: none found yet");
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -9,6 +9,7 @@ queries:
|
||||
paths:
|
||||
- src
|
||||
- extensions
|
||||
- packages/net-policy/src
|
||||
|
||||
paths-ignore:
|
||||
- "**/node_modules"
|
||||
|
||||
@@ -15,7 +15,6 @@ query-filters:
|
||||
|
||||
paths:
|
||||
- src/infra/net
|
||||
- src/shared/net
|
||||
- src/agents/tools/web-fetch.ts
|
||||
- src/agents/tools/web-guarded-fetch.ts
|
||||
- src/agents/tools/web-shared.ts
|
||||
@@ -23,6 +22,7 @@ paths:
|
||||
- src/web-fetch
|
||||
- src/web/provider-runtime-shared.ts
|
||||
- packages/memory-host-sdk/src/host/ssrf-policy.ts
|
||||
- packages/net-policy/src
|
||||
|
||||
paths-ignore:
|
||||
- "**/node_modules"
|
||||
|
||||
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:
|
||||
|
||||
82
.github/workflows/ci.yml
vendored
82
.github/workflows/ci.yml
vendored
@@ -28,7 +28,7 @@ permissions:
|
||||
|
||||
concurrency:
|
||||
group: ${{ github.event_name == 'workflow_dispatch' && format('{0}-manual-v1-{1}', github.workflow, github.run_id) || (github.event_name == 'pull_request' && format('{0}-v7-{1}', github.workflow, github.event.pull_request.number) || (github.repository == 'openclaw/openclaw' && format('{0}-v7-{1}', github.workflow, github.ref) || format('{0}-v7-{1}-{2}', github.workflow, github.ref, github.sha))) }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||
cancel-in-progress: ${{ github.event_name == 'pull_request' || (github.event_name == 'push' && github.repository == 'openclaw/openclaw' && github.ref == 'refs/heads/main') }}
|
||||
|
||||
env:
|
||||
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: "true"
|
||||
@@ -466,8 +466,8 @@ jobs:
|
||||
- name: Audit production dependencies
|
||||
run: node scripts/pre-commit/pnpm-audit-prod.mjs --audit-level=high
|
||||
|
||||
# Warm the lockfile- and pnpm-pinned store once before Linux Node shards fan out.
|
||||
# On a cold key this job owns the save, so later shards restore the exact key.
|
||||
# Warm the lockfile- and pnpm-pinned store without blocking Linux Node shards.
|
||||
# On a cold key this job owns the save for later workflow runs.
|
||||
pnpm-store-warmup:
|
||||
permissions:
|
||||
contents: read
|
||||
@@ -532,9 +532,9 @@ jobs:
|
||||
build-artifacts:
|
||||
permissions:
|
||||
contents: read
|
||||
needs: [preflight, pnpm-store-warmup]
|
||||
needs: [preflight]
|
||||
if: needs.preflight.outputs.run_build_artifacts == 'true'
|
||||
runs-on: ${{ github.event_name == 'workflow_dispatch' && 'ubuntu-24.04' || (github.repository == 'openclaw/openclaw' && 'blacksmith-16vcpu-ubuntu-2404' || 'ubuntu-24.04') }}
|
||||
runs-on: ${{ github.event_name == 'workflow_dispatch' && 'ubuntu-24.04' || (github.repository == 'openclaw/openclaw' && 'blacksmith-32vcpu-ubuntu-2404' || 'ubuntu-24.04') }}
|
||||
timeout-minutes: 20
|
||||
outputs:
|
||||
channels-result: ${{ steps.built_artifact_checks.outputs['channels-result'] }}
|
||||
@@ -597,6 +597,14 @@ jobs:
|
||||
with:
|
||||
install-bun: "false"
|
||||
|
||||
- name: Restore build-all step cache
|
||||
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/llm-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/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-
|
||||
|
||||
- name: Build dist
|
||||
env:
|
||||
NODE_OPTIONS: --max-old-space-size=8192
|
||||
@@ -694,20 +702,6 @@ jobs:
|
||||
pids+=("$!")
|
||||
}
|
||||
|
||||
if [ "$RUN_GATEWAY_WATCH" = "true" ]; then
|
||||
gateway_watch_log="${RUNNER_TEMP}/gateway-watch.log"
|
||||
echo "starting gateway-watch: node scripts/check-gateway-watch-regression.mjs --skip-build --ready-timeout-ms 5000"
|
||||
if node scripts/check-gateway-watch-regression.mjs --skip-build --ready-timeout-ms 5000 >"$gateway_watch_log" 2>&1; then
|
||||
result="success"
|
||||
else
|
||||
result="failure"
|
||||
fi
|
||||
echo "::group::gateway-watch log"
|
||||
cat "$gateway_watch_log"
|
||||
echo "::endgroup::"
|
||||
results["gateway-watch"]="$result"
|
||||
fi
|
||||
|
||||
if [ "$RUN_CHANNELS" = "true" ]; then
|
||||
start_check "channels" env \
|
||||
NODE_OPTIONS=--max-old-space-size=8192 \
|
||||
@@ -722,6 +716,11 @@ jobs:
|
||||
node scripts/run-vitest.mjs run --config test/vitest/vitest.full-core-support-boundary.config.ts
|
||||
fi
|
||||
|
||||
if [ "$RUN_GATEWAY_WATCH" = "true" ]; then
|
||||
start_check "gateway-watch" \
|
||||
node scripts/check-gateway-watch-regression.mjs --skip-build --ready-timeout-ms 5000
|
||||
fi
|
||||
|
||||
for index in "${!pids[@]}"; do
|
||||
name="${names[$index]}"
|
||||
log="${logs[$index]}"
|
||||
@@ -764,7 +763,7 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
name: ${{ matrix.check_name }}
|
||||
needs: [preflight, pnpm-store-warmup]
|
||||
needs: [preflight]
|
||||
if: needs.preflight.outputs.run_checks_fast_core == 'true'
|
||||
runs-on: ${{ github.event_name == 'workflow_dispatch' && 'ubuntu-24.04' || (github.repository == 'openclaw/openclaw' && 'blacksmith-4vcpu-ubuntu-2404' || 'ubuntu-24.04') }}
|
||||
timeout-minutes: 60
|
||||
@@ -853,7 +852,7 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
name: ${{ matrix.checkName }}
|
||||
needs: [preflight, pnpm-store-warmup]
|
||||
needs: [preflight]
|
||||
if: needs.preflight.outputs.run_plugin_contracts_shards == 'true'
|
||||
runs-on: ${{ github.event_name == 'workflow_dispatch' && 'ubuntu-24.04' || (github.repository == 'openclaw/openclaw' && 'blacksmith-4vcpu-ubuntu-2404' || 'ubuntu-24.04') }}
|
||||
timeout-minutes: 60
|
||||
@@ -933,7 +932,7 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
name: ${{ matrix.checkName }}
|
||||
needs: [preflight, pnpm-store-warmup]
|
||||
needs: [preflight]
|
||||
if: needs.preflight.outputs.run_checks_fast == 'true'
|
||||
runs-on: ${{ github.event_name == 'workflow_dispatch' && 'ubuntu-24.04' || (github.repository == 'openclaw/openclaw' && 'blacksmith-4vcpu-ubuntu-2404' || 'ubuntu-24.04') }}
|
||||
timeout-minutes: 60
|
||||
@@ -1085,7 +1084,7 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
name: ${{ matrix.check_name }}
|
||||
needs: [preflight, pnpm-store-warmup]
|
||||
needs: [preflight]
|
||||
if: needs.preflight.outputs.run_checks_node_core_nondist == 'true'
|
||||
runs-on: ${{ github.event_name == 'workflow_dispatch' && 'ubuntu-24.04' || (github.repository == 'openclaw/openclaw' && (matrix.runner || 'blacksmith-8vcpu-ubuntu-2404') || 'ubuntu-24.04') }}
|
||||
timeout-minutes: 60
|
||||
@@ -1191,8 +1190,8 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
name: ${{ matrix.check_name }}
|
||||
needs: [preflight, pnpm-store-warmup]
|
||||
if: ${{ !cancelled() && always() && needs.preflight.outputs.run_check == 'true' && needs.pnpm-store-warmup.result == 'success' }}
|
||||
needs: [preflight]
|
||||
if: ${{ !cancelled() && always() && needs.preflight.outputs.run_check == 'true' }}
|
||||
runs-on: ${{ github.event_name == 'workflow_dispatch' && 'ubuntu-24.04' || (github.repository == 'openclaw/openclaw' && (matrix.runner || 'blacksmith-4vcpu-ubuntu-2404') || 'ubuntu-24.04') }}
|
||||
timeout-minutes: 20
|
||||
strategy:
|
||||
@@ -1322,8 +1321,8 @@ jobs:
|
||||
permissions:
|
||||
contents: read
|
||||
name: ${{ matrix.check_name }}
|
||||
needs: [preflight, pnpm-store-warmup]
|
||||
if: ${{ !cancelled() && always() && needs.preflight.outputs.run_check_additional == 'true' && needs.pnpm-store-warmup.result == 'success' }}
|
||||
needs: [preflight]
|
||||
if: ${{ !cancelled() && always() && needs.preflight.outputs.run_check_additional == 'true' }}
|
||||
runs-on: ${{ github.event_name == 'workflow_dispatch' && 'ubuntu-24.04' || (github.repository == 'openclaw/openclaw' && 'blacksmith-8vcpu-ubuntu-2404' || 'ubuntu-24.04') }}
|
||||
timeout-minutes: 20
|
||||
strategy:
|
||||
@@ -1404,7 +1403,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', '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/**', '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-
|
||||
|
||||
@@ -1421,10 +1420,16 @@ 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
|
||||
cache_inputs=(
|
||||
tsconfig.json \
|
||||
tsconfig.plugin-sdk.dts.json \
|
||||
packages/plugin-sdk/tsconfig.json \
|
||||
packages/llm-core/package.json \
|
||||
scripts/check-extension-package-tsc-boundary.mjs \
|
||||
scripts/prepare-extension-package-boundary-artifacts.mjs \
|
||||
scripts/write-plugin-sdk-entry-dts.ts \
|
||||
@@ -1432,6 +1437,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:
|
||||
@@ -1489,7 +1500,7 @@ jobs:
|
||||
check-docs:
|
||||
permissions:
|
||||
contents: read
|
||||
needs: [preflight, pnpm-store-warmup]
|
||||
needs: [preflight]
|
||||
if: needs.preflight.outputs.run_check_docs == 'true'
|
||||
runs-on: ${{ github.event_name == 'workflow_dispatch' && 'ubuntu-24.04' || (github.repository == 'openclaw/openclaw' && 'blacksmith-4vcpu-ubuntu-2404' || 'ubuntu-24.04') }}
|
||||
timeout-minutes: 20
|
||||
@@ -1673,6 +1684,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 \
|
||||
@@ -1681,7 +1693,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
|
||||
@@ -1793,6 +1805,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 \
|
||||
@@ -1801,7 +1814,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
|
||||
@@ -1859,6 +1872,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 \
|
||||
@@ -1867,7 +1881,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
|
||||
@@ -2114,7 +2128,7 @@ jobs:
|
||||
- macos-node
|
||||
- macos-swift
|
||||
- android
|
||||
if: ${{ !cancelled() && always() && (github.event_name != 'pull_request' || !github.event.pull_request.draft) }}
|
||||
if: ${{ !cancelled() && always() && github.event_name != 'push' && (github.event_name != 'pull_request' || !github.event.pull_request.draft) }}
|
||||
runs-on: ubuntu-24.04
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
|
||||
@@ -33,6 +33,7 @@ on:
|
||||
- "packages/plugin-package-contract/**"
|
||||
- "packages/plugin-sdk/**"
|
||||
- "packages/memory-host-sdk/**"
|
||||
- "packages/net-policy/**"
|
||||
- "src/*.ts"
|
||||
- "src/**/*.ts"
|
||||
- "src/config/**"
|
||||
@@ -301,7 +302,7 @@ jobs:
|
||||
esac
|
||||
|
||||
case "${file}" in
|
||||
src/*.ts|src/**/*.ts|extensions/*.ts|extensions/**/*.ts)
|
||||
src/*.ts|src/**/*.ts|extensions/*.ts|extensions/**/*.ts|packages/net-policy/src/*|packages/net-policy/src/**/*)
|
||||
network_runtime=true
|
||||
;;
|
||||
esac
|
||||
|
||||
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
|
||||
|
||||
@@ -72,6 +72,7 @@ Skills own workflows; root owns hard policy and routing.
|
||||
- Plugin SDK exception: shipped external API gets new API first plus named compat/deprecation, small tests/docs if useful, removal plan.
|
||||
- Migrate internal/bundled callers to modern API in the same change. Do not let internal compat become permanent architecture.
|
||||
- Channels are implementation under `src/channels/**`; plugin authors get SDK seams. Providers own auth/catalog/runtime hooks; core owns generic loop.
|
||||
- Agent run terminal state: normalize/merge via `src/agents/agent-run-terminal-outcome.ts`; do not rederive timeout/cancel precedence in projections.
|
||||
- Hot paths should carry prepared facts forward: provider id, model ref, channel id, target, capability family, attachment class. Do not rediscover with broad plugin/provider/channel/capability loaders.
|
||||
- Do not fix repeated request-time discovery with scattered caches. Move the canonical fact earlier; reuse prepared runtime objects; delete duplicate lookup branches.
|
||||
- Gateway/plugin metadata is process-stable: installs, manifests, catalogs, generated paths, bundled metadata. Changes require restart or explicit owner reload/install/doctor flow.
|
||||
@@ -92,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.
|
||||
@@ -227,6 +229,7 @@ Skills own workflows; root owns hard policy and routing.
|
||||
- Parallels: `$openclaw-parallels-smoke`; Discord roundtrip: `$parallels-discord-roundtrip`.
|
||||
- Crabbox/WebVNC human demos: keep remote desktop visible/windowed; no fullscreen remote browser unless video/capture-style output.
|
||||
- ClawSweeper ops: `$clawsweeper`. Deployed hook sessions may post one concise `#clawsweeper` note only when surprising/actionable/risky; if using message tool, reply exactly `NO_REPLY`.
|
||||
- Generated-media completions wake the requester agent first. Requester visible-reply config decides final text vs message tool; direct media send is fallback/recovery only.
|
||||
- Memory wiki prompt digest stays tiny; prefer `wiki_search` / `wiki_get`; verify contact data before use; source-class provenance for generated people facts.
|
||||
- Rebrand/migration/config warnings: run `openclaw doctor`.
|
||||
- Never edit `node_modules`.
|
||||
|
||||
96
CHANGELOG.md
96
CHANGELOG.md
@@ -2,17 +2,59 @@
|
||||
|
||||
Docs: https://docs.openclaw.ai
|
||||
|
||||
## 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
|
||||
|
||||
- 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)
|
||||
- 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.
|
||||
- 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)
|
||||
- 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.
|
||||
- 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.
|
||||
- Performance: reuse prepared provider handles, strict tool schemas, gateway runtime metadata, session maintenance config, plugin metadata, bundled skill allowlists, package-local plugin artifacts, and single-entry store writes.
|
||||
|
||||
## 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 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.
|
||||
- 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)
|
||||
- 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)
|
||||
- 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
|
||||
@@ -20,41 +62,25 @@ 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, 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 @RomneyDa.
|
||||
- Policy: add policy comparison, ingress-channel conformance, and sandbox-posture conformance checks. (#85572, #85744, #86768)
|
||||
- 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)
|
||||
|
||||
### 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, 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, and @benjamin1492.
|
||||
- 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, @xiaotian, @funmerlin, @joshavant, @eleqtrizit, @heyitsaamir, @amittell, @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)
|
||||
- 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)
|
||||
- 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)
|
||||
- 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 @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)
|
||||
- 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)
|
||||
- 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, 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)
|
||||
- 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.
|
||||
|
||||
## 2026.5.27
|
||||
|
||||
|
||||
@@ -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,11 @@
|
||||
# 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.
|
||||
|
||||
## 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"
|
||||
|
||||
@@ -1 +1,3 @@
|
||||
Maintenance update for the current OpenClaw release.
|
||||
|
||||
- Added hosted push relay defaults, realtime Talk playback, and safer WebSocket ping handling for mobile sessions.
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -361,6 +361,26 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"get_goal": {
|
||||
"emoji": "🎯",
|
||||
"title": "Get Goal",
|
||||
"detailKeys": []
|
||||
},
|
||||
"create_goal": {
|
||||
"emoji": "🎯",
|
||||
"title": "Create Goal",
|
||||
"detailKeys": [
|
||||
"objective",
|
||||
"token_budget"
|
||||
]
|
||||
},
|
||||
"update_goal": {
|
||||
"emoji": "🎯",
|
||||
"title": "Update Goal",
|
||||
"detailKeys": [
|
||||
"status"
|
||||
]
|
||||
},
|
||||
"update_plan": {
|
||||
"emoji": "🗺️",
|
||||
"title": "Update Plan",
|
||||
|
||||
@@ -556,7 +556,7 @@ public struct MessageActionParams: Codable, Sendable {
|
||||
sessionkey: String?,
|
||||
sessionid: String?,
|
||||
inboundturnkind: String? = nil,
|
||||
agentid: String?,
|
||||
agentid: String? = nil,
|
||||
toolcontext: [String: AnyCodable]?,
|
||||
idempotencykey: String)
|
||||
{
|
||||
@@ -617,7 +617,7 @@ public struct SendParams: Codable, Sendable {
|
||||
gifplayback: Bool?,
|
||||
channel: String?,
|
||||
accountid: String?,
|
||||
agentid: String?,
|
||||
agentid: String? = nil,
|
||||
replytoid: String?,
|
||||
threadid: String?,
|
||||
forcedocument: Bool?,
|
||||
@@ -765,7 +765,7 @@ public struct AgentParams: Codable, Sendable {
|
||||
|
||||
public init(
|
||||
message: String,
|
||||
agentid: String?,
|
||||
agentid: String? = nil,
|
||||
provider: String?,
|
||||
model: String?,
|
||||
to: String?,
|
||||
@@ -893,7 +893,7 @@ public struct AgentIdentityParams: Codable, Sendable {
|
||||
public let sessionkey: String?
|
||||
|
||||
public init(
|
||||
agentid: String?,
|
||||
agentid: String? = nil,
|
||||
sessionkey: String?)
|
||||
{
|
||||
self.agentid = agentid
|
||||
@@ -1617,7 +1617,7 @@ public struct SessionsListParams: Codable, Sendable {
|
||||
includelastmessage: Bool?,
|
||||
label: String?,
|
||||
spawnedby: String?,
|
||||
agentid: String?,
|
||||
agentid: String? = nil,
|
||||
search: String?)
|
||||
{
|
||||
self.limit = limit
|
||||
@@ -1741,7 +1741,7 @@ public struct SessionsResolveParams: Codable, Sendable {
|
||||
key: String?,
|
||||
sessionid: String?,
|
||||
label: String?,
|
||||
agentid: String?,
|
||||
agentid: String? = nil,
|
||||
spawnedby: String?,
|
||||
includeglobal: Bool?,
|
||||
includeunknown: Bool?)
|
||||
@@ -1825,6 +1825,7 @@ public struct SessionOperationEvent: Codable, Sendable {
|
||||
public let operation: String
|
||||
public let phase: AnyCodable
|
||||
public let sessionkey: String
|
||||
public let agentid: String?
|
||||
public let ts: Int
|
||||
public let completed: Bool?
|
||||
public let reason: String?
|
||||
@@ -1834,6 +1835,7 @@ public struct SessionOperationEvent: Codable, Sendable {
|
||||
operation: String,
|
||||
phase: AnyCodable,
|
||||
sessionkey: String,
|
||||
agentid: String? = nil,
|
||||
ts: Int,
|
||||
completed: Bool?,
|
||||
reason: String?)
|
||||
@@ -1842,6 +1844,7 @@ public struct SessionOperationEvent: Codable, Sendable {
|
||||
self.operation = operation
|
||||
self.phase = phase
|
||||
self.sessionkey = sessionkey
|
||||
self.agentid = agentid
|
||||
self.ts = ts
|
||||
self.completed = completed
|
||||
self.reason = reason
|
||||
@@ -1852,6 +1855,7 @@ public struct SessionOperationEvent: Codable, Sendable {
|
||||
case operation
|
||||
case phase
|
||||
case sessionkey = "sessionKey"
|
||||
case agentid = "agentId"
|
||||
case ts
|
||||
case completed
|
||||
case reason
|
||||
@@ -1860,68 +1864,84 @@ public struct SessionOperationEvent: Codable, Sendable {
|
||||
|
||||
public struct SessionsCompactionListParams: Codable, Sendable {
|
||||
public let key: String
|
||||
public let agentid: String?
|
||||
|
||||
public init(
|
||||
key: String)
|
||||
key: String,
|
||||
agentid: String? = nil)
|
||||
{
|
||||
self.key = key
|
||||
self.agentid = agentid
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case key
|
||||
case agentid = "agentId"
|
||||
}
|
||||
}
|
||||
|
||||
public struct SessionsCompactionGetParams: Codable, Sendable {
|
||||
public let key: String
|
||||
public let agentid: String?
|
||||
public let checkpointid: String
|
||||
|
||||
public init(
|
||||
key: String,
|
||||
agentid: String? = nil,
|
||||
checkpointid: String)
|
||||
{
|
||||
self.key = key
|
||||
self.agentid = agentid
|
||||
self.checkpointid = checkpointid
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case key
|
||||
case agentid = "agentId"
|
||||
case checkpointid = "checkpointId"
|
||||
}
|
||||
}
|
||||
|
||||
public struct SessionsCompactionBranchParams: Codable, Sendable {
|
||||
public let key: String
|
||||
public let agentid: String?
|
||||
public let checkpointid: String
|
||||
|
||||
public init(
|
||||
key: String,
|
||||
agentid: String? = nil,
|
||||
checkpointid: String)
|
||||
{
|
||||
self.key = key
|
||||
self.agentid = agentid
|
||||
self.checkpointid = checkpointid
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case key
|
||||
case agentid = "agentId"
|
||||
case checkpointid = "checkpointId"
|
||||
}
|
||||
}
|
||||
|
||||
public struct SessionsCompactionRestoreParams: Codable, Sendable {
|
||||
public let key: String
|
||||
public let agentid: String?
|
||||
public let checkpointid: String
|
||||
|
||||
public init(
|
||||
key: String,
|
||||
agentid: String? = nil,
|
||||
checkpointid: String)
|
||||
{
|
||||
self.key = key
|
||||
self.agentid = agentid
|
||||
self.checkpointid = checkpointid
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case key
|
||||
case agentid = "agentId"
|
||||
case checkpointid = "checkpointId"
|
||||
}
|
||||
}
|
||||
@@ -2046,7 +2066,7 @@ public struct SessionsCreateParams: Codable, Sendable {
|
||||
|
||||
public init(
|
||||
key: String?,
|
||||
agentid: String?,
|
||||
agentid: String? = nil,
|
||||
label: String?,
|
||||
model: String?,
|
||||
parentsessionkey: String?,
|
||||
@@ -2078,6 +2098,7 @@ public struct SessionsCreateParams: Codable, Sendable {
|
||||
|
||||
public struct SessionsSendParams: Codable, Sendable {
|
||||
public let key: String
|
||||
public let agentid: String?
|
||||
public let message: String
|
||||
public let thinking: String?
|
||||
public let attachments: [AnyCodable]?
|
||||
@@ -2086,6 +2107,7 @@ public struct SessionsSendParams: Codable, Sendable {
|
||||
|
||||
public init(
|
||||
key: String,
|
||||
agentid: String? = nil,
|
||||
message: String,
|
||||
thinking: String?,
|
||||
attachments: [AnyCodable]?,
|
||||
@@ -2093,6 +2115,7 @@ public struct SessionsSendParams: Codable, Sendable {
|
||||
idempotencykey: String?)
|
||||
{
|
||||
self.key = key
|
||||
self.agentid = agentid
|
||||
self.message = message
|
||||
self.thinking = thinking
|
||||
self.attachments = attachments
|
||||
@@ -2102,6 +2125,7 @@ public struct SessionsSendParams: Codable, Sendable {
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case key
|
||||
case agentid = "agentId"
|
||||
case message
|
||||
case thinking
|
||||
case attachments
|
||||
@@ -2112,29 +2136,37 @@ public struct SessionsSendParams: Codable, Sendable {
|
||||
|
||||
public struct SessionsMessagesSubscribeParams: Codable, Sendable {
|
||||
public let key: String
|
||||
public let agentid: String?
|
||||
|
||||
public init(
|
||||
key: String)
|
||||
key: String,
|
||||
agentid: String? = nil)
|
||||
{
|
||||
self.key = key
|
||||
self.agentid = agentid
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case key
|
||||
case agentid = "agentId"
|
||||
}
|
||||
}
|
||||
|
||||
public struct SessionsMessagesUnsubscribeParams: Codable, Sendable {
|
||||
public let key: String
|
||||
public let agentid: String?
|
||||
|
||||
public init(
|
||||
key: String)
|
||||
key: String,
|
||||
agentid: String? = nil)
|
||||
{
|
||||
self.key = key
|
||||
self.agentid = agentid
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case key
|
||||
case agentid = "agentId"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2162,6 +2194,7 @@ public struct SessionsAbortParams: Codable, Sendable {
|
||||
|
||||
public struct SessionsPatchParams: Codable, Sendable {
|
||||
public let key: String
|
||||
public let agentid: String?
|
||||
public let label: AnyCodable?
|
||||
public let thinkinglevel: AnyCodable?
|
||||
public let fastmode: AnyCodable?
|
||||
@@ -2188,6 +2221,7 @@ public struct SessionsPatchParams: Codable, Sendable {
|
||||
|
||||
public init(
|
||||
key: String,
|
||||
agentid: String? = nil,
|
||||
label: AnyCodable?,
|
||||
thinkinglevel: AnyCodable?,
|
||||
fastmode: AnyCodable?,
|
||||
@@ -2213,6 +2247,7 @@ public struct SessionsPatchParams: Codable, Sendable {
|
||||
groupactivation: AnyCodable?)
|
||||
{
|
||||
self.key = key
|
||||
self.agentid = agentid
|
||||
self.label = label
|
||||
self.thinkinglevel = thinkinglevel
|
||||
self.fastmode = fastmode
|
||||
@@ -2240,6 +2275,7 @@ public struct SessionsPatchParams: Codable, Sendable {
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case key
|
||||
case agentid = "agentId"
|
||||
case label
|
||||
case thinkinglevel = "thinkingLevel"
|
||||
case fastmode = "fastMode"
|
||||
@@ -2320,39 +2356,47 @@ public struct SessionsPluginPatchResult: Codable, Sendable {
|
||||
|
||||
public struct SessionsResetParams: Codable, Sendable {
|
||||
public let key: String
|
||||
public let agentid: String?
|
||||
public let reason: AnyCodable?
|
||||
|
||||
public init(
|
||||
key: String,
|
||||
agentid: String? = nil,
|
||||
reason: AnyCodable?)
|
||||
{
|
||||
self.key = key
|
||||
self.agentid = agentid
|
||||
self.reason = reason
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case key
|
||||
case agentid = "agentId"
|
||||
case reason
|
||||
}
|
||||
}
|
||||
|
||||
public struct SessionsDeleteParams: Codable, Sendable {
|
||||
public let key: String
|
||||
public let agentid: String?
|
||||
public let deletetranscript: Bool?
|
||||
public let emitlifecyclehooks: Bool?
|
||||
|
||||
public init(
|
||||
key: String,
|
||||
agentid: String? = nil,
|
||||
deletetranscript: Bool?,
|
||||
emitlifecyclehooks: Bool?)
|
||||
{
|
||||
self.key = key
|
||||
self.agentid = agentid
|
||||
self.deletetranscript = deletetranscript
|
||||
self.emitlifecyclehooks = emitlifecyclehooks
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case key
|
||||
case agentid = "agentId"
|
||||
case deletetranscript = "deleteTranscript"
|
||||
case emitlifecyclehooks = "emitLifecycleHooks"
|
||||
}
|
||||
@@ -2360,18 +2404,22 @@ public struct SessionsDeleteParams: Codable, Sendable {
|
||||
|
||||
public struct SessionsCompactParams: Codable, Sendable {
|
||||
public let key: String
|
||||
public let agentid: String?
|
||||
public let maxlines: Int?
|
||||
|
||||
public init(
|
||||
key: String,
|
||||
agentid: String? = nil,
|
||||
maxlines: Int?)
|
||||
{
|
||||
self.key = key
|
||||
self.agentid = agentid
|
||||
self.maxlines = maxlines
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case key
|
||||
case agentid = "agentId"
|
||||
case maxlines = "maxLines"
|
||||
}
|
||||
}
|
||||
@@ -2463,7 +2511,7 @@ public struct TaskSummary: Codable, Sendable {
|
||||
runtime: String?,
|
||||
status: AnyCodable,
|
||||
title: String?,
|
||||
agentid: String?,
|
||||
agentid: String? = nil,
|
||||
sessionkey: String?,
|
||||
childsessionkey: String?,
|
||||
ownerkey: String?,
|
||||
@@ -2537,7 +2585,7 @@ public struct TasksListParams: Codable, Sendable {
|
||||
|
||||
public init(
|
||||
status: AnyCodable?,
|
||||
agentid: String?,
|
||||
agentid: String? = nil,
|
||||
sessionkey: String?,
|
||||
limit: Int?,
|
||||
cursor: String?)
|
||||
@@ -4727,7 +4775,7 @@ public struct CommandsListParams: Codable, Sendable {
|
||||
public let includeargs: Bool?
|
||||
|
||||
public init(
|
||||
agentid: String?,
|
||||
agentid: String? = nil,
|
||||
provider: String?,
|
||||
scope: AnyCodable?,
|
||||
includeargs: Bool?)
|
||||
@@ -4764,7 +4812,7 @@ public struct SkillsStatusParams: Codable, Sendable {
|
||||
public let agentid: String?
|
||||
|
||||
public init(
|
||||
agentid: String?)
|
||||
agentid: String? = nil)
|
||||
{
|
||||
self.agentid = agentid
|
||||
}
|
||||
@@ -4779,7 +4827,7 @@ public struct ToolsCatalogParams: Codable, Sendable {
|
||||
public let includeplugins: Bool?
|
||||
|
||||
public init(
|
||||
agentid: String?,
|
||||
agentid: String? = nil,
|
||||
includeplugins: Bool?)
|
||||
{
|
||||
self.agentid = agentid
|
||||
@@ -4913,7 +4961,7 @@ public struct ToolsEffectiveParams: Codable, Sendable {
|
||||
public let sessionkey: String
|
||||
|
||||
public init(
|
||||
agentid: String?,
|
||||
agentid: String? = nil,
|
||||
sessionkey: String)
|
||||
{
|
||||
self.agentid = agentid
|
||||
@@ -5058,7 +5106,7 @@ public struct ToolsInvokeParams: Codable, Sendable {
|
||||
name: String,
|
||||
args: [String: AnyCodable]?,
|
||||
sessionkey: String?,
|
||||
agentid: String?,
|
||||
agentid: String? = nil,
|
||||
confirm: Bool?,
|
||||
idempotencykey: String?)
|
||||
{
|
||||
@@ -5232,7 +5280,7 @@ public struct SkillsSecurityVerdictsParams: Codable, Sendable {
|
||||
public let agentid: String?
|
||||
|
||||
public init(
|
||||
agentid: String?)
|
||||
agentid: String? = nil)
|
||||
{
|
||||
self.agentid = agentid
|
||||
}
|
||||
@@ -5265,7 +5313,7 @@ public struct SkillsSkillCardParams: Codable, Sendable {
|
||||
public let skillkey: String
|
||||
|
||||
public init(
|
||||
agentid: String?,
|
||||
agentid: String? = nil,
|
||||
skillkey: String)
|
||||
{
|
||||
self.agentid = agentid
|
||||
@@ -5402,7 +5450,7 @@ public struct CronJob: Codable, Sendable {
|
||||
|
||||
public init(
|
||||
id: String,
|
||||
agentid: String?,
|
||||
agentid: String? = nil,
|
||||
sessionkey: String?,
|
||||
name: String,
|
||||
description: String?,
|
||||
@@ -5478,7 +5526,7 @@ public struct CronListParams: Codable, Sendable {
|
||||
lastrunstatus: AnyCodable?,
|
||||
sortby: AnyCodable?,
|
||||
sortdir: AnyCodable?,
|
||||
agentid: String?)
|
||||
agentid: String? = nil)
|
||||
{
|
||||
self.includedisabled = includedisabled
|
||||
self.limit = limit
|
||||
@@ -5524,7 +5572,7 @@ public struct CronAddParams: Codable, Sendable {
|
||||
|
||||
public init(
|
||||
name: String,
|
||||
agentid: AnyCodable?,
|
||||
agentid: AnyCodable? = nil,
|
||||
sessionkey: AnyCodable?,
|
||||
description: String?,
|
||||
enabled: Bool?,
|
||||
@@ -5912,7 +5960,7 @@ public struct ExecApprovalRequestParams: Codable, Sendable {
|
||||
ask: AnyCodable?,
|
||||
warningtext: AnyCodable?,
|
||||
commandspans: [[String: AnyCodable]]?,
|
||||
agentid: AnyCodable?,
|
||||
agentid: AnyCodable? = nil,
|
||||
resolvedpath: AnyCodable?,
|
||||
sessionkey: AnyCodable?,
|
||||
turnsourcechannel: AnyCodable?,
|
||||
@@ -6019,7 +6067,7 @@ public struct PluginApprovalRequestParams: Codable, Sendable {
|
||||
toolname: String?,
|
||||
toolcallid: String?,
|
||||
alloweddecisions: [String]?,
|
||||
agentid: String?,
|
||||
agentid: String? = nil,
|
||||
sessionkey: String?,
|
||||
turnsourcechannel: String?,
|
||||
turnsourceto: String?,
|
||||
@@ -6480,21 +6528,25 @@ public struct DevicePairResolvedEvent: Codable, Sendable {
|
||||
|
||||
public struct ChatHistoryParams: Codable, Sendable {
|
||||
public let sessionkey: String
|
||||
public let agentid: String?
|
||||
public let limit: Int?
|
||||
public let maxchars: Int?
|
||||
|
||||
public init(
|
||||
sessionkey: String,
|
||||
agentid: String? = nil,
|
||||
limit: Int?,
|
||||
maxchars: Int?)
|
||||
{
|
||||
self.sessionkey = sessionkey
|
||||
self.agentid = agentid
|
||||
self.limit = limit
|
||||
self.maxchars = maxchars
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case sessionkey = "sessionKey"
|
||||
case agentid = "agentId"
|
||||
case limit
|
||||
case maxchars = "maxChars"
|
||||
}
|
||||
@@ -6502,6 +6554,7 @@ public struct ChatHistoryParams: Codable, Sendable {
|
||||
|
||||
public struct ChatSendParams: Codable, Sendable {
|
||||
public let sessionkey: String
|
||||
public let agentid: String?
|
||||
public let sessionid: String?
|
||||
public let message: String
|
||||
public let thinking: String?
|
||||
@@ -6519,6 +6572,7 @@ public struct ChatSendParams: Codable, Sendable {
|
||||
|
||||
public init(
|
||||
sessionkey: String,
|
||||
agentid: String? = nil,
|
||||
sessionid: String?,
|
||||
message: String,
|
||||
thinking: String?,
|
||||
@@ -6535,6 +6589,7 @@ public struct ChatSendParams: Codable, Sendable {
|
||||
idempotencykey: String)
|
||||
{
|
||||
self.sessionkey = sessionkey
|
||||
self.agentid = agentid
|
||||
self.sessionid = sessionid
|
||||
self.message = message
|
||||
self.thinking = thinking
|
||||
@@ -6553,6 +6608,7 @@ public struct ChatSendParams: Codable, Sendable {
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case sessionkey = "sessionKey"
|
||||
case agentid = "agentId"
|
||||
case sessionid = "sessionId"
|
||||
case message
|
||||
case thinking
|
||||
@@ -6572,39 +6628,47 @@ public struct ChatSendParams: Codable, Sendable {
|
||||
|
||||
public struct ChatAbortParams: Codable, Sendable {
|
||||
public let sessionkey: String
|
||||
public let agentid: String?
|
||||
public let runid: String?
|
||||
|
||||
public init(
|
||||
sessionkey: String,
|
||||
agentid: String? = nil,
|
||||
runid: String?)
|
||||
{
|
||||
self.sessionkey = sessionkey
|
||||
self.agentid = agentid
|
||||
self.runid = runid
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case sessionkey = "sessionKey"
|
||||
case agentid = "agentId"
|
||||
case runid = "runId"
|
||||
}
|
||||
}
|
||||
|
||||
public struct ChatInjectParams: Codable, Sendable {
|
||||
public let sessionkey: String
|
||||
public let agentid: String?
|
||||
public let message: String
|
||||
public let label: String?
|
||||
|
||||
public init(
|
||||
sessionkey: String,
|
||||
agentid: String? = nil,
|
||||
message: String,
|
||||
label: String?)
|
||||
{
|
||||
self.sessionkey = sessionkey
|
||||
self.agentid = agentid
|
||||
self.message = message
|
||||
self.label = label
|
||||
}
|
||||
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case sessionkey = "sessionKey"
|
||||
case agentid = "agentId"
|
||||
case message
|
||||
case label
|
||||
}
|
||||
@@ -6613,6 +6677,7 @@ public struct ChatInjectParams: Codable, Sendable {
|
||||
public struct ChatDeltaEvent: Codable, Sendable {
|
||||
public let runid: String
|
||||
public let sessionkey: String
|
||||
public let agentid: String?
|
||||
public let spawnedby: String?
|
||||
public let seq: Int
|
||||
public let state: String
|
||||
@@ -6624,6 +6689,7 @@ public struct ChatDeltaEvent: Codable, Sendable {
|
||||
public init(
|
||||
runid: String,
|
||||
sessionkey: String,
|
||||
agentid: String? = nil,
|
||||
spawnedby: String?,
|
||||
seq: Int,
|
||||
state: String,
|
||||
@@ -6634,6 +6700,7 @@ public struct ChatDeltaEvent: Codable, Sendable {
|
||||
{
|
||||
self.runid = runid
|
||||
self.sessionkey = sessionkey
|
||||
self.agentid = agentid
|
||||
self.spawnedby = spawnedby
|
||||
self.seq = seq
|
||||
self.state = state
|
||||
@@ -6646,6 +6713,7 @@ public struct ChatDeltaEvent: Codable, Sendable {
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case runid = "runId"
|
||||
case sessionkey = "sessionKey"
|
||||
case agentid = "agentId"
|
||||
case spawnedby = "spawnedBy"
|
||||
case seq
|
||||
case state
|
||||
@@ -6659,6 +6727,7 @@ public struct ChatDeltaEvent: Codable, Sendable {
|
||||
public struct ChatFinalEvent: Codable, Sendable {
|
||||
public let runid: String
|
||||
public let sessionkey: String
|
||||
public let agentid: String?
|
||||
public let spawnedby: String?
|
||||
public let seq: Int
|
||||
public let state: String
|
||||
@@ -6669,6 +6738,7 @@ public struct ChatFinalEvent: Codable, Sendable {
|
||||
public init(
|
||||
runid: String,
|
||||
sessionkey: String,
|
||||
agentid: String? = nil,
|
||||
spawnedby: String?,
|
||||
seq: Int,
|
||||
state: String,
|
||||
@@ -6678,6 +6748,7 @@ public struct ChatFinalEvent: Codable, Sendable {
|
||||
{
|
||||
self.runid = runid
|
||||
self.sessionkey = sessionkey
|
||||
self.agentid = agentid
|
||||
self.spawnedby = spawnedby
|
||||
self.seq = seq
|
||||
self.state = state
|
||||
@@ -6689,6 +6760,7 @@ public struct ChatFinalEvent: Codable, Sendable {
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case runid = "runId"
|
||||
case sessionkey = "sessionKey"
|
||||
case agentid = "agentId"
|
||||
case spawnedby = "spawnedBy"
|
||||
case seq
|
||||
case state
|
||||
@@ -6701,6 +6773,7 @@ public struct ChatFinalEvent: Codable, Sendable {
|
||||
public struct ChatAbortedEvent: Codable, Sendable {
|
||||
public let runid: String
|
||||
public let sessionkey: String
|
||||
public let agentid: String?
|
||||
public let spawnedby: String?
|
||||
public let seq: Int
|
||||
public let state: String
|
||||
@@ -6710,6 +6783,7 @@ public struct ChatAbortedEvent: Codable, Sendable {
|
||||
public init(
|
||||
runid: String,
|
||||
sessionkey: String,
|
||||
agentid: String? = nil,
|
||||
spawnedby: String?,
|
||||
seq: Int,
|
||||
state: String,
|
||||
@@ -6718,6 +6792,7 @@ public struct ChatAbortedEvent: Codable, Sendable {
|
||||
{
|
||||
self.runid = runid
|
||||
self.sessionkey = sessionkey
|
||||
self.agentid = agentid
|
||||
self.spawnedby = spawnedby
|
||||
self.seq = seq
|
||||
self.state = state
|
||||
@@ -6728,6 +6803,7 @@ public struct ChatAbortedEvent: Codable, Sendable {
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case runid = "runId"
|
||||
case sessionkey = "sessionKey"
|
||||
case agentid = "agentId"
|
||||
case spawnedby = "spawnedBy"
|
||||
case seq
|
||||
case state
|
||||
@@ -6739,6 +6815,7 @@ public struct ChatAbortedEvent: Codable, Sendable {
|
||||
public struct ChatErrorEvent: Codable, Sendable {
|
||||
public let runid: String
|
||||
public let sessionkey: String
|
||||
public let agentid: String?
|
||||
public let spawnedby: String?
|
||||
public let seq: Int
|
||||
public let state: String
|
||||
@@ -6751,6 +6828,7 @@ public struct ChatErrorEvent: Codable, Sendable {
|
||||
public init(
|
||||
runid: String,
|
||||
sessionkey: String,
|
||||
agentid: String? = nil,
|
||||
spawnedby: String?,
|
||||
seq: Int,
|
||||
state: String,
|
||||
@@ -6762,6 +6840,7 @@ public struct ChatErrorEvent: Codable, Sendable {
|
||||
{
|
||||
self.runid = runid
|
||||
self.sessionkey = sessionkey
|
||||
self.agentid = agentid
|
||||
self.spawnedby = spawnedby
|
||||
self.seq = seq
|
||||
self.state = state
|
||||
@@ -6775,6 +6854,7 @@ public struct ChatErrorEvent: Codable, Sendable {
|
||||
private enum CodingKeys: String, CodingKey {
|
||||
case runid = "runId"
|
||||
case sessionkey = "sessionKey"
|
||||
case agentid = "agentId"
|
||||
case spawnedby = "spawnedBy"
|
||||
case seq
|
||||
case state
|
||||
|
||||
@@ -176,6 +176,18 @@ const config = {
|
||||
entry: ["src/index.ts!", "src/schema.ts!"],
|
||||
project: ["src/**/*.ts!"],
|
||||
},
|
||||
"packages/net-policy": {
|
||||
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 @@
|
||||
5b30f43bee4a40f8365e1471ecf43d671a54527c014b93e919e81e8a8dd9f15a config-baseline.json
|
||||
7bd4b4416321c09280af245f5deda1f5075364de2a271d5bb4bee0ce6c5ca7f1 config-baseline.core.json
|
||||
6fea71ca36eafc07c4a67abef806177fd58914b57b1bf9a73502b2efc8f873a3 config-baseline.channel.json
|
||||
6add0a3051a081880313949da8c91500159a8bc29395c322eec0bee1987e808f config-baseline.plugin.json
|
||||
289c1bae4b9574d219fe61931be6b3ce42d4efb37d0a2edc570a521016394db5 config-baseline.json
|
||||
5bcb22d1506d82e59caa3bbc97931213299e3a2c0d45dbc549386b254661094a config-baseline.core.json
|
||||
a9102c0611b8170fac37853cc31771810f31757a9e3b2c6796bbd9625f9b9206 config-baseline.channel.json
|
||||
0a8e088f8dc7b12341075ce019281d5fe45827ae802f60c71a490022ba5867cf config-baseline.plugin.json
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
95980fd2e863f4142d694b6b5ee551d24de221a399aff6c3850543c747aae074 plugin-sdk-api-baseline.json
|
||||
a76b021246574d525fce78c186b396244381b687b42e69876d16b3034b72237c plugin-sdk-api-baseline.jsonl
|
||||
cf29066e9465cb5ac1387d1d482d0939b9176220ecc69964da9af1a471939269 plugin-sdk-api-baseline.json
|
||||
ab43993cf713a96b191c55cf89bb215c18ecdc2d8edf50f31369ce3b162c56e3 plugin-sdk-api-baseline.jsonl
|
||||
|
||||
@@ -102,7 +102,7 @@ Not every agent run creates a task. Heartbeat turns and normal interactive chat
|
||||
<Accordion title="Notify defaults for cron and media">
|
||||
Main-session cron tasks use `silent` notify policy by default - they create records for tracking but do not generate notifications. Isolated cron tasks also default to `silent` but are more visible because they run in their own session.
|
||||
|
||||
Session-backed `image_generate`, `music_generate`, and `video_generate` runs also use `silent` notify policy. They still create task records, but completion is handed back to the original agent session as an internal wake so the agent can write the follow-up message and attach the finished media itself. Generated-media completion events require message-tool delivery: the agent must send the finished media with the `message` tool, then reply `NO_REPLY`. If the requester session is no longer active or its active wake fails, and the completion agent misses some or all generated media, OpenClaw sends an idempotent direct fallback with only the missing media to the original channel target.
|
||||
Session-backed `image_generate`, `music_generate`, and `video_generate` runs also use `silent` notify policy. They still create task records, but completion is handed back to the original agent session as an internal wake so the agent can write the follow-up message and attach the finished media itself. The requester agent follows its normal visible-reply contract: automatic final reply when configured, or `message(action="send")` plus `NO_REPLY` when the session requires message-tool replies. If the requester session is no longer active or its active wake fails, and the completion agent misses some or all generated media, OpenClaw sends an idempotent direct fallback with only the missing media to the original channel target.
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Concurrent media-generation guardrail">
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -43,6 +43,7 @@ Notes:
|
||||
- Local mode uses the embedded agent runtime directly. Most local tools work, but Gateway-only features are unavailable.
|
||||
- Local mode adds `/auth [provider]` inside the TUI command surface.
|
||||
- Plugin approval gates still apply in local mode. Tools that require approval prompt for a decision in the terminal; nothing is silently auto-approved because the Gateway is not involved.
|
||||
- Session [goals](/tools/goal) appear in the footer and can be managed with `/goal`.
|
||||
|
||||
## Examples
|
||||
|
||||
@@ -87,3 +88,4 @@ rerun `openclaw config validate`. See [TUI](/web/tui) and [Config](/cli/config).
|
||||
|
||||
- [CLI reference](/cli)
|
||||
- [TUI](/web/tui)
|
||||
- [Goal](/tools/goal)
|
||||
|
||||
@@ -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`.
|
||||
|
||||
@@ -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`.
|
||||
|
||||
@@ -266,6 +266,10 @@ The doctor checks Convex broker env, validates endpoint settings, and verifies a
|
||||
|
||||
Live transport lanes share one contract instead of each inventing their own scenario list shape. `qa-channel` is the broad synthetic product-behavior suite and is not part of the live transport coverage matrix.
|
||||
|
||||
Live transport runners should import the shared scenario ids, baseline
|
||||
coverage helpers, and scenario-selection helper from
|
||||
`openclaw/plugin-sdk/qa-live-transport-scenarios`.
|
||||
|
||||
| Lane | Canary | Mention gating | Bot-to-bot | Allowlist block | Top-level reply | Restart resume | Thread follow-up | Thread isolation | Reaction observation | Help command | Native command registration |
|
||||
| -------- | ------ | -------------- | ---------- | --------------- | --------------- | -------------- | ---------------- | ---------------- | -------------------- | ------------ | --------------------------- |
|
||||
| Matrix | x | x | x | x | x | x | x | x | x | | |
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -1333,6 +1333,7 @@
|
||||
"group": "Agent coordination",
|
||||
"pages": [
|
||||
"tools/agent-send",
|
||||
"tools/goal",
|
||||
"tools/steer",
|
||||
"tools/subagents",
|
||||
"tools/acp-agents",
|
||||
@@ -1404,6 +1405,7 @@
|
||||
"providers/fal",
|
||||
"providers/fireworks",
|
||||
"providers/github-copilot",
|
||||
"providers/gmi",
|
||||
"providers/google",
|
||||
"providers/gradium",
|
||||
"providers/groq",
|
||||
@@ -1416,8 +1418,10 @@
|
||||
"providers/minimax",
|
||||
"providers/mistral",
|
||||
"providers/moonshot",
|
||||
"providers/novita",
|
||||
"providers/nvidia",
|
||||
"providers/ollama",
|
||||
"providers/ollama-cloud",
|
||||
"providers/openai",
|
||||
"providers/opencode",
|
||||
"providers/opencode-go",
|
||||
@@ -1426,6 +1430,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"],
|
||||
},
|
||||
},
|
||||
|
||||
|
||||
@@ -935,11 +935,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"],
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -183,6 +183,13 @@ Define providers under `secrets.providers`:
|
||||
passEnv: ["PATH", "VAULT_ADDR"],
|
||||
jsonOnly: true,
|
||||
},
|
||||
"team-secrets": {
|
||||
source: "exec",
|
||||
pluginIntegration: {
|
||||
pluginId: "acme-secrets",
|
||||
integrationId: "secret-store",
|
||||
},
|
||||
},
|
||||
},
|
||||
defaults: {
|
||||
env: "default",
|
||||
@@ -219,6 +226,11 @@ Define providers under `secrets.providers`:
|
||||
- Pair `allowSymlinkCommand` with `trustedDirs` for package-manager paths (for example `["/opt/homebrew"]`).
|
||||
- Supports timeout, no-output timeout, output byte limits, env allowlist, and trusted dirs.
|
||||
- Windows fail-closed note: if ACL verification is unavailable for the command path, resolution fails. For trusted paths only, set `allowInsecurePath: true` on that provider to bypass path security checks.
|
||||
- Plugin-managed exec providers can use `pluginIntegration` instead of
|
||||
copied `command`/`args`. OpenClaw resolves the current command details
|
||||
from the installed plugin manifest during startup/reload. If the plugin is
|
||||
disabled, removed, untrusted, or no longer declares the integration,
|
||||
active SecretRefs using that provider fail closed.
|
||||
|
||||
Request payload (stdin):
|
||||
|
||||
|
||||
@@ -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>
|
||||
|
||||
@@ -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**
|
||||
|
||||
@@ -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` | unset | Completion-idle guard used after a tool handoff when Codex emits raw assistant completion or progress but does not send `turn/completed`. Defaults to the assistant completion idle timeout when unset. 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 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. |
|
||||
|
||||
The plugin blocks older or unversioned app-server handshakes. Codex app-server
|
||||
must report stable version `0.125.0` or newer.
|
||||
@@ -337,10 +337,15 @@ 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 falls back to the assistant completion idle timeout otherwise.
|
||||
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.
|
||||
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.
|
||||
|
||||
## Model discovery
|
||||
|
||||
@@ -422,15 +427,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` | unset | Completion-idle guard used after a tool handoff when Codex emits raw assistant completion or progress but does not send `turn/completed`. Defaults to the assistant completion idle timeout when unset. 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`. 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. |
|
||||
|
||||
OpenClaw-owned dynamic tool calls are bounded independently from
|
||||
`appServer.requestTimeoutMs`: Codex `item/tool/call` requests use a 90 second
|
||||
@@ -574,10 +575,15 @@ 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
|
||||
falls back to the assistant completion idle timeout otherwise. 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.
|
||||
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.
|
||||
|
||||
Environment overrides remain available for local testing:
|
||||
|
||||
@@ -715,7 +721,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`.
|
||||
|
||||
@@ -169,6 +169,7 @@ or npm install metadata. Those belong in your plugin code and `package.json`.
|
||||
| `modelIdNormalization` | No | `object` | Provider-owned model-id alias/prefix cleanup that must run before provider runtime loads. |
|
||||
| `providerEndpoints` | No | `object[]` | Manifest-owned endpoint host/baseUrl metadata for provider routes that core must classify before provider runtime loads. |
|
||||
| `providerRequest` | No | `object` | Cheap provider-family and request-compatibility metadata used by generic request policy before provider runtime loads. |
|
||||
| `secretProviderIntegrations` | No | `Record<string, object>` | Declarative SecretRef exec provider presets that setup or install surfaces can offer without hardcoding provider-specific integrations in core. |
|
||||
| `cliBackends` | No | `string[]` | CLI inference backend ids owned by this plugin. Used for startup auto-activation from explicit config refs. |
|
||||
| `syntheticAuthRefs` | No | `string[]` | Provider or CLI backend refs whose plugin-owned synthetic auth hook should be probed during cold model discovery before runtime loads. |
|
||||
| `nonSecretAuthMarkers` | No | `string[]` | Bundled-plugin-owned placeholder API key values that represent non-secret local, OAuth, or ambient credential state. |
|
||||
@@ -635,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"],
|
||||
@@ -1080,6 +1081,72 @@ Provider fields:
|
||||
| `compatibilityFamily` | `"moonshot"` | Optional provider-family compatibility bucket for shared request helpers. |
|
||||
| `openAICompletions` | `object` | OpenAI-compatible completions request flags, currently `supportsStreamingUsage`. |
|
||||
|
||||
## secretProviderIntegrations reference
|
||||
|
||||
Use `secretProviderIntegrations` when a plugin can publish a reusable SecretRef
|
||||
exec provider preset. OpenClaw reads this metadata before plugin runtime loads,
|
||||
stores plugin ownership in `secrets.providers.<alias>.pluginIntegration`, and
|
||||
leaves actual secret resolution to the SecretRef runtime.
|
||||
Presets are exposed only for bundled plugins and installed plugins discovered
|
||||
from the managed plugin install roots, such as git and ClawHub installs.
|
||||
|
||||
```json
|
||||
{
|
||||
"secretProviderIntegrations": {
|
||||
"secret-store": {
|
||||
"providerAlias": "team-secrets",
|
||||
"displayName": "Team secrets",
|
||||
"source": "exec",
|
||||
"command": "${node}",
|
||||
"args": ["./bin/resolve-secrets.mjs"]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The map key is the integration id. If `providerAlias` is omitted, OpenClaw uses
|
||||
the integration id as the SecretRef provider alias. Provider aliases must match
|
||||
the normal SecretRef provider alias pattern, for example `team-secrets` or
|
||||
`onepassword-work`.
|
||||
|
||||
When an operator selects the preset, OpenClaw writes a provider reference like:
|
||||
|
||||
```json
|
||||
{
|
||||
"secrets": {
|
||||
"providers": {
|
||||
"team-secrets": {
|
||||
"source": "exec",
|
||||
"pluginIntegration": {
|
||||
"pluginId": "acme-secrets",
|
||||
"integrationId": "secret-store"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
At startup/reload, OpenClaw resolves that provider by loading current plugin
|
||||
manifest metadata, checking that the owning plugin is installed and active, and
|
||||
materializing the exec command from the manifest. Disabling or removing the
|
||||
plugin revokes the provider for active SecretRefs. Operators who want standalone
|
||||
exec configuration can still write manual `command`/`args` providers directly.
|
||||
|
||||
Only `source: "exec"` presets are currently supported. `command` must be
|
||||
`${node}`, and `args[0]` must be a `./` plugin-root-relative resolver script.
|
||||
OpenClaw materializes it at startup/reload to the current Node executable and
|
||||
the absolute in-plugin script path. Node options such as `--require`, `--import`,
|
||||
`--loader`, `--env-file`, `--eval`, and `--print` are not part of the manifest
|
||||
preset contract. Operators who need non-Node commands can configure standalone
|
||||
manual exec providers directly.
|
||||
|
||||
OpenClaw derives `trustedDirs` for manifest presets from the plugin root and,
|
||||
for `${node}` presets, the current Node executable directory. Manifest-authored
|
||||
`trustedDirs` are ignored. Other exec provider options such as `timeoutMs`,
|
||||
`maxOutputBytes`, `jsonOnly`, `env`, `passEnv`, and `allowInsecurePath` pass
|
||||
through to the normal SecretRef exec provider config.
|
||||
|
||||
## modelPricing reference
|
||||
|
||||
Use `modelPricing` when a provider needs control-plane pricing behavior before
|
||||
|
||||
@@ -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,18 +102,19 @@ 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 |
|
||||
@@ -136,7 +138,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,7 +108,7 @@ 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 |
|
||||
@@ -137,7 +139,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 |
|
||||
|
||||
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,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
|
||||
|
||||
|
||||
@@ -155,6 +155,7 @@ Most channel plugins do not need approval-specific code.
|
||||
- If custom approval auth intentionally allows only same-chat fallback, return `markImplicitSameChatApprovalAuthorization({ authorized: true })` from `openclaw/plugin-sdk/approval-auth-runtime`; otherwise core treats the result as explicit approver authorization.
|
||||
- If a channel-owned native callback resolves approvals directly, use `isImplicitSameChatApprovalAuthorization(...)` before resolving so implicit fallback still goes through the channel's normal actor authorization.
|
||||
- If a channel needs native approval delivery, keep channel code focused on target normalization plus transport/presentation facts. Use `createChannelExecApprovalProfile`, `createChannelNativeOriginTargetResolver`, `createChannelApproverDmTargetResolver`, and `createApproverRestrictedNativeApprovalCapability` from `openclaw/plugin-sdk/approval-runtime`. Put the channel-specific facts behind `approvalCapability.nativeRuntime`, ideally via `createChannelApprovalNativeRuntimeAdapter(...)` or `createLazyChannelApprovalNativeRuntimeAdapter(...)`, so core can assemble the handler and own request filtering, routing, dedupe, expiry, gateway subscription, and routed-elsewhere notices. `nativeRuntime` is split into a few smaller seams:
|
||||
- Use `createNativeApprovalChannelRouteGates` from `openclaw/plugin-sdk/approval-native-runtime` when a channel supports both session-origin native delivery and explicit approval forwarding targets. The helper centralizes approval config selection, `mode` handling, agent/session filters, account binding, session-target matching, and target-list matching while callers still own the channel id, default forwarding mode, account lookup, transport-enabled check, target normalization, and turn-source target resolution. Do not use it to create core-owned channel policy defaults; pass the channel's documented default mode explicitly.
|
||||
- `createChannelNativeOriginTargetResolver` uses the shared channel-route matcher by default for `{ to, accountId, threadId }` targets. Pass `targetsMatch` only when a channel has provider-specific equivalence rules, such as Slack timestamp prefix matching.
|
||||
- Pass `normalizeTargetForMatch` to `createChannelNativeOriginTargetResolver` when the channel needs to canonicalize provider ids before the default route matcher or a custom `targetsMatch` callback runs, while preserving the original target for delivery. Use `normalizeTarget` only when the resolved delivery target itself should be canonicalized.
|
||||
- `availability` - whether the account is configured and whether a request should be handled
|
||||
|
||||
@@ -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,10 +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, 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` |
|
||||
@@ -179,7 +180,7 @@ and pairing-path families.
|
||||
| `plugin-sdk/approval-gateway-runtime` | Shared approval gateway-resolution helper |
|
||||
| `plugin-sdk/approval-handler-adapter-runtime` | Lightweight native approval adapter loading helpers for hot channel entrypoints |
|
||||
| `plugin-sdk/approval-handler-runtime` | Broader approval handler runtime helpers; prefer the narrower adapter/gateway seams when they are enough |
|
||||
| `plugin-sdk/approval-native-runtime` | Native approval target + account-binding helpers and local native exec prompt suppression |
|
||||
| `plugin-sdk/approval-native-runtime` | Native approval target, account-binding, route-gate, forwarding fallback, and local native exec prompt suppression helpers |
|
||||
| `plugin-sdk/approval-reaction-runtime` | Hardcoded approval reaction bindings, reaction prompt payloads, reaction target stores, and compatibility export for local native exec prompt suppression |
|
||||
| `plugin-sdk/approval-reply-runtime` | Exec/plugin approval reply payload helpers |
|
||||
| `plugin-sdk/approval-runtime` | Exec/plugin approval payload helpers, native approval routing/runtime helpers, and structured approval display helpers such as `formatApprovalDisplayPath` |
|
||||
@@ -192,6 +193,7 @@ and pairing-path families.
|
||||
| `plugin-sdk/allow-from` | `formatAllowFromLowercase` |
|
||||
| `plugin-sdk/channel-secret-runtime` | Narrow secret-contract collection helpers for channel/plugin secret surfaces |
|
||||
| `plugin-sdk/secret-ref-runtime` | Narrow `coerceSecretRef` and SecretRef typing helpers for secret-contract/config parsing |
|
||||
| `plugin-sdk/secret-provider-integration` | Type-only SecretRef provider integration manifest and preset contracts for plugins that publish external secret provider presets |
|
||||
| `plugin-sdk/security-runtime` | Shared trust, DM gating, root-bounded file/path helpers including create-only writes, sync/async atomic file replacement, sibling temp writes, cross-device move fallback, private file-store helpers, symlink-parent guards, external-content, sensitive text redaction, constant-time secret comparison, and secret-collection helpers |
|
||||
| `plugin-sdk/ssrf-policy` | Host allowlist and private-network SSRF policy helpers |
|
||||
| `plugin-sdk/ssrf-dispatcher` | Narrow pinned-dispatcher helpers without the broad infra runtime surface |
|
||||
@@ -219,6 +221,7 @@ and pairing-path families.
|
||||
| `plugin-sdk/lazy-runtime` | Lazy runtime import/binding helpers such as `createLazyRuntimeModule`, `createLazyRuntimeMethod`, and `createLazyRuntimeSurface` |
|
||||
| `plugin-sdk/process-runtime` | Process exec helpers |
|
||||
| `plugin-sdk/cli-runtime` | CLI formatting, wait, version, argument-invocation, and lazy command-group helpers |
|
||||
| `plugin-sdk/qa-live-transport-scenarios` | Shared live transport QA scenario ids, baseline coverage helpers, and scenario-selection helper |
|
||||
| `plugin-sdk/gateway-method-runtime` | Reserved Gateway method dispatch helper for plugin HTTP routes that declare `contracts.gatewayMethodDispatch: ["authenticated-request"]` |
|
||||
| `plugin-sdk/gateway-runtime` | Gateway client, event-loop-ready client start helper, gateway CLI RPC, gateway protocol errors, and channel-status patch helpers |
|
||||
| `plugin-sdk/config-contracts` | Focused type-only config surface for plugin config shapes such as `OpenClawConfig` and channel/provider config types |
|
||||
@@ -289,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 |
|
||||
|
||||
@@ -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,
|
||||
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,17 +89,31 @@ 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_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
|
||||
@@ -105,6 +124,12 @@ 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, and
|
||||
blocks expired claims or timed-out runs so operators can recover them from the
|
||||
board.
|
||||
|
||||
## Session lifecycle sync
|
||||
|
||||
Cards can be linked to existing dashboard sessions or to the session created
|
||||
@@ -163,8 +188,9 @@ 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`
|
||||
- create, update, move, delete, comment, link, dependency link, proof, artifact,
|
||||
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
|
||||
|
||||
115
docs/providers/qwen-oauth.md
Normal file
115
docs/providers/qwen-oauth.md
Normal file
@@ -0,0 +1,115 @@
|
||||
---
|
||||
summary: "Use the Qwen Portal provider id with OpenClaw"
|
||||
read_when:
|
||||
- You want to configure the qwen-oauth provider id
|
||||
- You previously used Qwen Portal OAuth credentials
|
||||
- You need the Qwen Portal endpoint or migration guidance
|
||||
title: "Qwen OAuth / Portal"
|
||||
---
|
||||
|
||||
`qwen-oauth` is the Qwen Portal provider id. It targets the Qwen Portal endpoint
|
||||
and keeps older Qwen OAuth / portal setups addressable through a distinct
|
||||
provider id.
|
||||
|
||||
Use this provider when you specifically have a current Qwen Portal token for
|
||||
`https://portal.qwen.ai/v1`, or when you are migrating an older Qwen Portal /
|
||||
Qwen CLI setup and want to keep those credentials separate from the canonical
|
||||
Qwen Cloud provider. It is not the recommended first choice for new Qwen users.
|
||||
|
||||
For new Qwen Cloud setups, prefer [Qwen](/providers/qwen) with the Standard
|
||||
ModelStudio endpoint unless you specifically have a current Qwen Portal token.
|
||||
|
||||
## Setup
|
||||
|
||||
Provide your portal token through onboarding:
|
||||
|
||||
```bash
|
||||
openclaw onboard --auth-choice qwen-oauth
|
||||
```
|
||||
|
||||
Or set:
|
||||
|
||||
```bash
|
||||
export QWEN_API_KEY="<your-qwen-portal-token>" # pragma: allowlist secret
|
||||
```
|
||||
|
||||
## Defaults
|
||||
|
||||
- Provider: `qwen-oauth`
|
||||
- Aliases: `qwen-portal`, `qwen-cli`
|
||||
- Base URL: `https://portal.qwen.ai/v1`
|
||||
- Env var: `QWEN_API_KEY`
|
||||
- API style: OpenAI-compatible
|
||||
- Default model: `qwen-oauth/qwen3.5-plus`
|
||||
|
||||
## How this differs from Qwen
|
||||
|
||||
OpenClaw has two Qwen-facing provider ids:
|
||||
|
||||
| Provider | Endpoint family | Best for |
|
||||
| ------------ | -------------------------------------------------------- | -------------------------------------------------------------------------------------- |
|
||||
| `qwen` | Qwen Cloud / Alibaba DashScope and Coding Plan endpoints | New API-key setups, Standard pay-as-you-go, Coding Plan, multimodal DashScope features |
|
||||
| `qwen-oauth` | Qwen Portal endpoint at `portal.qwen.ai/v1` | Existing Qwen Portal tokens and legacy Qwen OAuth / CLI setups |
|
||||
|
||||
Both providers use OpenAI-compatible request shapes, but they are separate auth
|
||||
surfaces. A token stored for `qwen-oauth` should not be treated as a DashScope
|
||||
or ModelStudio key, and a new DashScope key should use the canonical `qwen`
|
||||
provider instead.
|
||||
|
||||
## When to choose Qwen OAuth / Portal
|
||||
|
||||
- You already have a working Qwen Portal token.
|
||||
- You are preserving a legacy Qwen OAuth or Qwen CLI workflow while moving to
|
||||
OpenClaw's provider model.
|
||||
- You need to test compatibility with the Qwen Portal endpoint specifically.
|
||||
|
||||
Choose [Qwen](/providers/qwen) for new setup, broader endpoint choices, Standard
|
||||
ModelStudio, Coding Plan, and the full bundled Qwen catalog.
|
||||
|
||||
## Models
|
||||
|
||||
The bundled catalog seeds the Qwen Portal default:
|
||||
|
||||
- `qwen-oauth/qwen3.5-plus`
|
||||
|
||||
Availability depends on the current Qwen Portal account and token. If your
|
||||
account uses ModelStudio / DashScope API keys instead, configure the canonical
|
||||
`qwen` provider:
|
||||
|
||||
```bash
|
||||
openclaw onboard --auth-choice qwen-standard-api-key
|
||||
openclaw models set qwen/qwen3-coder-plus
|
||||
```
|
||||
|
||||
## Migration
|
||||
|
||||
Legacy Qwen Portal OAuth profiles may not be refreshable. If a portal profile
|
||||
stops working, re-authenticate with a current token or switch to the Standard
|
||||
Qwen provider:
|
||||
|
||||
```bash
|
||||
openclaw onboard --auth-choice qwen-standard-api-key
|
||||
```
|
||||
|
||||
Standard global ModelStudio uses:
|
||||
|
||||
```text
|
||||
https://dashscope-intl.aliyuncs.com/compatible-mode/v1
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
- Portal OAuth refresh failures: legacy Qwen Portal OAuth profiles may not be
|
||||
refreshable. Re-run onboarding with a current token.
|
||||
- Wrong endpoint errors: confirm the model ref starts with `qwen-oauth/` when
|
||||
using a portal token. Use `qwen/` refs only for the canonical Qwen provider.
|
||||
- `QWEN_API_KEY` confusion: both Qwen pages mention this env var, but onboarding
|
||||
stores credentials under the selected provider id. Prefer onboarding when you
|
||||
keep both `qwen` and `qwen-oauth` available on the same machine.
|
||||
|
||||
## Related
|
||||
|
||||
- [Qwen](/providers/qwen)
|
||||
- [Alibaba Model Studio](/providers/alibaba)
|
||||
- [Model providers](/concepts/model-providers)
|
||||
- [All providers](/providers/index)
|
||||
@@ -6,21 +6,13 @@ read_when:
|
||||
title: "Qwen"
|
||||
---
|
||||
|
||||
<Warning>
|
||||
|
||||
**Qwen OAuth has been removed.** The free-tier OAuth integration
|
||||
(`qwen-portal`) that used `portal.qwen.ai` endpoints is no longer available.
|
||||
See [Issue #49557](https://github.com/openclaw/openclaw/issues/49557) for
|
||||
background.
|
||||
|
||||
</Warning>
|
||||
|
||||
OpenClaw now treats Qwen as a first-class bundled provider with canonical id
|
||||
`qwen`. The bundled provider targets the Qwen Cloud / Alibaba DashScope and
|
||||
Coding Plan endpoints and keeps legacy `modelstudio` ids working as a
|
||||
compatibility alias.
|
||||
Coding Plan endpoints, keeps legacy `modelstudio` ids working as a compatibility
|
||||
alias, and also exposes the Qwen Portal token flow as provider `qwen-oauth`.
|
||||
|
||||
- Provider: `qwen`
|
||||
- Portal provider: [`qwen-oauth`](/providers/qwen-oauth)
|
||||
- Preferred env var: `QWEN_API_KEY`
|
||||
- Also accepted for compatibility: `MODELSTUDIO_API_KEY`, `DASHSCOPE_API_KEY`
|
||||
- API style: OpenAI-compatible
|
||||
@@ -132,6 +124,44 @@ Choose your plan type and follow the setup steps.
|
||||
</Note>
|
||||
|
||||
</Tab>
|
||||
|
||||
<Tab title="Qwen OAuth / Portal">
|
||||
**Best for:** a Qwen Portal token against `https://portal.qwen.ai/v1`.
|
||||
|
||||
See [Qwen OAuth / Portal](/providers/qwen-oauth) for the dedicated provider
|
||||
page and migration notes.
|
||||
|
||||
<Steps>
|
||||
<Step title="Provide your portal token">
|
||||
```bash
|
||||
openclaw onboard --auth-choice qwen-oauth
|
||||
```
|
||||
</Step>
|
||||
<Step title="Set a default model">
|
||||
```json5
|
||||
{
|
||||
agents: {
|
||||
defaults: {
|
||||
model: { primary: "qwen-oauth/qwen3.5-plus" },
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
</Step>
|
||||
<Step title="Verify the model is available">
|
||||
```bash
|
||||
openclaw models list --provider qwen-oauth
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
<Note>
|
||||
`qwen-oauth` uses the same `QWEN_API_KEY` env var name as the DashScope
|
||||
provider, but stores auth under the `qwen-oauth` provider id when configured
|
||||
through OpenClaw onboarding.
|
||||
</Note>
|
||||
|
||||
</Tab>
|
||||
</Tabs>
|
||||
|
||||
## Plan types and endpoints
|
||||
@@ -142,6 +172,7 @@ Choose your plan type and follow the setup steps.
|
||||
| Standard (pay-as-you-go) | Global | `qwen-standard-api-key` | `dashscope-intl.aliyuncs.com/compatible-mode/v1` |
|
||||
| Coding Plan (subscription) | China | `qwen-api-key-cn` | `coding.dashscope.aliyuncs.com/v1` |
|
||||
| Coding Plan (subscription) | Global | `qwen-api-key` | `coding-intl.dashscope.aliyuncs.com/v1` |
|
||||
| Qwen Portal | Global | `qwen-oauth` | `portal.qwen.ai/v1` |
|
||||
|
||||
The provider auto-selects the endpoint based on your auth choice. Canonical
|
||||
choices use the `qwen-*` family; `modelstudio-*` remains compatibility-only.
|
||||
@@ -169,6 +200,7 @@ the Standard endpoint.
|
||||
| `qwen/glm-5` | text | 202,752 | GLM |
|
||||
| `qwen/glm-4.7` | text | 202,752 | GLM |
|
||||
| `qwen/kimi-k2.5` | text, image | 262,144 | Moonshot AI via Alibaba |
|
||||
| `qwen-oauth/qwen3.5-plus` | text, image | 1,000,000 | Qwen Portal default |
|
||||
|
||||
<Note>
|
||||
Availability can still vary by endpoint and billing plan even when a model is
|
||||
|
||||
@@ -1,52 +1,68 @@
|
||||
---
|
||||
summary: "Use Xiaomi MiMo models with OpenClaw"
|
||||
summary: "Use Xiaomi MiMo pay-as-you-go and Token Plan models with OpenClaw"
|
||||
read_when:
|
||||
- You want Xiaomi MiMo models in OpenClaw
|
||||
- You need XIAOMI_API_KEY setup
|
||||
- You need Xiaomi MiMo auth or Token Plan setup
|
||||
title: "Xiaomi MiMo"
|
||||
---
|
||||
|
||||
Xiaomi MiMo is the API platform for **MiMo** models. OpenClaw includes a bundled `xiaomi` plugin that registers both an OpenAI-compatible chat provider and a speech (TTS) provider against the same `XIAOMI_API_KEY`.
|
||||
Xiaomi MiMo is the API platform for **MiMo** models. OpenClaw includes a bundled Xiaomi plugin with two text-provider presets:
|
||||
|
||||
| Property | Value |
|
||||
| --------------- | ---------------------------------------- |
|
||||
| Provider id | `xiaomi` |
|
||||
| Plugin | bundled, `enabledByDefault: true` |
|
||||
| Auth env var | `XIAOMI_API_KEY` |
|
||||
| Onboarding flag | `--auth-choice xiaomi-api-key` |
|
||||
| Direct CLI flag | `--xiaomi-api-key <key>` |
|
||||
| Contracts | chat completions + `speechProviders` |
|
||||
| API | OpenAI-compatible (`openai-completions`) |
|
||||
| Base URL | `https://api.xiaomimimo.com/v1` |
|
||||
| Default model | `xiaomi/mimo-v2-flash` |
|
||||
| TTS default | `mimo-v2.5-tts`, voice `mimo_default` |
|
||||
- `xiaomi` for pay-as-you-go keys (`sk-...`)
|
||||
- `xiaomi-token-plan` for Token Plan keys (`tp-...`) with regional endpoint presets
|
||||
|
||||
The same plugin also registers the `xiaomi` speech (TTS) provider.
|
||||
|
||||
| Property | Value |
|
||||
| ---------------- | -------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| Provider ids | `xiaomi` (pay-as-you-go), `xiaomi-token-plan` (Token Plan) |
|
||||
| Plugin | bundled, `enabledByDefault: true` |
|
||||
| Auth env vars | `XIAOMI_API_KEY`, `XIAOMI_TOKEN_PLAN_API_KEY` |
|
||||
| Onboarding flags | `--auth-choice xiaomi-api-key`, `--auth-choice xiaomi-token-plan-cn`, `--auth-choice xiaomi-token-plan-sgp`, `--auth-choice xiaomi-token-plan-ams` |
|
||||
| Direct CLI flags | `--xiaomi-api-key <key>`, `--xiaomi-token-plan-api-key <key>` |
|
||||
| Contracts | chat completions + `speechProviders` |
|
||||
| API | OpenAI-compatible (`openai-completions`) |
|
||||
| Base URLs | Pay-as-you-go: `https://api.xiaomimimo.com/v1`; Token Plan presets: `token-plan-{cn,sgp,ams}...` |
|
||||
| Default models | `xiaomi/mimo-v2-flash`, `xiaomi-token-plan/mimo-v2.5-pro` |
|
||||
| TTS default | `mimo-v2.5-tts`, voice `mimo_default` |
|
||||
|
||||
## Getting started
|
||||
|
||||
<Steps>
|
||||
<Step title="Get an API key">
|
||||
Create an API key in the [Xiaomi MiMo console](https://platform.xiaomimimo.com/#/console/api-keys).
|
||||
<Step title="Get the right key">
|
||||
Create a pay-as-you-go key in the [Xiaomi MiMo console](https://platform.xiaomimimo.com/#/console/api-keys), or open your Token Plan subscription page and copy the regional OpenAI-compatible base URL plus the matching `tp-...` key.
|
||||
</Step>
|
||||
|
||||
<Step title="Run onboarding">
|
||||
Pay-as-you-go:
|
||||
|
||||
```bash
|
||||
openclaw onboard --auth-choice xiaomi-api-key
|
||||
```
|
||||
|
||||
Or pass the key directly:
|
||||
Token Plan:
|
||||
|
||||
```bash
|
||||
openclaw onboard --auth-choice xiaomi-token-plan-sgp
|
||||
```
|
||||
|
||||
Or pass the keys directly:
|
||||
|
||||
```bash
|
||||
openclaw onboard --auth-choice xiaomi-api-key --xiaomi-api-key "$XIAOMI_API_KEY"
|
||||
openclaw onboard --auth-choice xiaomi-token-plan-sgp --xiaomi-token-plan-api-key "$XIAOMI_TOKEN_PLAN_API_KEY"
|
||||
```
|
||||
|
||||
</Step>
|
||||
<Step title="Verify the model is available">
|
||||
```bash
|
||||
openclaw models list --provider xiaomi
|
||||
openclaw models list --provider xiaomi-token-plan
|
||||
```
|
||||
</Step>
|
||||
</Steps>
|
||||
|
||||
## Built-in catalog
|
||||
## Pay-as-you-go catalog
|
||||
|
||||
| Model ref | Input | Context | Max output | Reasoning | Notes |
|
||||
| ---------------------- | ----------- | --------- | ---------- | --------- | ------------- |
|
||||
@@ -58,6 +74,23 @@ Xiaomi MiMo is the API platform for **MiMo** models. OpenClaw includes a bundled
|
||||
The default model ref is `xiaomi/mimo-v2-flash`. The provider is injected automatically when `XIAOMI_API_KEY` is set or an auth profile exists.
|
||||
</Tip>
|
||||
|
||||
## Token Plan catalog
|
||||
|
||||
Choose the Token Plan auth choice that matches the regional base URL shown in Xiaomi's subscription UI:
|
||||
|
||||
- `xiaomi-token-plan-cn` -> `https://token-plan-cn.xiaomimimo.com/v1`
|
||||
- `xiaomi-token-plan-sgp` -> `https://token-plan-sgp.xiaomimimo.com/v1`
|
||||
- `xiaomi-token-plan-ams` -> `https://token-plan-ams.xiaomimimo.com/v1`
|
||||
|
||||
| Model ref | Input | Context | Max output | Reasoning | Notes |
|
||||
| --------------------------------- | ----------- | --------- | ---------- | --------- | ------------- |
|
||||
| `xiaomi-token-plan/mimo-v2.5-pro` | text | 1,048,576 | 32,000 | Yes | Default model |
|
||||
| `xiaomi-token-plan/mimo-v2.5` | text, image | 1,048,576 | 32,000 | Yes | Multimodal |
|
||||
|
||||
<Tip>
|
||||
Token Plan onboarding validates the key shape and warns when a `tp-...` key is entered into the pay-as-you-go path, or an `sk-...` key is entered into the Token Plan path.
|
||||
</Tip>
|
||||
|
||||
## Text-to-speech
|
||||
|
||||
The bundled `xiaomi` plugin also registers Xiaomi MiMo as a speech provider for
|
||||
@@ -117,7 +150,6 @@ Opus with `ffmpeg` before delivery.
|
||||
name: "Xiaomi MiMo V2 Flash",
|
||||
reasoning: false,
|
||||
input: ["text"],
|
||||
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
||||
contextWindow: 262144,
|
||||
maxTokens: 8192,
|
||||
},
|
||||
@@ -126,7 +158,6 @@ Opus with `ffmpeg` before delivery.
|
||||
name: "Xiaomi MiMo V2 Pro",
|
||||
reasoning: true,
|
||||
input: ["text"],
|
||||
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
||||
contextWindow: 1048576,
|
||||
maxTokens: 32000,
|
||||
},
|
||||
@@ -135,7 +166,6 @@ Opus with `ffmpeg` before delivery.
|
||||
name: "Xiaomi MiMo V2 Omni",
|
||||
reasoning: true,
|
||||
input: ["text", "image"],
|
||||
cost: { input: 0, output: 0, cacheRead: 0, cacheWrite: 0 },
|
||||
contextWindow: 262144,
|
||||
maxTokens: 32000,
|
||||
},
|
||||
@@ -146,24 +176,68 @@ Opus with `ffmpeg` before delivery.
|
||||
}
|
||||
```
|
||||
|
||||
Pricing and compat flags come from the bundled plugin manifest, so the config example omits `cost` and `compat` to avoid diverging from runtime behavior.
|
||||
|
||||
Token Plan:
|
||||
|
||||
```json5
|
||||
{
|
||||
env: { XIAOMI_TOKEN_PLAN_API_KEY: "tp-your-key" },
|
||||
agents: { defaults: { model: { primary: "xiaomi-token-plan/mimo-v2.5-pro" } } },
|
||||
models: {
|
||||
mode: "merge",
|
||||
providers: {
|
||||
"xiaomi-token-plan": {
|
||||
baseUrl: "https://token-plan-sgp.xiaomimimo.com/v1",
|
||||
api: "openai-completions",
|
||||
apiKey: "XIAOMI_TOKEN_PLAN_API_KEY",
|
||||
models: [
|
||||
{
|
||||
id: "mimo-v2.5-pro",
|
||||
name: "Xiaomi MiMo V2.5 Pro",
|
||||
reasoning: true,
|
||||
input: ["text"],
|
||||
contextWindow: 1048576,
|
||||
maxTokens: 32000,
|
||||
},
|
||||
{
|
||||
id: "mimo-v2.5",
|
||||
name: "Xiaomi MiMo V2.5",
|
||||
reasoning: true,
|
||||
input: ["text", "image"],
|
||||
contextWindow: 1048576,
|
||||
maxTokens: 32000,
|
||||
},
|
||||
],
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
```
|
||||
|
||||
Pricing comes from the bundled manifest (Token Plan models include tiered cache-read pricing), so the config example omits `cost`.
|
||||
|
||||
<AccordionGroup>
|
||||
<Accordion title="Auto-injection behavior">
|
||||
The `xiaomi` provider is injected automatically when `XIAOMI_API_KEY` is set in your environment or an auth profile exists. You do not need to manually configure the provider unless you want to override model metadata or the base URL.
|
||||
The `xiaomi` provider is injected automatically when `XIAOMI_API_KEY` is set in your environment or an auth profile exists. `xiaomi-token-plan` needs a regional base URL, so the supported path is the bundled Token Plan onboarding choice or an explicit `models.providers.xiaomi-token-plan` config block.
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Model details">
|
||||
- **mimo-v2-flash** — lightweight and fast, ideal for general-purpose text tasks. No reasoning support.
|
||||
- **mimo-v2-pro** — supports reasoning with a 1M token context window for long-document workloads.
|
||||
- **mimo-v2-omni** — reasoning-enabled multimodal model that accepts both text and image inputs.
|
||||
- **mimo-v2.5-pro** — Token Plan default with Xiaomi's current V2.5 reasoning stack.
|
||||
- **mimo-v2.5** — Token Plan multimodal V2.5 route.
|
||||
|
||||
<Note>
|
||||
All models use the `xiaomi/` prefix (for example `xiaomi/mimo-v2-pro`).
|
||||
Pay-as-you-go models use the `xiaomi/` prefix. Token Plan models use the `xiaomi-token-plan/` prefix.
|
||||
</Note>
|
||||
|
||||
</Accordion>
|
||||
|
||||
<Accordion title="Troubleshooting">
|
||||
- If models do not appear, confirm `XIAOMI_API_KEY` is set and valid.
|
||||
- If models do not appear, confirm the relevant key env var or auth profile is present and valid.
|
||||
- For Token Plan, confirm the chosen onboarding region matches the subscription page base URL and that the key starts with `tp-`.
|
||||
- When the Gateway runs as a daemon, ensure the key is available to that process (for example in `~/.openclaw/.env` or via `env.shellEnv`).
|
||||
|
||||
<Warning>
|
||||
|
||||
2256
docs/refactor/database-first.md
Normal file
2256
docs/refactor/database-first.md
Normal file
File diff suppressed because it is too large
Load Diff
@@ -15,11 +15,12 @@ OpenClaw assembles its own system prompt on every run. It includes:
|
||||
|
||||
- Tool list + short descriptions
|
||||
- Skills list (only metadata; instructions are loaded on demand with `read`).
|
||||
The compact skills block is bounded by `skills.limits.maxSkillsPromptChars`,
|
||||
with optional per-agent override at
|
||||
`agents.list[].skillsLimits.maxSkillsPromptChars`.
|
||||
Native Codex turns receive the compact skills block as turn-scoped
|
||||
collaboration developer instructions; other harnesses receive it in the normal
|
||||
prompt surface. It is bounded by `skills.limits.maxSkillsPromptChars`, with
|
||||
optional per-agent override at `agents.list[].skillsLimits.maxSkillsPromptChars`.
|
||||
- Self-update instructions
|
||||
- Workspace + bootstrap files (`AGENTS.md`, `SOUL.md`, `TOOLS.md`, `IDENTITY.md`, `USER.md`, `HEARTBEAT.md`, `BOOTSTRAP.md` when new, plus `MEMORY.md` when present). Native Codex turns do not paste raw `MEMORY.md` from the configured agent workspace when memory tools are available for that workspace; they include a small memory pointer and use memory tools on demand. 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. Lowercase root `memory.md` is not injected; it is legacy repair input for `openclaw doctor --fix` when paired with `MEMORY.md`. Large injected files are truncated by `agents.defaults.bootstrapMaxChars` (default: 12000), and total bootstrap injection is capped by `agents.defaults.bootstrapTotalMaxChars` (default: 60000). `memory/*.md` daily files are not part of the normal bootstrap prompt; they remain on-demand via memory tools on ordinary turns, but reset/startup model runs can prepend a one-shot startup-context block with recent daily memory for that first turn. Bare chat `/new` and `/reset` commands are acknowledged without invoking the model. The startup prelude is controlled by `agents.defaults.startupContext`. Post-compaction AGENTS.md excerpts are separate and require explicit `agents.defaults.compaction.postCompactionSections` opt-in.
|
||||
- Workspace + bootstrap files (`AGENTS.md`, `SOUL.md`, `TOOLS.md`, `IDENTITY.md`, `USER.md`, `HEARTBEAT.md`, `BOOTSTRAP.md` when new, plus `MEMORY.md` when present). Native Codex turns do not paste raw `MEMORY.md` from the configured agent workspace when memory tools are available for that workspace; they include a small memory pointer in turn-scoped collaboration developer instructions and use memory tools on demand. 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. Lowercase root `memory.md` is not injected; it is legacy repair input for `openclaw doctor --fix` when paired with `MEMORY.md`. Large injected files are truncated by `agents.defaults.bootstrapMaxChars` (default: 12000), and total bootstrap injection is capped by `agents.defaults.bootstrapTotalMaxChars` (default: 60000). `memory/*.md` daily files are not part of the normal bootstrap prompt; they remain on-demand via memory tools on ordinary turns, but reset/startup model runs can prepend a one-shot startup-context block with recent daily memory for that first turn. Bare chat `/new` and `/reset` commands are acknowledged without invoking the model. The startup prelude is controlled by `agents.defaults.startupContext`. Post-compaction AGENTS.md excerpts are separate and require explicit `agents.defaults.compaction.postCompactionSections` opt-in.
|
||||
- Time (UTC + user timezone)
|
||||
- Reply tags + heartbeat behavior
|
||||
- Runtime metadata (host/OS/model/thinking)
|
||||
|
||||
@@ -134,7 +134,7 @@ Configure the proxy to:
|
||||
|
||||
Use this denylist as the starting point for any forward proxy, firewall, or egress policy.
|
||||
|
||||
OpenClaw application-level classifier logic lives in `src/infra/net/ssrf.ts` and `src/shared/net/ip.ts`. The relevant parity hooks are `BLOCKED_HOSTNAMES`, `BLOCKED_IPV4_SPECIAL_USE_RANGES`, `BLOCKED_IPV6_SPECIAL_USE_RANGES`, `RFC2544_BENCHMARK_PREFIX`, and the embedded IPv4 sentinel handling for NAT64, 6to4, Teredo, ISATAP, and IPv4-mapped forms. Those files are useful references when maintaining an external proxy policy, but OpenClaw does not automatically export or enforce those rules in your proxy.
|
||||
OpenClaw application-level classifier logic lives in `src/infra/net/ssrf.ts` and `packages/net-policy/src/ip.ts`. The relevant parity hooks are `BLOCKED_HOSTNAMES`, `BLOCKED_IPV4_SPECIAL_USE_RANGES`, `BLOCKED_IPV6_SPECIAL_USE_RANGES`, `RFC2544_BENCHMARK_PREFIX`, and the embedded IPv4 sentinel handling for NAT64, 6to4, Teredo, ISATAP, and IPv4-mapped forms. Those files are useful references when maintaining an external proxy policy, but OpenClaw does not automatically export or enforce those rules in your proxy.
|
||||
|
||||
| Range or host | Why to block |
|
||||
| ------------------------------------------------------------------------------------ | ---------------------------------------------------- |
|
||||
|
||||
@@ -557,9 +557,9 @@ Two ways to start an ACP session:
|
||||
</ParamField>
|
||||
<ParamField path="model" type="string">
|
||||
Explicit model override for the ACP child session. Codex ACP spawns
|
||||
normalize OpenClaw Codex refs such as `openai-codex/gpt-5.4` to Codex
|
||||
ACP startup config before `session/new`; slash forms such as
|
||||
`openai-codex/gpt-5.4/high` also set Codex ACP reasoning effort.
|
||||
normalize OpenAI refs such as `openai/gpt-5.4` to Codex ACP startup
|
||||
config before `session/new`; slash forms such as `openai/gpt-5.4/high`
|
||||
also set Codex ACP reasoning effort.
|
||||
Other harnesses must advertise ACP `models` and support
|
||||
`session/set_model`; otherwise OpenClaw/acpx fails clearly instead of
|
||||
silently falling back to the target agent default.
|
||||
@@ -792,7 +792,7 @@ operations:
|
||||
|
||||
| Command | Maps to | Notes |
|
||||
| ---------------------------- | ------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `/acp model <id>` | runtime config key `model` | For Codex ACP, OpenClaw normalizes `openai-codex/<model>` to the adapter model id and maps slash reasoning suffixes such as `openai-codex/gpt-5.4/high` to `reasoning_effort`. |
|
||||
| `/acp model <id>` | runtime config key `model` | For Codex ACP, OpenClaw normalizes `openai/<model>` to the adapter model id and maps slash reasoning suffixes such as `openai/gpt-5.4/high` to `reasoning_effort`. |
|
||||
| `/acp set thinking <level>` | canonical option `thinking` | OpenClaw sends the backend-advertised equivalent when present, preferring `thinking`, then `effort`, `reasoning_effort`, or `thought_level`. For Codex ACP, the adapter maps values to `reasoning_effort`. |
|
||||
| `/acp permissions <profile>` | canonical option `permissionProfile` | OpenClaw sends the backend-advertised equivalent when present, such as `approval_policy`, `permission_profile`, `permissions`, or `permission_mode`. |
|
||||
| `/acp timeout <seconds>` | canonical option `timeoutSeconds` | OpenClaw sends the backend-advertised equivalent when present, such as `timeout` or `timeout_seconds`. |
|
||||
|
||||
217
docs/tools/goal.md
Normal file
217
docs/tools/goal.md
Normal file
@@ -0,0 +1,217 @@
|
||||
---
|
||||
doc-schema-version: 1
|
||||
summary: "Session goals: durable per-session objectives, /goal controls, model goal tools, token budgets, and TUI status"
|
||||
read_when:
|
||||
- You want OpenClaw to keep one objective visible across a long session
|
||||
- You need to pause, resume, block, complete, or clear a session goal
|
||||
- You want to understand the get_goal, create_goal, and update_goal tools
|
||||
- You want to see how goals appear in the TUI
|
||||
title: "Goal"
|
||||
---
|
||||
|
||||
# Goal
|
||||
|
||||
A **goal** is one durable objective attached to the current OpenClaw session.
|
||||
It gives the agent and the operator a shared target for long-running work,
|
||||
without turning that target into a background task, reminder, cron job, or
|
||||
standing order.
|
||||
|
||||
Goals are session state. They move with the session key, survive process
|
||||
restarts, show up in `/goal`, are available to the model through the goal
|
||||
tools, and appear in the TUI footer when the active session has one.
|
||||
|
||||
## Quick start
|
||||
|
||||
Set a goal:
|
||||
|
||||
```text
|
||||
/goal start get CI green for PR 87469 and push the fix
|
||||
```
|
||||
|
||||
Check it:
|
||||
|
||||
```text
|
||||
/goal
|
||||
```
|
||||
|
||||
Pause it when work is intentionally waiting:
|
||||
|
||||
```text
|
||||
/goal pause waiting for CI
|
||||
```
|
||||
|
||||
Resume it:
|
||||
|
||||
```text
|
||||
/goal resume
|
||||
```
|
||||
|
||||
Mark it complete:
|
||||
|
||||
```text
|
||||
/goal complete pushed and verified
|
||||
```
|
||||
|
||||
Clear it:
|
||||
|
||||
```text
|
||||
/goal clear
|
||||
```
|
||||
|
||||
## What goals are for
|
||||
|
||||
Use a goal when a session has a concrete outcome that should remain visible
|
||||
across many turns:
|
||||
|
||||
- A PR closeout: fix, verify, autoreview, push, and open or update the PR.
|
||||
- A debug run: reproduce the bug, identify the owning surface, patch, and prove
|
||||
the fix.
|
||||
- A docs pass: read the relevant docs, write the new page, cross-link it, and
|
||||
verify the docs build.
|
||||
- A maintenance task: inspect current state, make bounded changes, run the right
|
||||
checks, and report what changed.
|
||||
|
||||
A goal is not a task queue. Use [Task Flow](/automation/taskflow),
|
||||
[tasks](/automation/tasks), [cron jobs](/automation/cron-jobs), or
|
||||
[standing orders](/automation/standing-orders) when work should run detached,
|
||||
repeat on a schedule, fan out into managed sub-work, or persist as a policy.
|
||||
|
||||
## Command reference
|
||||
|
||||
`/goal` without arguments prints the current goal summary:
|
||||
|
||||
```text
|
||||
Goal
|
||||
Status: active
|
||||
Objective: get CI green for PR 87469 and push the fix
|
||||
Tokens used: 12k
|
||||
Token budget: 12k/50k
|
||||
|
||||
Commands: /goal pause, /goal complete, /goal clear
|
||||
```
|
||||
|
||||
Commands:
|
||||
|
||||
- `/goal` or `/goal status` shows the current goal.
|
||||
- `/goal start <objective>` creates a new goal for the current session.
|
||||
- `/goal set <objective>` and `/goal create <objective>` are aliases for
|
||||
`start`.
|
||||
- `/goal pause [note]` pauses an active goal.
|
||||
- `/goal resume [note]` resumes a paused, blocked, usage-limited, or
|
||||
budget-limited goal.
|
||||
- `/goal complete [note]` marks the goal achieved.
|
||||
- `/goal done [note]` is an alias for `complete`.
|
||||
- `/goal block [note]` marks the goal blocked.
|
||||
- `/goal blocked [note]` is an alias for `block`.
|
||||
- `/goal clear` removes the goal from the session.
|
||||
|
||||
Only one goal can exist on a session at a time. Starting a second goal fails
|
||||
until the current one is cleared.
|
||||
|
||||
## Statuses
|
||||
|
||||
Goals use a small status set:
|
||||
|
||||
- `active`: the session is pursuing the goal.
|
||||
- `paused`: the operator paused the goal; `/goal resume` makes it active again.
|
||||
- `blocked`: the agent or operator reported a real blocker; `/goal resume`
|
||||
makes it active again when new information or state is available.
|
||||
- `budget_limited`: the configured token budget was reached; `/goal resume`
|
||||
restarts pursuit from the same objective.
|
||||
- `usage_limited`: reserved for usage-limit stop states; `/goal resume`
|
||||
restarts pursuit when allowed.
|
||||
- `complete`: the goal was achieved. Complete goals are terminal; use
|
||||
`/goal clear` before starting another goal.
|
||||
|
||||
`/new` and `/reset` clear the current session goal because they intentionally
|
||||
start fresh session context.
|
||||
|
||||
## Token budgets
|
||||
|
||||
Goals can have an optional positive token budget. The budget is stored with the
|
||||
goal and measured from the session's fresh token count at creation time. If the
|
||||
current session only has stale or unknown token usage when the goal starts,
|
||||
OpenClaw waits for the next fresh session token snapshot and uses that as the
|
||||
baseline, so tokens spent before the goal existed are not charged to the goal.
|
||||
|
||||
When token usage reaches the budget, the goal changes to `budget_limited`. This
|
||||
does not delete the goal or erase the objective. It tells the operator and the
|
||||
agent that the goal is no longer actively being pursued until it is resumed or
|
||||
cleared.
|
||||
|
||||
Token budgets are a session-goal guardrail, not a billing cap. Provider quota,
|
||||
cost reporting, and context-window behavior still use the normal OpenClaw
|
||||
usage and model controls.
|
||||
|
||||
## Model tools
|
||||
|
||||
OpenClaw exposes three core goal tools to agent harnesses:
|
||||
|
||||
- `get_goal`: read the current session goal, including status, objective, token
|
||||
usage, and token budget.
|
||||
- `create_goal`: create a goal only when the user, system, or developer
|
||||
instructions explicitly request one. It fails if the session already has a
|
||||
goal.
|
||||
- `update_goal`: mark the goal `complete` or `blocked`.
|
||||
|
||||
The model cannot silently pause, resume, clear, or replace a goal. Those are
|
||||
operator/session controls through `/goal` and reset commands. This keeps the
|
||||
agent from quietly moving the target while preserving a clean path for the
|
||||
agent to report achievement or a genuine blocker.
|
||||
|
||||
The `update_goal` tool should mark a goal `complete` only when the objective is
|
||||
actually achieved. It should mark a goal `blocked` only when the same blocking
|
||||
condition has repeated and the agent cannot make meaningful progress without
|
||||
new user input or an external-state change.
|
||||
|
||||
## TUI
|
||||
|
||||
The TUI keeps the active session's goal visible in the footer next to the
|
||||
agent, session, model, run controls, and token counts.
|
||||
|
||||
Footer examples:
|
||||
|
||||
- `Pursuing goal (12k/50k)` for an active goal with a token budget.
|
||||
- `Goal paused (/goal resume)` for a paused goal.
|
||||
- `Goal blocked (/goal resume)` for a blocked goal.
|
||||
- `Goal hit usage limits (/goal resume)` for a usage-limited goal.
|
||||
- `Goal unmet (50k/50k)` for a budget-limited goal.
|
||||
- `Goal achieved (42k)` for a completed goal.
|
||||
|
||||
The footer is intentionally compact. Use `/goal` for the full objective, note,
|
||||
token budget, and available commands.
|
||||
|
||||
## Channel behavior
|
||||
|
||||
The `/goal` command works in command-capable OpenClaw sessions, including the
|
||||
TUI and chat surfaces that permit text commands. Goal state is attached to the
|
||||
session key, not the transport. If two surfaces use the same session, they see
|
||||
the same goal.
|
||||
|
||||
Goal state is not a delivery directive. It does not force replies through a
|
||||
channel, change queue behavior, approve tools, or schedule work.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
`Goal error: goal already exists` means the session already has a goal. Use
|
||||
`/goal` to inspect it, `/goal complete` if it is done, or `/goal clear` before
|
||||
starting a different objective.
|
||||
|
||||
`Goal error: goal not found` means the session has no goal yet. Start one with
|
||||
`/goal start <objective>`.
|
||||
|
||||
`Goal error: goal is already complete` means the goal is terminal. Clear it
|
||||
before starting or resuming another objective.
|
||||
|
||||
If token usage looks like `0` or stale, the active session may not have a fresh
|
||||
token snapshot yet. Usage refreshes as OpenClaw records session usage and
|
||||
transcript-derived totals.
|
||||
|
||||
## Related
|
||||
|
||||
- [Slash commands](/tools/slash-commands)
|
||||
- [TUI](/web/tui)
|
||||
- [Session tool](/concepts/session-tool)
|
||||
- [Compaction](/concepts/compaction)
|
||||
- [Task Flow](/automation/taskflow)
|
||||
- [Standing orders](/automation/standing-orders)
|
||||
@@ -11,17 +11,18 @@ sidebarTitle: "Image generation"
|
||||
The `image_generate` tool lets the agent create and edit images using your
|
||||
configured providers. In chat sessions, image generation runs asynchronously:
|
||||
OpenClaw records a background task, returns the task id immediately, and wakes
|
||||
the agent when the provider finishes. The completion agent must send generated
|
||||
images through the `message` tool. If the requester session is inactive or
|
||||
its active wake fails, and some generated images are still missing from
|
||||
message-tool delivery, OpenClaw sends an idempotent direct fallback with only
|
||||
the missing images.
|
||||
the agent when the provider finishes. The completion agent follows the
|
||||
session's normal visible-reply mode: automatic final reply delivery when
|
||||
configured, or `message(action="send")` when the session requires the message
|
||||
tool. If the requester session is inactive or its active wake fails, and some
|
||||
generated images are still missing from the completion reply, OpenClaw sends an
|
||||
idempotent direct fallback with only the missing images.
|
||||
|
||||
<Note>
|
||||
The tool only appears when at least one image-generation provider is
|
||||
available. If you do not see `image_generate` in your agent's tools,
|
||||
configure `agents.defaults.imageGenerationModel`, set up a provider API key,
|
||||
or sign in with OpenAI Codex OAuth.
|
||||
or sign in with OpenAI ChatGPT/Codex OAuth.
|
||||
</Note>
|
||||
|
||||
## Quick start
|
||||
@@ -45,9 +46,9 @@ or sign in with OpenAI Codex OAuth.
|
||||
}
|
||||
```
|
||||
|
||||
Codex OAuth uses the same `openai/gpt-image-2` model ref. When an
|
||||
`openai-codex` OAuth profile is configured, OpenClaw routes image
|
||||
requests through that OAuth profile instead of first trying
|
||||
ChatGPT/Codex OAuth uses the same `openai/gpt-image-2` model ref. When an
|
||||
`openai` OAuth profile is configured, OpenClaw routes image requests
|
||||
through that OAuth profile instead of first trying
|
||||
`OPENAI_API_KEY`. Explicit `models.providers.openai` config (API key,
|
||||
custom/Azure base URL) opts back into the direct OpenAI Images API
|
||||
route.
|
||||
@@ -76,7 +77,7 @@ internal image endpoints remain blocked by default.
|
||||
| Goal | Model ref | Auth |
|
||||
| ---------------------------------------------------- | -------------------------------------------------- | -------------------------------------- |
|
||||
| OpenAI image generation with API billing | `openai/gpt-image-2` | `OPENAI_API_KEY` |
|
||||
| OpenAI image generation with Codex subscription auth | `openai/gpt-image-2` | OpenAI Codex OAuth |
|
||||
| OpenAI image generation with Codex subscription auth | `openai/gpt-image-2` | OpenAI ChatGPT/Codex OAuth |
|
||||
| OpenAI transparent-background PNG/WebP | `openai/gpt-image-1.5` | `OPENAI_API_KEY` or OpenAI Codex OAuth |
|
||||
| DeepInfra image generation | `deepinfra/black-forest-labs/FLUX-1-schnell` | `DEEPINFRA_API_KEY` |
|
||||
| fal Krea 2 expressive/style-directed generation | `fal/krea/v2/medium/text-to-image` | `FAL_KEY` |
|
||||
@@ -104,7 +105,7 @@ backend emits it.
|
||||
| Google | `gemini-3.1-flash-image-preview` | Yes | `GEMINI_API_KEY` or `GOOGLE_API_KEY` |
|
||||
| LiteLLM | `gpt-image-2` | Yes (up to 5 input images) | `LITELLM_API_KEY` |
|
||||
| MiniMax | `image-01` | Yes (subject reference) | `MINIMAX_API_KEY` or MiniMax OAuth (`minimax-portal`) |
|
||||
| OpenAI | `gpt-image-2` | Yes (up to 4 images) | `OPENAI_API_KEY` or OpenAI Codex OAuth |
|
||||
| OpenAI | `gpt-image-2` | Yes (up to 4 images) | `OPENAI_API_KEY` or OpenAI ChatGPT/Codex OAuth |
|
||||
| OpenRouter | `google/gemini-3.1-flash-image-preview` | Yes (up to 5 input images) | `OPENROUTER_API_KEY` |
|
||||
| Vydra | `grok-imagine` | No | `VYDRA_API_KEY` |
|
||||
| xAI | `grok-imagine-image` | Yes (up to 5 images) | `XAI_API_KEY` |
|
||||
@@ -279,7 +280,7 @@ to 10 for GPT Image 2 edits, up to 10 style references for Krea 2, and up to
|
||||
<AccordionGroup>
|
||||
<Accordion title="OpenAI gpt-image-2 (and gpt-image-1.5)">
|
||||
OpenAI image generation defaults to `openai/gpt-image-2`. If an
|
||||
`openai-codex` OAuth profile is configured, OpenClaw reuses the same
|
||||
`openai` OAuth profile is configured, OpenClaw reuses the same
|
||||
OAuth profile used by Codex subscription chat models and sends the
|
||||
image request through the Codex Responses backend. Legacy Codex base
|
||||
URLs such as `https://chatgpt.com/backend-api` are canonicalized to
|
||||
|
||||
@@ -78,18 +78,18 @@ The table lists representative tools so you can recognize the surface. It is
|
||||
not the full policy reference. For exact groups, defaults, and allow/deny
|
||||
semantics, use [Tools and custom providers](/gateway/config-tools).
|
||||
|
||||
| Category | Use when the agent needs to... | Representative tools | Read next |
|
||||
| ----------------------- | ----------------------------------------------------------------------------- | -------------------------------------------------------------------- | ---------------------------------------------------------------------- |
|
||||
| Runtime | Run commands, manage processes, or use provider-backed Python analysis | `exec`, `process`, `code_execution` | [Exec](/tools/exec), [Code execution](/tools/code-execution) |
|
||||
| Files | Read and change workspace files | `read`, `write`, `edit`, `apply_patch` | [Apply patch](/tools/apply-patch) |
|
||||
| Web | Search the web, search X posts, or fetch readable page content | `web_search`, `x_search`, `web_fetch` | [Web tools](/tools/web), [Web fetch](/tools/web-fetch) |
|
||||
| Browser | Operate a browser session | `browser` | [Browser](/tools/browser) |
|
||||
| Messaging and channels | Send replies or channel actions | `message` | [Agent send](/tools/agent-send) |
|
||||
| Sessions and agents | Inspect sessions, delegate work, steer another run, or report status | `sessions_*`, `subagents`, `agents_list`, `session_status` | [Sub-agents](/tools/subagents), [Session tool](/concepts/session-tool) |
|
||||
| Automation | Schedule work or respond to background events | `cron`, `heartbeat_respond` | [Automation](/automation) |
|
||||
| Gateway and nodes | Inspect Gateway state or paired target devices | `gateway`, `nodes` | [Gateway configuration](/gateway/configuration), [Nodes](/nodes) |
|
||||
| Media | Analyze, generate, or speak media | `image`, `image_generate`, `music_generate`, `video_generate`, `tts` | [Media overview](/tools/media-overview) |
|
||||
| Large OpenClaw catalogs | Search and call many eligible tools without sending every schema to the model | `tool_search_code`, `tool_search`, `tool_describe` | [Tool Search](/tools/tool-search) |
|
||||
| Category | Use when the agent needs to... | Representative tools | Read next |
|
||||
| ----------------------- | ----------------------------------------------------------------------------- | -------------------------------------------------------------------- | ------------------------------------------------------------------------------------------- |
|
||||
| Runtime | Run commands, manage processes, or use provider-backed Python analysis | `exec`, `process`, `code_execution` | [Exec](/tools/exec), [Code execution](/tools/code-execution) |
|
||||
| Files | Read and change workspace files | `read`, `write`, `edit`, `apply_patch` | [Apply patch](/tools/apply-patch) |
|
||||
| Web | Search the web, search X posts, or fetch readable page content | `web_search`, `x_search`, `web_fetch` | [Web tools](/tools/web), [Web fetch](/tools/web-fetch) |
|
||||
| Browser | Operate a browser session | `browser` | [Browser](/tools/browser) |
|
||||
| Messaging and channels | Send replies or channel actions | `message` | [Agent send](/tools/agent-send) |
|
||||
| Sessions and agents | Inspect sessions, delegate work, steer another run, or report status | `sessions_*`, `subagents`, `agents_list`, `session_status`, `goal` | [Goal](/tools/goal), [Sub-agents](/tools/subagents), [Session tool](/concepts/session-tool) |
|
||||
| Automation | Schedule work or respond to background events | `cron`, `heartbeat_respond` | [Automation](/automation) |
|
||||
| Gateway and nodes | Inspect Gateway state or paired target devices | `gateway`, `nodes` | [Gateway configuration](/gateway/configuration), [Nodes](/nodes) |
|
||||
| Media | Analyze, generate, or speak media | `image`, `image_generate`, `music_generate`, `video_generate`, `tts` | [Media overview](/tools/media-overview) |
|
||||
| Large OpenClaw catalogs | Search and call many eligible tools without sending every schema to the model | `tool_search_code`, `tool_search`, `tool_describe` | [Tool Search](/tools/tool-search) |
|
||||
|
||||
<Note>
|
||||
Tool Search is an experimental OpenClaw agent surface. Codex harness runs use
|
||||
|
||||
@@ -47,10 +47,10 @@ Use `tools.allow` only when you want restrictive allowlist mode.
|
||||
"llm-task": {
|
||||
"enabled": true,
|
||||
"config": {
|
||||
"defaultProvider": "openai-codex",
|
||||
"defaultProvider": "openai",
|
||||
"defaultModel": "gpt-5.5",
|
||||
"defaultAuthProfileId": "main",
|
||||
"allowedModels": ["openai/gpt-5.4"],
|
||||
"allowedModels": ["openai/gpt-5.5"],
|
||||
"maxTokens": 800,
|
||||
"timeoutMs": 30000
|
||||
}
|
||||
|
||||
@@ -98,11 +98,12 @@ For async tools, OpenClaw submits the request to the provider, returns a task
|
||||
id immediately, and tracks the job in the task ledger. The agent continues
|
||||
responding to other messages while the job runs. When the provider finishes,
|
||||
OpenClaw wakes the agent with the generated media paths so it can tell the
|
||||
user and relay the result through the message tool. If the requester session
|
||||
is inactive or its active wake fails, and some generated media is still
|
||||
missing from message-tool delivery, OpenClaw sends an idempotent direct
|
||||
fallback with only the missing media. Media already delivered through the
|
||||
message tool is not posted again.
|
||||
user through the session's normal visible-reply mode: automatic final reply
|
||||
delivery when configured, or `message(action="send")` when the session requires
|
||||
the message tool. If the requester session is inactive or its active wake
|
||||
fails, and some generated media is still missing from the completion reply,
|
||||
OpenClaw sends an idempotent direct fallback with only the missing media. Media
|
||||
already delivered by the completion reply is not posted again.
|
||||
|
||||
## Speech-to-text and Voice Call
|
||||
|
||||
|
||||
@@ -15,12 +15,12 @@ fal, Google, MiniMax, and OpenRouter today.
|
||||
For session-backed agent runs, OpenClaw starts music generation as a
|
||||
background task, tracks it in the task ledger, then wakes the agent again
|
||||
when the track is ready so the agent can tell the user and attach the
|
||||
finished audio. Generated-media completions are delivered by the agent through
|
||||
the message tool. If the requester session is inactive or its active wake
|
||||
fails, and some generated audio is still missing from message-tool delivery,
|
||||
OpenClaw sends an idempotent direct fallback with only the missing audio. The
|
||||
completion wake explicitly warns the agent that normal final replies are
|
||||
private for this route.
|
||||
finished audio. The completion agent follows the session's normal visible-reply
|
||||
mode: automatic final reply delivery when configured, or `message(action="send")`
|
||||
when the session requires the message tool. If the requester session is
|
||||
inactive or its active wake fails, and some generated audio is still missing
|
||||
from the completion reply, OpenClaw sends an idempotent direct fallback with
|
||||
only the missing audio.
|
||||
|
||||
<Note>
|
||||
The built-in shared tool only appears when at least one music-generation
|
||||
|
||||
@@ -186,7 +186,7 @@ Key policy rules:
|
||||
surfaces, such as a provider/model ref, channel config, CLI backend, or agent
|
||||
harness runtime.
|
||||
- OpenAI-family Codex routing keeps provider and runtime plugin boundaries
|
||||
separate: `openai-codex/*` is legacy OpenAI-provider config, while the bundled
|
||||
separate: `openai-codex/*` is legacy config repaired by doctor, while the bundled
|
||||
`codex` plugin owns Codex app-server runtime for canonical `openai/*` agent
|
||||
refs, explicit `agentRuntime.id: "codex"`, and legacy `codex/*` refs.
|
||||
|
||||
|
||||
@@ -153,6 +153,7 @@ Current source-of-truth:
|
||||
- `/commands` shows the generated command catalog.
|
||||
- `/tools [compact|verbose]` shows what the current agent can use right now.
|
||||
- `/status` shows execution/runtime status, Gateway and system uptime, plus provider usage/quota when available.
|
||||
- `/goal [status] | /goal start <objective> | /goal pause|resume|complete|block|clear` manages the current session's durable [goal](/tools/goal).
|
||||
- `/diagnostics [note]` is the owner-only support-report flow for Gateway bugs and Codex harness runs. It asks for explicit exec approval every time before running `openclaw gateway diagnostics export --json`; do not approve diagnostics with an allow-all rule. After approval, it sends a pasteable report with the local bundle path, manifest summary, privacy notes, and relevant session ids. In group chats, the approval prompt and report go to the owner privately. When the active session uses the OpenAI Codex harness, the same approval also sends relevant Codex feedback to OpenAI servers and the completed reply lists the OpenClaw session ids, Codex thread ids, and `codex resume <thread-id>` commands. See [Diagnostics Export](/gateway/diagnostics).
|
||||
- `/crestodian <request>` runs the Crestodian setup and repair helper from an owner DM.
|
||||
- `/tasks` lists active/recent background tasks for the current session.
|
||||
|
||||
@@ -70,7 +70,7 @@ title: "Thinking levels"
|
||||
4. Per-model config: `agents.defaults.models["<provider>/<model>"].params.fastMode`
|
||||
5. Fallback: `off`
|
||||
- For `openai/*`, fast mode maps to OpenAI priority processing by sending `service_tier=priority` on supported Responses requests.
|
||||
- For `openai-codex/*`, fast mode sends the same `service_tier=priority` flag on Codex Responses. OpenClaw keeps one shared `/fast` toggle across both auth paths.
|
||||
- For Codex-backed `openai/*` models, fast mode sends the same `service_tier=priority` flag on Codex Responses. OpenClaw keeps one shared `/fast` toggle across both auth paths.
|
||||
- For direct public `anthropic/*` requests, including OAuth-authenticated traffic sent to `api.anthropic.com`, fast mode maps to Anthropic service tiers: `/fast on` sets `service_tier=auto`, `/fast off` sets `service_tier=standard_only`.
|
||||
- For `minimax/*` on the Anthropic-compatible path, `/fast on` (or `params.fastMode: true`) rewrites `MiniMax-M2.7` to `MiniMax-M2.7-highspeed`.
|
||||
- Explicit Anthropic `serviceTier` / `service_tier` model params override the fast-mode default when both are set. OpenClaw still skips Anthropic service-tier injection for non-Anthropic proxy base URLs.
|
||||
|
||||
@@ -62,10 +62,12 @@ session:
|
||||
1. OpenClaw submits the request to the provider and immediately returns a task id.
|
||||
2. The provider processes the job in the background (typically 30 seconds to several minutes depending on the provider and resolution; slow queue-backed providers can run up to the configured timeout).
|
||||
3. When the video is ready, OpenClaw wakes the same session with an internal completion event.
|
||||
4. The agent tells the user and attaches the finished video through the
|
||||
message tool. If the requester session is inactive or its active wake
|
||||
fails, and some generated video is still missing from message-tool delivery,
|
||||
OpenClaw sends an idempotent direct fallback with only the missing video.
|
||||
4. The agent tells the user through the session's normal visible-reply mode:
|
||||
final reply delivery when automatic, or `message(action="send")` when the
|
||||
session requires the message tool. If the requester session is inactive or
|
||||
its active wake fails, and some generated video is still missing from the
|
||||
completion reply, OpenClaw sends an idempotent direct fallback with only the
|
||||
missing video.
|
||||
|
||||
While a job is in flight, duplicate `video_generate` calls in the same
|
||||
session return the current task status instead of starting another
|
||||
|
||||
@@ -123,7 +123,7 @@ Direct OpenAI Responses models use OpenAI's hosted `web_search` tool automatical
|
||||
Codex-capable models can optionally use the provider-native Responses `web_search` tool instead of OpenClaw's managed `web_search` function.
|
||||
|
||||
- Configure it under `tools.web.search.openaiCodex`
|
||||
- It only activates for Codex-capable models (`openai-codex/*` or providers using `api: "openai-codex-responses"`)
|
||||
- It only activates for Codex-capable OpenAI models (`openai/*` models using `api: "openai-codex-responses"`)
|
||||
- Managed `web_search` still applies to non-Codex models
|
||||
- `mode: "cached"` is the default and recommended setting
|
||||
- `tools.web.search.enabled: false` disables both managed and native search
|
||||
|
||||
@@ -183,7 +183,7 @@ Activity entries keep only sanitized summaries and redacted, truncated output pr
|
||||
|
||||
</Accordion>
|
||||
<Accordion title="Talk mode (browser realtime)">
|
||||
Talk mode uses a registered realtime voice provider. Configure OpenAI with `talk.realtime.provider: "openai"` plus either `talk.realtime.providers.openai.apiKey`, `OPENAI_API_KEY`, or an `openai-codex` OAuth profile; configure Google with `talk.realtime.provider: "google"` plus `talk.realtime.providers.google.apiKey`. For hosted GPT realtime models, OpenClaw prefers the `openai-codex` OAuth profile before `OPENAI_API_KEY`; an explicit OpenAI realtime `apiKey` remains the advanced override. The browser never receives a standard provider API key. OpenAI receives an ephemeral Realtime client secret for WebRTC. Google Live receives a one-use constrained Live API auth token for a browser WebSocket session, with instructions and tool declarations locked into the token by the Gateway. Providers that only expose a backend realtime bridge run through the Gateway relay transport, so credentials and vendor sockets stay server-side while browser audio moves through authenticated Gateway RPCs. The Realtime session prompt is assembled by the Gateway; `talk.client.create` does not accept caller-provided instruction overrides.
|
||||
Talk mode uses a registered realtime voice provider. Configure OpenAI with `talk.realtime.provider: "openai"` plus either `talk.realtime.providers.openai.apiKey`, `OPENAI_API_KEY`, or an `openai` OAuth profile; configure Google with `talk.realtime.provider: "google"` plus `talk.realtime.providers.google.apiKey`. For hosted GPT realtime models, OpenClaw prefers the `openai` OAuth profile before `OPENAI_API_KEY`; an explicit OpenAI realtime `apiKey` remains the advanced override. The browser never receives a standard provider API key. OpenAI receives an ephemeral Realtime client secret for WebRTC. Google Live receives a one-use constrained Live API auth token for a browser WebSocket session, with instructions and tool declarations locked into the token by the Gateway. Providers that only expose a backend realtime bridge run through the Gateway relay transport, so credentials and vendor sockets stay server-side while browser audio moves through authenticated Gateway RPCs. The Realtime session prompt is assembled by the Gateway; `talk.client.create` does not accept caller-provided instruction overrides.
|
||||
|
||||
The Chat composer includes a Talk options button next to the Talk start/stop button. The options apply to the next Talk session and can override provider, transport, model, voice, reasoning effort, VAD threshold, silence duration, and prefix padding. When an option is blank, the Gateway uses configured defaults where available or the provider default. Selecting Gateway relay forces the backend relay path; selecting WebRTC keeps the session client-owned and fails instead of silently falling back to relay if the provider cannot create a browser session.
|
||||
|
||||
|
||||
@@ -54,7 +54,7 @@ Notes:
|
||||
- Header: connection URL, current agent, current session.
|
||||
- Chat log: user messages, assistant replies, system notices, tool cards.
|
||||
- Status line: connection/run state (connecting, running, streaming, idle, error).
|
||||
- Footer: connection state + agent + session + model + think/fast/verbose/trace/reasoning + token counts + deliver.
|
||||
- Footer: connection state + agent + session + model + goal state + think/fast/verbose/trace/reasoning + token counts + deliver.
|
||||
- Input: text editor with autocomplete.
|
||||
|
||||
## Mental model: agents + sessions
|
||||
@@ -68,6 +68,9 @@ Notes:
|
||||
- `per-sender` (default): each agent has many sessions.
|
||||
- `global`: the TUI always uses the `global` session (the picker may be empty).
|
||||
- The current agent + session are always visible in the footer.
|
||||
- If the session has a [goal](/tools/goal), the footer shows its compact state
|
||||
such as `Pursuing goal`, `Goal paused (/goal resume)`, or
|
||||
`Goal achieved`.
|
||||
- When started without `--session`, gateway-mode TUI resumes the last selected session for the same gateway, agent, and session scope if that session still exists. Passing `--session`, `/session`, `/new`, or `/reset` remains explicit.
|
||||
|
||||
## Sending + delivery
|
||||
@@ -116,6 +119,7 @@ Session controls:
|
||||
- `/trace <on|off>`
|
||||
- `/reasoning <on|off|stream>`
|
||||
- `/usage <off|tokens|full>`
|
||||
- `/goal [status] | /goal start <objective> | /goal pause|resume|complete|block|clear`
|
||||
- `/elevated <on|off|ask|full>` (alias: `/elev`)
|
||||
- `/activation <mention|always>`
|
||||
- `/deliver <on|off>`
|
||||
|
||||
4
extensions/acpx/npm-shrinkwrap.json
generated
4
extensions/acpx/npm-shrinkwrap.json
generated
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/acpx",
|
||||
"version": "2026.5.28",
|
||||
"version": "2026.5.30",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/acpx",
|
||||
"version": "2026.5.28",
|
||||
"version": "2026.5.30",
|
||||
"dependencies": {
|
||||
"@agentclientprotocol/claude-agent-acp": "0.37.0",
|
||||
"@zed-industries/codex-acp": "0.15.0",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/acpx",
|
||||
"version": "2026.5.28",
|
||||
"version": "2026.5.30",
|
||||
"description": "OpenClaw ACP runtime backend with plugin-owned session and transport management.",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
@@ -26,10 +26,10 @@
|
||||
"minHostVersion": ">=2026.4.25"
|
||||
},
|
||||
"compat": {
|
||||
"pluginApi": ">=2026.5.28"
|
||||
"pluginApi": ">=2026.5.30"
|
||||
},
|
||||
"build": {
|
||||
"openclawVersion": "2026.5.28",
|
||||
"openclawVersion": "2026.5.30",
|
||||
"staticAssets": [
|
||||
{
|
||||
"source": "./src/runtime-internals/mcp-proxy.mjs",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/admin-http-rpc",
|
||||
"version": "2026.5.28",
|
||||
"version": "2026.5.30",
|
||||
"private": true,
|
||||
"description": "OpenClaw admin HTTP RPC endpoint",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@openclaw/alibaba-provider",
|
||||
"version": "2026.5.28",
|
||||
"version": "2026.5.30",
|
||||
"private": true,
|
||||
"description": "OpenClaw Alibaba Model Studio video provider plugin",
|
||||
"type": "module",
|
||||
|
||||
@@ -1,12 +1,12 @@
|
||||
{
|
||||
"name": "@openclaw/amazon-bedrock-mantle-provider",
|
||||
"version": "2026.5.28",
|
||||
"version": "2026.5.30",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "@openclaw/amazon-bedrock-mantle-provider",
|
||||
"version": "2026.5.28",
|
||||
"version": "2026.5.30",
|
||||
"dependencies": {
|
||||
"@anthropic-ai/sdk": "0.98.0",
|
||||
"@aws/bedrock-token-generator": "1.1.0"
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user