Skip to content

Commit 1a49000

Browse files
committed
Auto-merge upstream openclaw/openclaw
2 parents e3a108f + 66ac519 commit 1a49000

16 files changed

Lines changed: 702 additions & 89 deletions

File tree

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ Docs: https://docs.openclaw.ai
9090
- iMessage (imsg): strip an accidental protobuf length-delimited UTF-8 field wrapper from inbound `text` and `reply_to_text` when it fully consumes the field, fixing leading garbage before the real message. (#63868) Thanks @neeravmakwana.
9191
- Gateway/pairing: fail closed for paired device records that have no device tokens, and reject pairing approvals whose requested scopes do not match the requested device roles.
9292
- ACP/gateway chat: classify lifecycle errors before forwarding them to ACP clients so refusals use ACP's refusal stop reason while transient backend errors continue to finish as normal turns.
93+
- Agents/BTW: strip replayed tool blocks, hidden reasoning, and malformed image payloads from `/btw` side-question context so Bedrock no-tools side questions keep working after tool-use turns. (#64225) Thanks @ngutman.
9394
- Commands/btw: keep tool-less side questions from sending injected empty `tools` arrays on strict OpenAI-compatible providers, so `/btw` continues working after prior tool-call history. (#64219) Thanks @ngutman.
9495
- Agents/Bedrock: let `/btw` side questions use `auth: "aws-sdk"` without a static API key so Bedrock IAM and instance-role sessions stop failing before the side question runs. (#64218) Thanks @SnowSky1.
9596

extensions/browser/src/browser/client-fetch.ts

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { fetchWithSsrFGuard } from "openclaw/plugin-sdk/ssrf-runtime";
12
import { normalizeOptionalString } from "openclaw/plugin-sdk/text-runtime";
23
import { normalizeLowercaseStringOrEmpty } from "openclaw/plugin-sdk/text-runtime";
34
import { formatCliCommand } from "../cli/command-format.js";
@@ -183,8 +184,17 @@ async function fetchHttpJson<T>(
183184
}
184185

185186
const t = setTimeout(() => ctrl.abort(new Error("timed out")), timeoutMs);
187+
let release: (() => Promise<void>) | undefined;
186188
try {
187-
const res = await fetch(url, { ...init, signal: ctrl.signal });
189+
const guarded = await fetchWithSsrFGuard({
190+
url,
191+
init,
192+
signal: ctrl.signal,
193+
policy: { allowPrivateNetwork: true },
194+
auditContext: "browser-control-client",
195+
});
196+
release = guarded.release;
197+
const res = guarded.response;
188198
if (!res.ok) {
189199
if (isRateLimitStatus(res.status)) {
190200
// Do not reflect upstream response text into the error surface (log/agent injection risk)
@@ -199,6 +209,7 @@ async function fetchHttpJson<T>(
199209
return (await res.json()) as T;
200210
} finally {
201211
clearTimeout(t);
212+
await release?.();
202213
if (upstreamSignal && upstreamAbortListener) {
203214
upstreamSignal.removeEventListener("abort", upstreamAbortListener);
204215
}

extensions/nostr/src/nostr-profile-http.test.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,10 +90,12 @@ function createMockResponse(): ServerResponse & {
9090
_getData: () => string;
9191
_getStatusCode: () => number;
9292
} {
93-
const res = new ServerResponse({} as IncomingMessage);
94-
9593
let data = "";
9694
let statusCode = 200;
95+
const res = Object.assign(new ServerResponse({} as IncomingMessage), {
96+
_getData: () => data,
97+
_getStatusCode: () => statusCode,
98+
});
9799

98100
res.write = function (chunk: unknown) {
99101
data += String(chunk);
@@ -114,9 +116,6 @@ function createMockResponse(): ServerResponse & {
114116
},
115117
});
116118

117-
res._getData = () => data;
118-
res._getStatusCode = () => statusCode;
119-
120119
return res;
121120
}
122121

extensions/tlon/src/monitor/index.ts

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -566,12 +566,10 @@ export async function monitorTlonProvider(opts: MonitorTlonOpts = {}): Promise<v
566566
metadata?: { model?: string };
567567
model?: string;
568568
};
569-
const extRoute = route;
570569
const defaultModel = cfg.agents?.defaults?.model;
571570
const modelInfo =
572571
extPayload.metadata?.model ||
573572
extPayload.model ||
574-
extRoute.model ||
575573
(typeof defaultModel === "string" ? defaultModel : defaultModel?.primary);
576574
replyText = `${replyText}\n\n_[Generated by ${formatModelName(modelInfo)}]_`;
577575
}

scripts/test-projects.mjs

Lines changed: 15 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@ import {
66
buildFullSuiteVitestRunPlans,
77
createVitestRunSpecs,
88
parseTestProjectsArgs,
9+
resolveParallelFullSuiteConcurrency,
910
resolveChangedTargetArgs,
10-
shouldUseLocalFullSuiteParallelByDefault,
1111
writeVitestIncludeFile,
1212
} from "./test-projects.test-support.mjs";
1313
import {
@@ -116,29 +116,17 @@ function runVitestSpec(spec) {
116116
});
117117
}
118118

119-
function parsePositiveInt(value) {
120-
const parsed = Number.parseInt(value ?? "", 10);
121-
return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
122-
}
123-
124-
function resolveParallelFullSuiteConcurrency(specCount, env) {
125-
const override = parsePositiveInt(env.OPENCLAW_TEST_PROJECTS_PARALLEL);
126-
if (override !== null) {
127-
return Math.min(override, specCount);
128-
}
129-
if (env.OPENCLAW_TEST_PROJECTS_SERIAL === "1") {
130-
return 1;
119+
function applyDefaultParallelVitestWorkerBudget(specs, env) {
120+
if (env.OPENCLAW_VITEST_MAX_WORKERS || env.OPENCLAW_TEST_WORKERS) {
121+
return specs;
131122
}
132-
if (env.CI === "true" || env.GITHUB_ACTIONS === "true") {
133-
return 1;
134-
}
135-
if (
136-
env.OPENCLAW_TEST_PROJECTS_LEAF_SHARDS !== "1" &&
137-
!shouldUseLocalFullSuiteParallelByDefault(env)
138-
) {
139-
return 1;
140-
}
141-
return 1;
123+
return specs.map((spec) => ({
124+
...spec,
125+
env: {
126+
...spec.env,
127+
OPENCLAW_VITEST_MAX_WORKERS: "2",
128+
},
129+
}));
142130
}
143131

144132
function orderFullSuiteSpecsForParallelRun(specs) {
@@ -218,7 +206,10 @@ async function main() {
218206
if (isFullSuiteRun) {
219207
const concurrency = resolveParallelFullSuiteConcurrency(runSpecs.length, process.env);
220208
if (concurrency > 1) {
221-
const parallelSpecs = orderFullSuiteSpecsForParallelRun(runSpecs);
209+
const parallelSpecs = applyDefaultParallelVitestWorkerBudget(
210+
orderFullSuiteSpecsForParallelRun(runSpecs),
211+
process.env,
212+
);
222213
console.error(
223214
`[test] running ${parallelSpecs.length} Vitest shards with parallelism ${concurrency}`,
224215
);

scripts/test-projects.test-support.mjs

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -649,6 +649,37 @@ export function shouldUseLocalFullSuiteParallelByDefault(env = process.env) {
649649
);
650650
}
651651

652+
function parsePositiveInt(value) {
653+
const parsed = Number.parseInt(value ?? "", 10);
654+
return Number.isFinite(parsed) && parsed > 0 ? parsed : null;
655+
}
656+
657+
export function resolveParallelFullSuiteConcurrency(specCount, env = process.env) {
658+
const override = parsePositiveInt(env.OPENCLAW_TEST_PROJECTS_PARALLEL);
659+
if (override !== null) {
660+
return Math.min(override, specCount);
661+
}
662+
if (env.OPENCLAW_TEST_PROJECTS_SERIAL === "1") {
663+
return 1;
664+
}
665+
if (env.CI === "true" || env.GITHUB_ACTIONS === "true") {
666+
return 1;
667+
}
668+
const workerBudget = parsePositiveInt(
669+
env.OPENCLAW_VITEST_MAX_WORKERS ?? env.OPENCLAW_TEST_WORKERS,
670+
);
671+
if (workerBudget !== null && workerBudget <= 1) {
672+
return 1;
673+
}
674+
if (
675+
env.OPENCLAW_TEST_PROJECTS_LEAF_SHARDS !== "1" &&
676+
!shouldUseLocalFullSuiteParallelByDefault(env)
677+
) {
678+
return 1;
679+
}
680+
return Math.min(10, specCount);
681+
}
682+
652683
export function createVitestRunSpecs(args, params = {}) {
653684
const cwd = params.cwd ?? process.cwd();
654685
const plans = buildVitestRunPlans(args, cwd);

0 commit comments

Comments
 (0)