Skip to content

Commit df47181

Browse files
authored
Merge branch 'main' into fix/echo-transcript-dollar-substitution
2 parents 04b307e + c29054a commit df47181

17 files changed

Lines changed: 109 additions & 13 deletions
Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
729181bf726ea51bebfa51c760eff8d5016933c21815e47197b5d05db8d549d5 plugin-sdk-api-baseline.json
2-
d8add92c9c5445e8bdd8a8361cdd5a42e1ab5baa45cd16ea640152d6f577f1bf plugin-sdk-api-baseline.jsonl
1+
fcf5285d9e7be94565a3470a17aaa1291afb779538f95dd98203d4adb0350602 plugin-sdk-api-baseline.json
2+
c7ae91b7f7dd0f5ecb253a6a08484d81871a433b7cae96214e6ef8fe76fbe51c plugin-sdk-api-baseline.jsonl

docs/automation/cron-jobs.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -141,7 +141,7 @@ Fast mode follows the resolved live selection. If the selected model config has
141141

142142
If a run hits a live model-switch handoff, cron retries with the switched provider/model and persists that selection (and any new auth profile) for the active run. Retries are bounded: after the initial attempt plus 2 switch retries, cron aborts instead of looping.
143143

144-
Before an isolated run starts, OpenClaw checks reachable local endpoints for configured `api: "ollama"` and `api: "openai-completions"` providers whose `baseUrl` is loopback, private-network, or `.local`. This preflight walks the job's configured fallback chain and only marks the run `skipped` once every candidate is unreachable; `--fallbacks ""` keeps that walk strict to just the primary model. A down endpoint records the run as `skipped` with a clear error instead of starting a model call. The result is cached for 5 minutes per endpoint (not per job or model), so many due jobs sharing a dead local Ollama/vLLM/SGLang/LM Studio server cost one probe instead of a request storm. Skipped preflight runs do not increment execution-error backoff; set `failureAlert.includeSkipped` to opt into repeated skip alerts.
144+
Before an isolated run starts, OpenClaw checks reachable local endpoints for configured `api: "ollama"` and `api: "openai-completions"` providers whose `baseUrl` is loopback, private-network, or `.local`. Local-provider preflight checks walk configured fallbacks and only mark the run `skipped` once every candidate is unreachable; `--fallbacks ""` keeps that walk strict to just the primary model. A down endpoint records the run as `skipped` with a clear error instead of starting a model call. The result is cached for 5 minutes per endpoint (not per job or model), so many due jobs sharing a dead local Ollama/vLLM/SGLang/LM Studio server cost one probe instead of a request storm. Skipped preflight runs do not increment execution-error backoff; set `failureAlert.includeSkipped` to opt into repeated skip alerts.
145145

146146
### Command payloads
147147

docs/help/environment.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ title: "Environment variables"
88
---
99

1010
OpenClaw pulls environment variables from multiple sources. The rule is **never override existing values**.
11-
Workspace `.env` files are a lower-trust source: OpenClaw ignores provider credentials and protected runtime controls from workspace `.env` before applying precedence.
11+
Workspace `.env` files are a lower-trust source: OpenClaw ignores provider credential environment variables from workspace `.env` files and protected runtime controls there before applying precedence.
1212

1313
## Precedence (highest to lowest)
1414

docs/help/testing-live.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,8 @@ The curated model lists below live in `src/agents/live-model-filter.ts` and
6565
change over time; treat the arrays there as the source of truth, not this
6666
page.
6767

68+
MiniMax M3 uses `minimax/MiniMax-M3` as its default provider/model reference.
69+
6870
### Layer 1: Direct model completion (no gateway)
6971

7072
- Test: `src/agents/models.profiles.live.test.ts`

docs/nodes/talk.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ Supported keys: `voice` / `voice_id` / `voiceId`, `model` / `model_id` / `modelI
9191
| `providers.mlx.modelId` | `mlx-community/Soprano-80M-bf16` | |
9292
| `providers.elevenlabs.apiKey` | - | Falls back to `ELEVENLABS_API_KEY` (or gateway shell profile if available). |
9393
| `speechLocale` | device default | BCP 47 locale id for on-device Talk speech recognition on iOS/macOS. |
94-
| `silenceTimeoutMs` | `700` ms macOS/Android, `900` ms iOS | Pause window before Talk sends the transcript. |
94+
| `silenceTimeoutMs` | 700 ms on macOS and Android, 900 ms on iOS | Pause window before Talk sends the transcript. |
9595
| `interruptOnSpeech` | `true` | |
9696
| `outputFormat` | `pcm_44100` macOS/iOS, `pcm_24000` Android | Set `mp3_*` to force MP3 streaming. |
9797
| `consultThinkingLevel` | unset | Thinking level override for the agent run behind realtime `openclaw_agent_consult` calls. |

docs/reference/full-release-validation.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -190,8 +190,8 @@ underlying QA runtime parity lane is advisory. Tideclaw alpha runs may still
190190
treat non-package-safety release-check lanes as advisory. When
191191
`live_suite_filter` explicitly requests a gated QA live lane such as Discord,
192192
WhatsApp, or Slack, the matching `OPENCLAW_RELEASE_QA_*_LIVE_CI_ENABLED` repo
193-
variable must be enabled; otherwise input capture fails instead of silently
194-
skipping the lane. Rerun `rerun_group=qa`, `qa-parity`, or `qa-live` when you
193+
variable must be enabled; otherwise input capture fails instead of silently skipping the lane.
194+
Rerun `rerun_group=qa`, `qa-parity`, or `qa-live` when you
195195
need fresh QA evidence.
196196

197197
## Evidence to keep

docs/snippets/plugin-publish/minimal-package.json

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,12 @@
22
"name": "@myorg/openclaw-my-plugin",
33
"version": "1.0.0",
44
"type": "module",
5+
"dependencies": {
6+
"typebox": "1.1.39"
7+
},
8+
"peerDependencies": {
9+
"openclaw": ">=2026.3.24-beta.2"
10+
},
511
"openclaw": {
612
"extensions": ["./index.ts"],
713
"compat": {

src/agents/minimax-docs.test.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,6 @@ const minimaxDoc = fs.readFileSync(path.join(repoRoot, "docs/providers/minimax.m
1515

1616
describe("MiniMax docs sync", () => {
1717
it("keeps the live-testing guide on the current MiniMax default", () => {
18-
expect(testingLiveDoc).toContain("MiniMax M3");
1918
expect(testingLiveDoc).toContain(MINIMAX_DEFAULT_MODEL_REF);
2019
});
2120

src/auto-reply/reply/commands-core.ts

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,9 +35,18 @@ export async function handleCommands(params: HandleCommandsParams): Promise<Comm
3535
if (HANDLERS === null) {
3636
HANDLERS = (await loadCommandHandlersRuntime()).loadCommandHandlers();
3737
}
38+
const allowCreateSessionEntry = params.allowCreateSessionEntry === true;
39+
const initialSessionEntry =
40+
params.initialSessionEntry ??
41+
(allowCreateSessionEntry
42+
? undefined
43+
: params.sessionEntry
44+
? { ...params.sessionEntry }
45+
: undefined);
3846
const commandParams: HandleCommandsParams = {
3947
...params,
40-
initialSessionEntry: params.sessionEntry ? { ...params.sessionEntry } : undefined,
48+
initialSessionEntry,
49+
allowCreateSessionEntry,
4150
};
4251
const resetResult = await maybeHandleResetCommand(commandParams);
4352
if (resetResult) {

src/auto-reply/reply/commands-session-store.test.ts

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,65 @@ async function withTempStore<T>(run: (storePath: string) => Promise<T>): Promise
1616
}
1717

1818
describe("commands session store persistence", () => {
19+
it("creates a missing row for the first command-only session mutation", async () => {
20+
await withTempStore(async (storePath) => {
21+
const sessionKey = "agent:main:first-command";
22+
const entry: SessionEntry = {
23+
sessionId: "first-command-session",
24+
updatedAt: 1,
25+
responseUsage: "tokens",
26+
};
27+
const sessionStore: Record<string, SessionEntry> = { [sessionKey]: entry };
28+
await saveSessionStore(storePath, {}, { skipMaintenance: true });
29+
30+
await expect(
31+
persistSessionEntry({
32+
allowCreateSessionEntry: true,
33+
sessionEntry: entry,
34+
sessionStore,
35+
sessionKey,
36+
storePath,
37+
touchedFields: ["responseUsage"],
38+
}),
39+
).resolves.toBe(true);
40+
41+
const persisted = loadSessionStore(storePath, { skipCache: true })[sessionKey];
42+
expect(persisted).toMatchObject({
43+
sessionId: "first-command-session",
44+
responseUsage: "tokens",
45+
});
46+
expect(sessionStore[sessionKey]).toMatchObject({
47+
sessionId: "first-command-session",
48+
responseUsage: "tokens",
49+
});
50+
});
51+
});
52+
53+
it("does not recreate a missing row without explicit create ownership", async () => {
54+
await withTempStore(async (storePath) => {
55+
const sessionKey = "agent:main:missing-existing";
56+
const entry: SessionEntry = {
57+
sessionId: "missing-existing-session",
58+
updatedAt: 1,
59+
responseUsage: "tokens",
60+
};
61+
const sessionStore: Record<string, SessionEntry> = { [sessionKey]: entry };
62+
await saveSessionStore(storePath, {}, { skipMaintenance: true });
63+
64+
await expect(
65+
persistSessionEntry({
66+
sessionEntry: entry,
67+
sessionStore,
68+
sessionKey,
69+
storePath,
70+
touchedFields: ["responseUsage"],
71+
}),
72+
).resolves.toBe(false);
73+
74+
expect(loadSessionStore(storePath, { skipCache: true })[sessionKey]).toBeUndefined();
75+
});
76+
});
77+
1978
it("persists command state without reverting concurrent session management", async () => {
2079
await withTempStore(async (storePath) => {
2180
const sessionKey = "agent:main:command";

0 commit comments

Comments
 (0)