Skip to content

Commit 9768eb4

Browse files
committed
Auto-merge upstream openclaw/openclaw
2 parents ffe4530 + 4ed60d9 commit 9768eb4

96 files changed

Lines changed: 6384 additions & 368 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

CHANGELOG.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ Docs: https://docs.openclaw.ai
5050
### Fixes
5151

5252
- Security: preserve restrictive plugin-only tool allowlists, require owner access for `/allowlist add` and `/allowlist remove`, fail closed when `before_tool_call` hooks crash, block browser SSRF redirect bypasses earlier, and keep non-interactive auth-choice inference scoped to bundled and already-trusted plugins. (#58476, #59836, #59822, #58771, #59120) Thanks @eleqtrizit and @pgondhi987.
53+
- Gateway/pairing: keep silent local first-pair compatibility, but seed new operator device tokens from a bounded server-owned baseline instead of persisting requested admin scopes, so shared-auth localhost connects cannot silently self-upgrade into paired admin. Thanks @smaeljaish771.
5354
- Providers/OpenAI: make GPT-5 and Codex runs act sooner with lower-verbosity defaults, visible progress during tool work, and a one-shot retry when a turn only narrates the plan instead of taking action.
5455
- Providers/OpenAI: preserve native `reasoning.effort: “none”` and strict tool schemas on direct OpenAI-family endpoints, keep compat routes on compat shaping, fix Responses WebSocket warm-up behavior, keep stable session and turn metadata, and fall back more gracefully after early WebSocket failures.
5556
- Providers/OpenAI: support GPT-5.4 assistant `phase` metadata across OpenAI-family Responses replay and the Gateway `/v1/responses` compatibility layer, including `commentary` tool preambles and `final_answer` replies.
@@ -78,6 +79,7 @@ Docs: https://docs.openclaw.ai
7879
- MS Teams: download inline DM images via Graph API and preserve channel reply threading in proactive fallback. (#52212, #55198) Thanks @Ted-developer and @hyojin.
7980
- MS Teams: replace the deprecated Teams SDK HttpPlugin stub with `httpServerAdapter` so recurring gateway deprecation warnings stop firing and the Express 5 compatibility workaround stays on the supported SDK path. (#60939) Thanks @coolramukaka-sys.
8081
- Control UI/chat: add a per-session thinking-level picker in the chat header and mobile chat settings, and keep the browser bundle on UI-local thinking/session-key helpers so Safari no longer crashes on Node-only imports before rendering chat controls.
82+
- Sandbox/SSH: reject hardlinked files during cross-device rename fallback so EXDEV file copies preserve the same pinned file-boundary checks as direct reads.
8183
- Control UI: keep Stop visible during tool-only execution, preserve pending-send busy state, and clear stale ClawHub search results as soon as the query changes. (#54528, #59800, #60267) Thanks @chziyue and @frankekn.
8284
- Control UI/avatar: honor `ui.assistant.avatar` when serving `/avatar/:agentId` so Appearance UI avatar paths stop falling back to initials placeholders. (#60778) Thanks @hannasdev.
8385
- Control UI/cron: highlight the Cron refresh button while refresh is in flight so the page's loading state stays visible even when prior data remains on screen. (#60394) Thanks @coder-zhuzm.
@@ -118,6 +120,7 @@ Docs: https://docs.openclaw.ai
118120
- Outbound/sanitizer: strip leaked `<tool_call>`, `<function_calls>`, and model special tokens from shared user-visible assistant text, including truncated tool-call streams, so internal scaffolding no longer bleeds into replies across surfaces. (#60619) Thanks @oliviareid-svg.
119121
- Agents/errors: surface an explicit disk-full message when local session or transcript writes fail with `ENOSPC`/`disk full`, so those runs stop degrading into opaque `NO_REPLY`-style failures. Thanks @vincentkoc.
120122
- Exec approvals: remove heuristic command-obfuscation gating from host exec so gateway and node runs rely on explicit policy, allowlist, and strict inline-eval rules only.
123+
- Agents/tool results: cap live tool-result persistence and overflow-recovery truncation at 40k characters so oversized tool output stays bounded without discarding recent context entirely.
121124
- Config/All Settings: keep the raw config view intact when sensitive fields are blank instead of corrupting or dropping the rendered snapshot. (#28214) Thanks @solodmd.
122125
- Plugin SDK/facades: back-fill bundled plugin facade sentinels before plugin-id tracking re-enters config loading, so CLI/provider startup no longer crashes with `shouldNormalizeGoogleProviderConfig is not a function` or other empty-facade reads during bundled plugin re-entry. Thanks @adam91holt.
123126
- Plugins/facades: back-fill facade sentinels before tracked-plugin resolution re-enters config loading, so facade exports stay defined during circular provider normalization. (#61180) Thanks @adam91holt.

docs/cli/models.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,8 @@ Current usage-window providers: Anthropic, GitHub Copilot, Gemini CLI, OpenAI
3131
Codex, MiniMax, Xiaomi, and z.ai. Usage auth comes from provider-specific hooks
3232
when available; otherwise OpenClaw falls back to matching OAuth/API-key
3333
credentials from auth profiles, env, or config.
34+
In `--json` output, `auth.providers` is the env/config/store-aware provider
35+
overview, while `auth.oauth` is auth-store profile health only.
3436
Add `--probe` to run live auth probes against each configured provider profile.
3537
Probes are real requests (may consume tokens and trigger rate limits).
3638
Use `--agent <id>` to inspect a configured agent’s model/auth state. When omitted,

docs/concepts/models.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,8 @@ resolved primary model.
175175
OAuth status is always shown (and included in `--json` output). If a configured
176176
provider has no credentials, `models status` prints a **Missing auth** section.
177177
JSON includes `auth.oauth` (warn window + profiles) and `auth.providers`
178-
(effective auth per provider).
178+
(effective auth per provider, including env-backed credentials). `auth.oauth`
179+
is auth-store profile health only; env-only providers do not appear there.
179180
Use `--check` for automation (exit `1` when missing/expired, `2` when expiring).
180181
Use `--probe` for live auth checks; probe rows can come from auth profiles, env
181182
credentials, or `models.json`.

docs/gateway/protocol.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -540,6 +540,9 @@ implemented in `src/gateway/server-methods/*.ts`.
540540
- Pairing auto-approval is centered on direct local loopback connects.
541541
- OpenClaw also has a narrow backend/container-local self-connect path for
542542
trusted shared-secret helper flows.
543+
- Local auto-approval for operator devices seeds a bounded per-device token
544+
baseline instead of persisting arbitrary requested operator scopes. A shared-
545+
secret session may still be broader than the silently issued device token.
543546
- Same-host tailnet or LAN connects are still treated as remote for pairing and
544547
require approval.
545548
- All WS clients must include `device` identity during `connect` (operator + node).

docs/install/docker.md

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -103,12 +103,7 @@ docker build -t openclaw:local -f Dockerfile .
103103
docker compose run --rm --no-deps --entrypoint node openclaw-gateway \
104104
dist/index.js onboard --mode local --no-install-daemon
105105
docker compose run --rm --no-deps --entrypoint node openclaw-gateway \
106-
dist/index.js config set gateway.mode local
107-
docker compose run --rm --no-deps --entrypoint node openclaw-gateway \
108-
dist/index.js config set gateway.bind lan
109-
docker compose run --rm --no-deps --entrypoint node openclaw-gateway \
110-
dist/index.js config set gateway.controlUi.allowedOrigins \
111-
'["http://localhost:18789","http://127.0.0.1:18789"]' --strict-json
106+
dist/index.js config set --batch-json '[{"path":"gateway.mode","value":"local"},{"path":"gateway.bind","value":"lan"},{"path":"gateway.controlUi.allowedOrigins","value":["http://localhost:18789","http://127.0.0.1:18789"]}]'
112107
docker compose up -d openclaw-gateway
113108
```
114109

@@ -395,8 +390,7 @@ scripts/sandbox-setup.sh
395390
Reset gateway mode and bind:
396391

397392
```bash
398-
docker compose run --rm openclaw-cli config set gateway.mode local
399-
docker compose run --rm openclaw-cli config set gateway.bind lan
393+
docker compose run --rm openclaw-cli config set --batch-json '[{"path":"gateway.mode","value":"local"},{"path":"gateway.bind","value":"lan"}]'
400394
docker compose run --rm openclaw-cli devices list --url ws://127.0.0.1:18789
401395
```
402396

docs/tools/video-generation.md

Lines changed: 18 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
---
2-
summary: "Generate videos using configured providers such as Qwen"
2+
summary: "Generate videos using configured providers such as OpenAI, Google, Qwen, and MiniMax"
33
read_when:
44
- Generating videos via the agent
55
- Configuring video generation providers and models
@@ -17,7 +17,7 @@ The tool only appears when at least one video-generation provider is available.
1717

1818
## Quick start
1919

20-
1. Set an API key for at least one provider (for example `QWEN_API_KEY`).
20+
1. Set an API key for at least one provider (for example `OPENAI_API_KEY`, `GEMINI_API_KEY`, or `QWEN_API_KEY`).
2121
2. Optionally set your preferred model:
2222

2323
```json5
@@ -36,9 +36,15 @@ The agent calls `video_generate` automatically. No tool allow-listing needed —
3636

3737
## Supported providers
3838

39-
| Provider | Default model | Reference inputs | API key |
40-
| -------- | ------------- | ---------------- | ---------------------------------------------------------- |
41-
| Qwen | `wan2.6-t2v` | Yes, remote URLs | `QWEN_API_KEY`, `MODELSTUDIO_API_KEY`, `DASHSCOPE_API_KEY` |
39+
| Provider | Default model | Reference inputs | API key |
40+
| -------- | ------------------------------- | ------------------ | ---------------------------------------------------------- |
41+
| BytePlus | `seedance-1-0-lite-t2v-250428` | 1 image | `BYTEPLUS_API_KEY` |
42+
| fal | `fal-ai/minimax/video-01-live` | 1 image | `FAL_KEY` |
43+
| Google | `veo-3.1-fast-generate-preview` | 1 image or 1 video | `GEMINI_API_KEY`, `GOOGLE_API_KEY` |
44+
| MiniMax | `MiniMax-Hailuo-2.3` | 1 image | `MINIMAX_API_KEY` |
45+
| OpenAI | `sora-2` | 1 image or 1 video | `OPENAI_API_KEY` |
46+
| Qwen | `wan2.6-t2v` | Yes, remote URLs | `QWEN_API_KEY`, `MODELSTUDIO_API_KEY`, `DASHSCOPE_API_KEY` |
47+
| Together | `Wan-AI/Wan2.2-T2V-A14B` | 1 image | `TOGETHER_API_KEY` |
4248

4349
Use `action: "list"` to inspect available providers and models at runtime:
4450

@@ -97,6 +103,13 @@ When generating a video, OpenClaw tries providers in this order:
97103

98104
If a provider fails, the next candidate is tried automatically. If all fail, the error includes details from each attempt.
99105

106+
## Provider notes
107+
108+
- OpenAI uses the native video endpoint and currently defaults to `sora-2`.
109+
- Google uses Gemini/Veo and supports a single image or video reference input.
110+
- MiniMax, Together, BytePlus, and fal currently support a single image reference input.
111+
- Qwen supports image/video references, but the upstream DashScope video endpoint currently requires remote `http(s)` URLs for those references.
112+
100113
## Qwen reference inputs
101114

102115
The bundled Qwen provider supports text-to-video plus image/video reference modes, but the upstream DashScope video endpoint currently requires **remote http(s) URLs** for reference inputs. Local file paths and uploaded buffers are rejected up front instead of being silently ignored.

extensions/byteplus/index.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import { createProviderApiKeyAuthMethod } from "openclaw/plugin-sdk/provider-aut
33
import { ensureModelAllowlistEntry } from "openclaw/plugin-sdk/provider-onboard";
44
import { BYTEPLUS_CODING_MODEL_CATALOG, BYTEPLUS_MODEL_CATALOG } from "./models.js";
55
import { buildBytePlusCodingProvider, buildBytePlusProvider } from "./provider-catalog.js";
6+
import { buildBytePlusVideoGenerationProvider } from "./video-generation-provider.js";
67

78
const PROVIDER_ID = "byteplus";
89
const BYTEPLUS_DEFAULT_MODEL_REF = "byteplus-plan/ark-code-latest";
@@ -78,5 +79,6 @@ export default definePluginEntry({
7879
return [...byteplusModels, ...byteplusPlanModels];
7980
},
8081
});
82+
api.registerVideoGenerationProvider(buildBytePlusVideoGenerationProvider());
8183
},
8284
});

extensions/byteplus/openclaw.plugin.json

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@
2020
"cliDescription": "BytePlus API key"
2121
}
2222
],
23+
"contracts": {
24+
"videoGenerationProviders": ["byteplus"]
25+
},
2326
"configSchema": {
2427
"type": "object",
2528
"additionalProperties": false,
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import { describePluginRegistrationContract } from "../../test/helpers/plugins/plugin-registration-contract.js";
2+
3+
describePluginRegistrationContract({
4+
pluginId: "byteplus",
5+
providerIds: ["byteplus", "byteplus-plan"],
6+
videoGenerationProviderIds: ["byteplus"],
7+
requireGenerateVideo: true,
8+
});
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
import { afterEach, describe, expect, it, vi } from "vitest";
2+
import { buildBytePlusVideoGenerationProvider } from "./video-generation-provider.js";
3+
4+
const {
5+
resolveApiKeyForProviderMock,
6+
postJsonRequestMock,
7+
fetchWithTimeoutMock,
8+
assertOkOrThrowHttpErrorMock,
9+
resolveProviderHttpRequestConfigMock,
10+
} = vi.hoisted(() => ({
11+
resolveApiKeyForProviderMock: vi.fn(async () => ({ apiKey: "byteplus-key" })),
12+
postJsonRequestMock: vi.fn(),
13+
fetchWithTimeoutMock: vi.fn(),
14+
assertOkOrThrowHttpErrorMock: vi.fn(async () => {}),
15+
resolveProviderHttpRequestConfigMock: vi.fn((params) => ({
16+
baseUrl: params.baseUrl ?? params.defaultBaseUrl,
17+
allowPrivateNetwork: false,
18+
headers: new Headers(params.defaultHeaders),
19+
dispatcherPolicy: undefined,
20+
})),
21+
}));
22+
23+
vi.mock("openclaw/plugin-sdk/provider-auth-runtime", () => ({
24+
resolveApiKeyForProvider: resolveApiKeyForProviderMock,
25+
}));
26+
27+
vi.mock("openclaw/plugin-sdk/provider-http", () => ({
28+
assertOkOrThrowHttpError: assertOkOrThrowHttpErrorMock,
29+
fetchWithTimeout: fetchWithTimeoutMock,
30+
postJsonRequest: postJsonRequestMock,
31+
resolveProviderHttpRequestConfig: resolveProviderHttpRequestConfigMock,
32+
}));
33+
34+
describe("byteplus video generation provider", () => {
35+
afterEach(() => {
36+
resolveApiKeyForProviderMock.mockClear();
37+
postJsonRequestMock.mockReset();
38+
fetchWithTimeoutMock.mockReset();
39+
assertOkOrThrowHttpErrorMock.mockClear();
40+
resolveProviderHttpRequestConfigMock.mockClear();
41+
});
42+
43+
it("creates a content-generation task, polls, and downloads the video", async () => {
44+
postJsonRequestMock.mockResolvedValue({
45+
response: {
46+
json: async () => ({
47+
id: "task_123",
48+
}),
49+
},
50+
release: vi.fn(async () => {}),
51+
});
52+
fetchWithTimeoutMock
53+
.mockResolvedValueOnce({
54+
json: async () => ({
55+
id: "task_123",
56+
status: "succeeded",
57+
content: {
58+
video_url: "https://example.com/byteplus.mp4",
59+
},
60+
model: "seedance-1-0-lite-t2v-250428",
61+
}),
62+
})
63+
.mockResolvedValueOnce({
64+
headers: new Headers({ "content-type": "video/mp4" }),
65+
arrayBuffer: async () => Buffer.from("mp4-bytes"),
66+
});
67+
68+
const provider = buildBytePlusVideoGenerationProvider();
69+
const result = await provider.generateVideo({
70+
provider: "byteplus",
71+
model: "seedance-1-0-lite-t2v-250428",
72+
prompt: "A lantern floats upward into the night sky",
73+
cfg: {},
74+
});
75+
76+
expect(postJsonRequestMock).toHaveBeenCalledWith(
77+
expect.objectContaining({
78+
url: "https://ark.ap-southeast.bytepluses.com/api/v3/contents/generations/tasks",
79+
}),
80+
);
81+
expect(result.videos).toHaveLength(1);
82+
expect(result.metadata).toEqual(
83+
expect.objectContaining({
84+
taskId: "task_123",
85+
}),
86+
);
87+
});
88+
});

0 commit comments

Comments
 (0)