@2en/clawly-plugins 1.30.0-beta.5 → 1.30.0-beta.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/clawly-config-defaults.json5 +14 -0
- package/gateway/config-model.ts +68 -0
- package/gateway/config-timezone.ts +19 -14
- package/gateway/index.ts +2 -0
- package/package.json +1 -1
|
@@ -179,9 +179,23 @@
|
|
|
179
179
|
},
|
|
180
180
|
},
|
|
181
181
|
|
|
182
|
+
// gateway.reload — use "hot" mode to prevent spurious SIGUSR1 restarts.
|
|
183
|
+
// config-setup writes restart-requiring keys (commands.*, gateway.*, env.*)
|
|
184
|
+
// after the gateway has already captured its startup config snapshot.
|
|
185
|
+
// In "hybrid" (default) mode, any subsequent config file write triggers the
|
|
186
|
+
// file watcher to diff against the stale snapshot, discover the config-setup
|
|
187
|
+
// changes as "new", and issue SIGUSR1. "hot" mode makes the watcher ignore
|
|
188
|
+
// restart-requiring diffs — only hot-reloadable changes (heartbeat, cron,
|
|
189
|
+
// hooks, browser) are applied. Direct SIGUSR1 from explicit restart commands
|
|
190
|
+
// and plugin auto-update is unaffected. If you manually edit a restart-
|
|
191
|
+
// requiring field in openclaw.json, run `openclaw restart` to apply it.
|
|
192
|
+
//
|
|
182
193
|
// gateway.nodes — allowlist dangerous node commands so the AI agent can
|
|
183
194
|
// invoke them on connected Clawly nodes (browser, reminders, calendar, device).
|
|
184
195
|
gateway: {
|
|
196
|
+
reload: {
|
|
197
|
+
mode: "hot",
|
|
198
|
+
},
|
|
185
199
|
nodes: {
|
|
186
200
|
allowCommands: [
|
|
187
201
|
// Browser commands (Mac nodes)
|
|
@@ -0,0 +1,68 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model switch RPC: writes agents.defaults.model.primary to openclaw.json
|
|
3
|
+
* without triggering a gateway restart.
|
|
4
|
+
*
|
|
5
|
+
* OpenClaw reads agents.defaults.model.primary dynamically on each chat
|
|
6
|
+
* request (loadConfig() has a ~200ms cache). A disk write takes effect
|
|
7
|
+
* within that window — no SIGUSR1 needed.
|
|
8
|
+
*
|
|
9
|
+
* Uses the runtime config APIs (loadConfig + writeConfigFile) for atomic
|
|
10
|
+
* writes, env var preservation, and config validation.
|
|
11
|
+
*
|
|
12
|
+
* Methods:
|
|
13
|
+
* - clawly.config.setModel({ model }) → { changed, model }
|
|
14
|
+
*/
|
|
15
|
+
|
|
16
|
+
import type {PluginApi} from '../types'
|
|
17
|
+
import type {OpenClawConfig} from '../types/openclaw'
|
|
18
|
+
|
|
19
|
+
export function registerConfigModel(api: PluginApi) {
|
|
20
|
+
api.registerGatewayMethod('clawly.config.setModel', async ({params, respond}) => {
|
|
21
|
+
const model = typeof params.model === 'string' ? params.model : ''
|
|
22
|
+
if (!model) {
|
|
23
|
+
respond(true, {changed: false, model: '', error: 'Missing model param'})
|
|
24
|
+
return
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
let config: OpenClawConfig
|
|
28
|
+
try {
|
|
29
|
+
config = {...(api.runtime.config.loadConfig() as OpenClawConfig)}
|
|
30
|
+
} catch (err) {
|
|
31
|
+
const msg = err instanceof Error ? err.message : String(err)
|
|
32
|
+
respond(true, {changed: false, model, error: `Load failed: ${msg}`})
|
|
33
|
+
return
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const current = (config.agents as Record<string, unknown> | undefined)?.defaults as
|
|
37
|
+
| Record<string, unknown>
|
|
38
|
+
| undefined
|
|
39
|
+
const currentModel = (current?.model as Record<string, unknown> | undefined)?.primary
|
|
40
|
+
|
|
41
|
+
if (currentModel === model) {
|
|
42
|
+
respond(true, {changed: false, model})
|
|
43
|
+
return
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
// Shallow-copy nested objects to avoid polluting the loadConfig() cache
|
|
47
|
+
// if writeConfigFile fails below.
|
|
48
|
+
const agents = {...((config.agents ?? {}) as Record<string, unknown>)}
|
|
49
|
+
const defaults = {...((agents.defaults ?? {}) as Record<string, unknown>)}
|
|
50
|
+
const modelObj = {...((defaults.model ?? {}) as Record<string, unknown>)}
|
|
51
|
+
modelObj.primary = model
|
|
52
|
+
defaults.model = modelObj
|
|
53
|
+
agents.defaults = defaults
|
|
54
|
+
config.agents = agents
|
|
55
|
+
|
|
56
|
+
try {
|
|
57
|
+
await api.runtime.config.writeConfigFile(config)
|
|
58
|
+
api.logger.info(`config-model: set model.primary to ${model}`)
|
|
59
|
+
respond(true, {changed: true, model})
|
|
60
|
+
} catch (err) {
|
|
61
|
+
const msg = err instanceof Error ? err.message : String(err)
|
|
62
|
+
api.logger.error(`config-model: write failed — ${msg}`)
|
|
63
|
+
respond(true, {changed: false, model, error: `Write failed: ${msg}`})
|
|
64
|
+
}
|
|
65
|
+
})
|
|
66
|
+
|
|
67
|
+
api.logger.info('config-model: registered clawly.config.setModel')
|
|
68
|
+
}
|
|
@@ -2,14 +2,15 @@
|
|
|
2
2
|
* Timezone sync RPC: writes agents.defaults.userTimezone to openclaw.json
|
|
3
3
|
* without triggering a gateway restart.
|
|
4
4
|
*
|
|
5
|
+
* Uses the runtime config APIs (loadConfig + writeConfigFile) for atomic
|
|
6
|
+
* writes, env var preservation, and config validation.
|
|
7
|
+
*
|
|
5
8
|
* Methods:
|
|
6
9
|
* - clawly.config.setTimezone({ timezone }) → { changed, timezone }
|
|
7
10
|
*/
|
|
8
11
|
|
|
9
|
-
import path from 'node:path'
|
|
10
|
-
|
|
11
12
|
import type {PluginApi} from '../types'
|
|
12
|
-
import {
|
|
13
|
+
import type {OpenClawConfig} from '../types/openclaw'
|
|
13
14
|
|
|
14
15
|
export function registerConfigTimezone(api: PluginApi) {
|
|
15
16
|
api.registerGatewayMethod('clawly.config.setTimezone', async ({params, respond}) => {
|
|
@@ -19,30 +20,34 @@ export function registerConfigTimezone(api: PluginApi) {
|
|
|
19
20
|
return
|
|
20
21
|
}
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
23
|
+
let config: OpenClawConfig
|
|
24
|
+
try {
|
|
25
|
+
config = {...(api.runtime.config.loadConfig() as OpenClawConfig)}
|
|
26
|
+
} catch (err) {
|
|
27
|
+
const msg = err instanceof Error ? err.message : String(err)
|
|
28
|
+
respond(true, {changed: false, timezone, error: `Load failed: ${msg}`})
|
|
25
29
|
return
|
|
26
30
|
}
|
|
27
31
|
|
|
28
|
-
const
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
const agents = (config.agents ?? {}) as Record<string, unknown>
|
|
32
|
-
const defaults = (agents.defaults ?? {}) as Record<string, unknown>
|
|
33
|
-
const current = defaults.userTimezone
|
|
32
|
+
const currentDefaults = (config.agents as Record<string, unknown> | undefined)?.defaults as
|
|
33
|
+
| Record<string, unknown>
|
|
34
|
+
| undefined
|
|
34
35
|
|
|
35
|
-
if (
|
|
36
|
+
if (currentDefaults?.userTimezone === timezone) {
|
|
36
37
|
respond(true, {changed: false, timezone})
|
|
37
38
|
return
|
|
38
39
|
}
|
|
39
40
|
|
|
41
|
+
// Shallow-copy nested objects to avoid polluting the loadConfig() cache
|
|
42
|
+
// if writeConfigFile fails below.
|
|
43
|
+
const agents = {...((config.agents ?? {}) as Record<string, unknown>)}
|
|
44
|
+
const defaults = {...((agents.defaults ?? {}) as Record<string, unknown>)}
|
|
40
45
|
defaults.userTimezone = timezone
|
|
41
46
|
agents.defaults = defaults
|
|
42
47
|
config.agents = agents
|
|
43
48
|
|
|
44
49
|
try {
|
|
45
|
-
|
|
50
|
+
await api.runtime.config.writeConfigFile(config)
|
|
46
51
|
api.logger.info(`config-timezone: set userTimezone to ${timezone}`)
|
|
47
52
|
respond(true, {changed: true, timezone})
|
|
48
53
|
} catch (err) {
|
package/gateway/index.ts
CHANGED
|
@@ -4,6 +4,7 @@ import {registerCalendarNative} from './calendar-native'
|
|
|
4
4
|
import {registerAnalytics} from './analytics'
|
|
5
5
|
import {registerAudit} from './audit'
|
|
6
6
|
import {registerClawhub2gateway} from './clawhub2gateway'
|
|
7
|
+
import {registerConfigModel} from './config-model'
|
|
7
8
|
import {registerConfigRepair} from './config-repair'
|
|
8
9
|
import {registerConfigTimezone} from './config-timezone'
|
|
9
10
|
import {registerCronDelivery} from './cron-delivery'
|
|
@@ -57,6 +58,7 @@ export function registerGateway(api: PluginApi) {
|
|
|
57
58
|
registerCronTelemetry(api)
|
|
58
59
|
registerMessageLog(api)
|
|
59
60
|
registerAnalytics(api)
|
|
61
|
+
registerConfigModel(api)
|
|
60
62
|
registerConfigRepair(api)
|
|
61
63
|
registerConfigTimezone(api)
|
|
62
64
|
registerSessionSanitize(api)
|