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

推荐订阅源

Microsoft Azure Blog
Microsoft Azure Blog
aimingoo的专栏
aimingoo的专栏
F
Fortinet All Blogs
Blog — PlanetScale
Blog — PlanetScale
GbyAI
GbyAI
MongoDB | Blog
MongoDB | Blog
月光博客
月光博客
The Cloudflare Blog
量子位
T
Tailwind CSS Blog
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
B
Blog
MyScale Blog
MyScale Blog
T
The Blog of Author Tim Ferriss
The GitHub Blog
The GitHub Blog
G
Google Developers Blog
D
DataBreaches.Net
V
Visual Studio Blog
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
Last Week in AI
Last Week in AI
U
Unit 42
博客园 - 聂微东
有赞技术团队
有赞技术团队
A
About on SuperTechFans

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
fix: improve mac settings performance · openclaw/openclaw...
steipete · 2026-05-17 · via Recent Commits to openclaw:main

@@ -2,43 +2,102 @@ import Foundation

22

import OpenClawProtocol

3344

extension ChannelsStore {

5-

func loadConfigSchema() async {

6-

guard !self.configSchemaLoading else { return }

5+

func loadConfigSchema(force: Bool = false) async {

6+

let sourceKey = self.currentConfigCacheSourceKey()

7+

self.resetConfigSchemaCacheIfSourceChanged(sourceKey)

8+

if !force, self.configSchema != nil {

9+

return

10+

}

11+

guard !self.queueConfigSchemaReloadIfLoading(sourceKey: sourceKey, force: force) else { return }

712

self.configSchemaLoading = true

8-

defer { self.configSchemaLoading = false }

13+

self.configSchemaLoadingSourceKey = sourceKey

14+

defer {

15+

self.configSchemaLoading = false

16+

self.configSchemaLoadingSourceKey = nil

17+

}

91810-

do {

11-

let res: ConfigSchemaResponse = try await GatewayConnection.shared.requestDecoded(

12-

method: .configSchema,

13-

params: nil,

14-

timeoutMs: 8000)

15-

let schemaValue = res.schema.foundationValue

16-

self.configSchema = ConfigSchemaNode(raw: schemaValue)

17-

let hintValues = res.uihints.mapValues { $0.foundationValue }

18-

self.configUiHints = decodeUiHints(hintValues)

19-

} catch {

20-

self.configStatus = error.localizedDescription

19+

var requestSourceKey = sourceKey

20+21+

while true {

22+

self.configSchemaLoadingSourceKey = requestSourceKey

23+

do {

24+

let res: ConfigSchemaResponse = try await GatewayConnection.shared.requestDecoded(

25+

method: .configSchema,

26+

params: nil,

27+

timeoutMs: 8000)

28+

self.applyConfigSchemaResponse(res, sourceKey: requestSourceKey)

29+

} catch {

30+

self.configStatus = error.localizedDescription

31+

}

32+33+

guard self.configSchemaReloadPending else { break }

34+

self.configSchemaReloadPending = false

35+

requestSourceKey = self.currentConfigCacheSourceKey()

36+

self.resetConfigSchemaCacheIfSourceChanged(requestSourceKey)

2137

}

2238

}

233924-

func loadConfig() async {

25-

do {

26-

let snap: ConfigSnapshot = try await GatewayConnection.shared.requestDecoded(

27-

method: .configGet,

28-

params: nil,

29-

timeoutMs: 10000)

30-

self.configStatus = snap.valid == false

31-

? "Config invalid; fix it in ~/.openclaw/openclaw.json."

32-

: nil

33-

self.configRoot = snap.config?.mapValues { $0.foundationValue } ?? [:]

34-

self.configDraft = cloneConfigValue(self.configRoot) as? [String: Any] ?? self.configRoot

35-

self.configDirty = false

36-

self.configLoaded = true

37-38-

self.applyUIConfig(snap)

39-

} catch {

40-

self.configStatus = error.localizedDescription

40+

func loadConfig(force: Bool = true) async {

41+

let sourceKey = self.currentConfigCacheSourceKey()

42+

self.resetConfigCacheIfSourceChanged(sourceKey)

43+

if !force, self.configLoaded {

44+

return

45+

}

46+

guard !self.queueConfigReloadIfLoading(sourceKey: sourceKey, force: force) else { return }

47+

self.configLoading = true

48+

self.configLoadingSourceKey = sourceKey

49+

defer {

50+

self.configLoading = false

51+

self.configLoadingSourceKey = nil

4152

}

53+54+

var requestForce = force

55+

var requestSourceKey = sourceKey

56+57+

while true {

58+

self.configLoadingSourceKey = requestSourceKey

59+

do {

60+

let snap: ConfigSnapshot = try await GatewayConnection.shared.requestDecoded(

61+

method: .configGet,

62+

params: nil,

63+

timeoutMs: 10000)

64+

self.applyConfigSnapshot(snap, sourceKey: requestSourceKey, force: requestForce)

65+

} catch {

66+

self.configStatus = error.localizedDescription

67+

}

68+69+

guard self.configForceReloadPending else { break }

70+

self.configForceReloadPending = false

71+

requestForce = true

72+

requestSourceKey = self.currentConfigCacheSourceKey()

73+

self.resetConfigCacheIfSourceChanged(requestSourceKey)

74+

}

75+

}

76+77+

func applyConfigSnapshot(_ snap: ConfigSnapshot, sourceKey: String, force: Bool) {

78+

guard self.configSourceKey == sourceKey else { return }

79+

guard force || !self.configDirty else { return }

80+81+

self.configStatus = snap.valid == false

82+

? "Config invalid; fix it in ~/.openclaw/openclaw.json."

83+

: nil

84+

self.configRoot = snap.config?.mapValues { $0.foundationValue } ?? [:]

85+

self.configDraft = cloneConfigValue(self.configRoot) as? [String: Any] ?? self.configRoot

86+

self.configDirty = false

87+

self.configLoaded = true

88+

self.configSourceKey = sourceKey

89+90+

self.applyUIConfig(snap)

91+

}

92+93+

func applyConfigSchemaResponse(_ res: ConfigSchemaResponse, sourceKey: String) {

94+

guard self.configSchemaSourceKey == sourceKey else { return }

95+96+

let schemaValue = res.schema.foundationValue

97+

self.configSchema = ConfigSchemaNode(raw: schemaValue)

98+

let hintValues = res.uihints.mapValues { $0.foundationValue }

99+

self.configUiHints = decodeUiHints(hintValues)

100+

self.configSchemaSourceKey = sourceKey

42101

}

4310244103

private func applyUIConfig(_ snap: ConfigSnapshot) {

@@ -85,7 +144,75 @@ extension ChannelsStore {

85144

}

8614587146

func reloadConfigDraft() async {

88-

await self.loadConfig()

147+

await self.loadConfig(force: true)

148+

}

149+150+

func resetConfigSchemaCacheIfSourceChanged(_ sourceKey: String) {

151+

guard let cachedSourceKey = self.configSchemaSourceKey else {

152+

self.configSchemaSourceKey = sourceKey

153+

return

154+

}

155+

guard cachedSourceKey != sourceKey else { return }

156+

self.configSchema = nil

157+

self.configUiHints = [:]

158+

self.configSchemaSourceKey = sourceKey

159+

}

160+161+

func resetConfigCacheIfSourceChanged(_ sourceKey: String) {

162+

guard let cachedSourceKey = self.configSourceKey else {

163+

self.configSourceKey = sourceKey

164+

return

165+

}

166+

guard cachedSourceKey != sourceKey else { return }

167+

self.configRoot = [:]

168+

self.configDraft = [:]

169+

self.configDirty = false

170+

self.configLoaded = false

171+

self.configSourceKey = sourceKey

172+

}

173+174+

func queueConfigReloadIfLoading(sourceKey: String, force: Bool) -> Bool {

175+

guard self.configLoading else { return false }

176+

if force || self.configLoadingSourceKey != sourceKey {

177+

self.configForceReloadPending = true

178+

}

179+

return true

180+

}

181+182+

func queueConfigSchemaReloadIfLoading(sourceKey: String, force: Bool) -> Bool {

183+

guard self.configSchemaLoading else { return false }

184+

if force || self.configSchemaLoadingSourceKey != sourceKey {

185+

self.configSchemaReloadPending = true

186+

}

187+

return true

188+

}

189+190+

private func currentConfigCacheSourceKey() -> String {

191+

let root = OpenClawConfigFile.loadDict()

192+

let settings = CommandResolver.connectionSettings(configRoot: root)

193+

let env = ProcessInfo.processInfo.environment

194+

return [

195+

"mode:\(settings.mode.rawValue)",

196+

"target:\(settings.target)",

197+

"identity:\(settings.identity)",

198+

"project:\(settings.projectRoot)",

199+

"cli:\(settings.cliPath)",

200+

"port:\(GatewayEnvironment.gatewayPort())",

201+

"gateway:\(Self.configFingerprint(root["gateway"]))",

202+

"token:\(Self.configFingerprint(env["OPENCLAW_GATEWAY_TOKEN"]))",

203+

"password:\(Self.configFingerprint(env["OPENCLAW_GATEWAY_PASSWORD"]))",

204+

].joined(separator: "|")

205+

}

206+207+

private static func configFingerprint(_ value: Any?) -> String {

208+

guard let value else { return "nil" }

209+

if JSONSerialization.isValidJSONObject(value),

210+

let data = try? JSONSerialization.data(withJSONObject: value, options: [.sortedKeys])

211+

{

212+

return "\(data.count):\(data.hashValue)"

213+

}

214+

let text = String(describing: value)

215+

return "\(text.count):\(text.hashValue)"

89216

}

90217

}

91218