惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
The Blog of Author Tim Ferriss
IT之家
IT之家
Engineering at Meta
Engineering at Meta
WordPress大学
WordPress大学
博客园 - 三生石上(FineUI控件)
博客园 - 聂微东
C
Check Point Blog
T
Tailwind CSS Blog
博客园 - Franky
H
Help Net Security
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
Google DeepMind News
Google DeepMind News
博客园 - 叶小钗
J
Java Code Geeks
腾讯CDC
罗磊的独立博客
爱范儿
爱范儿
阮一峰的网络日志
阮一峰的网络日志
Martin Fowler
Martin Fowler
酷 壳 – CoolShell
酷 壳 – CoolShell
I
InfoQ
B
Blog
V
Visual Studio Blog
F
Fortinet All Blogs

Recent Commits to openclaw:main

test: merge chat side-result checks · openclaw/openclaw@ddd2c2a test: merge cron history checks · openclaw/openclaw@f7eb746 test: merge responsive navigation shell checks · openclaw/openclaw@c2e4b47 docs(changelog): add codex oauth fixes · openclaw/openclaw@628e6cd test: merge navigation routing cases · openclaw/openclaw@5d8cecb Tests: mock channel registry bundled fallback · openclaw/openclaw@2b08233 Secrets: avoid broad web search discovery for single plugin config · openclaw/openclaw@a464f59 test: merge config view browser checks · openclaw/openclaw@20cf511 fix(status): align oauth health with runtime · openclaw/openclaw@eed7116 feat: add macOS screen snapshots for monitor preview (#67954) thanks … · openclaw/openclaw@f377db1 fix: report shared auth scopes in hello-ok (#67810) thanks @BunsDev · openclaw/openclaw@0b6c39b Auto-reply: avoid eager bundled route fallback · openclaw/openclaw@3ea1bf4 Tests: narrow session binding contract setup · openclaw/openclaw@54e4e16 fix(macOS): enable undo/redo in webchat composer text input (#34962) · openclaw/openclaw@00951dc Tests: speed up channel setup promotion · openclaw/openclaw@82b529a Docs: refresh agent instructions · openclaw/openclaw@5775fe2 fix(auth): serialize OAuth refresh across agents to fix #26322 (#67876) · openclaw/openclaw@8e79080 test: allow ollama public surface boundary test · openclaw/openclaw@7d4f1a6 Docs: add test performance guardrails · openclaw/openclaw@89706d3 Tests: restore context-engine usage proof · openclaw/openclaw@e4c4f95 Tests: slim context engine runtime coverage · openclaw/openclaw@74c198f ci: retry failed custom checkouts · openclaw/openclaw@0ee5baf test: trim duplicate provider auth onboarding cases · openclaw/openclaw@1ffc02e matrix: fix sessions_spawn --thread subagent session spawning (#67643) · openclaw/openclaw@1ce2596 test: reduce auth choice fixture churn · openclaw/openclaw@857b9cd test: mock health status config boundaries · openclaw/openclaw@9d5ab4a test: mock onboard config io boundary · openclaw/openclaw@299694d test: mock legacy state plugin boundaries · openclaw/openclaw@2713089 test: mock channel install boundaries · openclaw/openclaw@b945248 test: mock doctor preview channel boundaries · openclaw/openclaw@b1a3ad4
refactor: isolate plugin tool factory execution · opencla...
steipete · 2026-05-02 · via Recent Commits to openclaw:main

@@ -8,6 +8,7 @@ import {

88

loadManifestContractSnapshot,

99

} from "./manifest-contract-eligibility.js";

1010

import { hasManifestToolAvailability } from "./manifest-tool-availability.js";

11+

import type { PluginToolRegistration } from "./registry-types.js";

1112

import {

1213

getActivePluginChannelRegistry,

1314

getActivePluginRegistry,

@@ -148,6 +149,99 @@ function describePluginToolFactoryResult(

148149

return { result: "single", resultCount: 1 };

149150

}

150151152+

function createPluginToolFactoryTiming(params: {

153+

pluginId: string;

154+

names: string[];

155+

durationMs: number;

156+

elapsedMs: number;

157+

resolved: PluginToolFactoryResult;

158+

failed: boolean;

159+

optional: boolean;

160+

}): PluginToolFactoryTiming {

161+

const result = describePluginToolFactoryResult(params.resolved, params.failed);

162+

return {

163+

pluginId: params.pluginId,

164+

names: params.names,

165+

durationMs: params.durationMs,

166+

elapsedMs: params.elapsedMs,

167+

result: result.result,

168+

resultCount: result.resultCount,

169+

optional: params.optional,

170+

};

171+

}

172+173+

function resolvePluginToolFactoryEntry(params: {

174+

entry: PluginToolRegistration;

175+

ctx: OpenClawPluginToolContext;

176+

declaredNames: string[];

177+

currentRuntimeConfig: PluginLoadOptions["config"] | null | undefined;

178+

factoryTimingStartedAt: number;

179+

logError: (message: string) => void;

180+

}): {

181+

resolved: PluginToolFactoryResult;

182+

failed: boolean;

183+

timing: PluginToolFactoryTiming;

184+

} {

185+

let resolved: PluginToolFactoryResult = null;

186+

let failed = false;

187+

const factoryStartedAt = Date.now();

188+

const factoryCacheKey = buildPluginToolFactoryCacheKey({

189+

ctx: params.ctx,

190+

currentRuntimeConfig: params.currentRuntimeConfig,

191+

});

192+

const cached = readCachedPluginToolFactoryResult({

193+

factory: params.entry.factory,

194+

cacheKey: factoryCacheKey,

195+

});

196+197+

if (cached.hit) {

198+

resolved = cached.result;

199+

return {

200+

resolved,

201+

failed: false,

202+

timing: createPluginToolFactoryTiming({

203+

pluginId: params.entry.pluginId,

204+

names: params.declaredNames,

205+

durationMs: 0,

206+

elapsedMs: toElapsedMs(Date.now() - params.factoryTimingStartedAt),

207+

resolved,

208+

failed: false,

209+

optional: params.entry.optional,

210+

}),

211+

};

212+

}

213+214+

try {

215+

resolved = params.entry.factory(params.ctx);

216+

} catch (err) {

217+

failed = true;

218+

params.logError(`plugin tool failed (${params.entry.pluginId}): ${String(err)}`);

219+

} finally {

220+

if (!failed) {

221+

writeCachedPluginToolFactoryResult({

222+

factory: params.entry.factory,

223+

cacheKey: factoryCacheKey,

224+

result: resolved,

225+

});

226+

}

227+

}

228+229+

const factoryEndedAt = Date.now();

230+

return {

231+

resolved,

232+

failed,

233+

timing: createPluginToolFactoryTiming({

234+

pluginId: params.entry.pluginId,

235+

names: params.declaredNames,

236+

durationMs: toElapsedMs(factoryEndedAt - factoryStartedAt),

237+

elapsedMs: toElapsedMs(factoryEndedAt - params.factoryTimingStartedAt),

238+

resolved,

239+

failed,

240+

optional: params.entry.optional,

241+

}),

242+

};

243+

}

244+151245

function formatPluginToolFactoryTiming(timing: PluginToolFactoryTiming): string {

152246

const names = timing.names.length > 0 ? timing.names.join("|") : "-";

153247

return [

@@ -445,59 +539,19 @@ export function resolvePluginTools(params: {

445539

) {

446540

continue;

447541

}

448-

let resolved: PluginToolFactoryResult = null;

449-

let factoryFailed = false;

450-

const factoryStartedAt = Date.now();

451-

const factoryCacheKey = buildPluginToolFactoryCacheKey({

542+

const factoryResult = resolvePluginToolFactoryEntry({

543+

entry,

452544

ctx: params.context,

545+

declaredNames,

453546

currentRuntimeConfig: currentRuntimeConfigForFactoryCache,

547+

factoryTimingStartedAt,

548+

logError: (message) => context.logger.error(message),

454549

});

455-

const cached = readCachedPluginToolFactoryResult({

456-

factory: entry.factory,

457-

cacheKey: factoryCacheKey,

458-

});

459-

if (cached.hit) {

460-

resolved = cached.result;

461-

const result = describePluginToolFactoryResult(resolved, false);

462-

factoryTimings.push({

463-

pluginId: entry.pluginId,

464-

names: declaredNames,

465-

durationMs: 0,

466-

elapsedMs: toElapsedMs(Date.now() - factoryTimingStartedAt),

467-

result: result.result,

468-

resultCount: result.resultCount,

469-

optional: entry.optional,

470-

});

471-

} else {

472-

try {

473-

resolved = entry.factory(params.context);

474-

} catch (err) {

475-

factoryFailed = true;

476-

context.logger.error(`plugin tool failed (${entry.pluginId}): ${String(err)}`);

477-

} finally {

478-

const factoryEndedAt = Date.now();

479-

const result = describePluginToolFactoryResult(resolved, factoryFailed);

480-

factoryTimings.push({

481-

pluginId: entry.pluginId,

482-

names: declaredNames,

483-

durationMs: toElapsedMs(factoryEndedAt - factoryStartedAt),

484-

elapsedMs: toElapsedMs(factoryEndedAt - factoryTimingStartedAt),

485-

result: result.result,

486-

resultCount: result.resultCount,

487-

optional: entry.optional,

488-

});

489-

if (!factoryFailed) {

490-

writeCachedPluginToolFactoryResult({

491-

factory: entry.factory,

492-

cacheKey: factoryCacheKey,

493-

result: resolved,

494-

});

495-

}

496-

}

497-

}

498-

if (factoryFailed) {

550+

factoryTimings.push(factoryResult.timing);

551+

if (factoryResult.failed) {

499552

continue;

500553

}

554+

const { resolved } = factoryResult;

501555

if (!resolved) {

502556

if (declaredNames.length > 0) {

503557

context.logger.debug?.(