@2en/clawly-plugins 1.18.2 → 1.19.1

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.
@@ -10,6 +10,7 @@ import path from 'node:path'
10
10
 
11
11
  import type {PluginApi} from '../index'
12
12
  import {
13
+ EXTRA_GATEWAY_MODELS,
13
14
  PROVIDER_NAME,
14
15
  readOpenclawConfig,
15
16
  resolveStateDir,
@@ -85,13 +86,15 @@ export function registerConfigRepair(api: PluginApi) {
85
86
  ? imageModelFull.slice(prefix.length)
86
87
  : imageModelFull
87
88
 
89
+ const extraModels = EXTRA_GATEWAY_MODELS.map(({id, name, input}) => ({id, name, input}))
88
90
  const models = !defaultModel
89
91
  ? (provider?.models ?? [])
90
92
  : defaultModel === imageModel || !imageModel
91
- ? [{id: defaultModel, name: defaultModel, input: ['text', 'image']}]
93
+ ? [{id: defaultModel, name: defaultModel, input: ['text', 'image']}, ...extraModels]
92
94
  : [
93
95
  {id: defaultModel, name: defaultModel, input: ['text']},
94
96
  {id: imageModel, name: imageModel, input: ['text', 'image']},
97
+ ...extraModels,
95
98
  ]
96
99
 
97
100
  if (!config.models) config.models = {}
@@ -104,6 +107,24 @@ export function registerConfigRepair(api: PluginApi) {
104
107
  models,
105
108
  }
106
109
 
110
+ // Write agents.defaults.models alias map (mirrors model-gateway-setup)
111
+ if (defaultModel) {
112
+ const agents = (config.agents ?? {}) as any
113
+ const defaults = agents.defaults ?? {}
114
+ const modelsMap: Record<string, {alias: string}> = {
115
+ [`${PROVIDER_NAME}/${defaultModel}`]: {alias: defaultModel},
116
+ ...(imageModel && imageModel !== defaultModel
117
+ ? {[`${PROVIDER_NAME}/${imageModel}`]: {alias: imageModel}}
118
+ : {}),
119
+ }
120
+ for (const m of EXTRA_GATEWAY_MODELS) {
121
+ modelsMap[`${PROVIDER_NAME}/${m.id}`] = {alias: m.alias}
122
+ }
123
+ defaults.models = modelsMap
124
+ agents.defaults = defaults
125
+ config.agents = agents
126
+ }
127
+
107
128
  try {
108
129
  writeOpenclawConfig(configPath, config)
109
130
  api.logger.info(`config.repair: restored provider credentials (baseUrl + apiKey)`)
@@ -19,6 +19,14 @@ import {stripCliLogs} from '../lib/stripCliLogs'
19
19
 
20
20
  $.verbose = false
21
21
 
22
+ /** Extract the first emoji from a string, or null if none found. */
23
+ const EMOJI_RE =
24
+ /(?:\p{Emoji_Presentation}|\p{Emoji}\uFE0F)(?:\u200d(?:\p{Emoji_Presentation}|\p{Emoji}\uFE0F))*/u
25
+ function extractEmoji(value: string | undefined): string | null {
26
+ if (!value) return null
27
+ return value.match(EMOJI_RE)?.[0] ?? null
28
+ }
29
+
22
30
  const TOKEN_DIR = path.join(os.homedir(), '.openclaw', 'clawly')
23
31
  const TOKEN_FILE = path.join(TOKEN_DIR, 'expo-push-token.json')
24
32
  const EXPO_PUSH_URL = 'https://exp.host/--/api/v2/push/send'
@@ -73,7 +81,8 @@ export async function getAgentIdentity(
73
81
  */
74
82
  export async function resolveAgentTitle(agentId?: string): Promise<string> {
75
83
  const identity = await getAgentIdentity(agentId)
76
- return `${identity?.emoji ?? '🦞'} ${identity?.name ?? 'Clawly'}`
84
+ const emoji = extractEmoji(identity?.emoji) ?? '🦞'
85
+ return `${emoji} ${identity?.name ?? 'Clawly'}`
77
86
  }
78
87
 
79
88
  export async function sendPushNotification(
@@ -16,6 +16,51 @@ import type {PluginApi} from './index'
16
16
 
17
17
  export const PROVIDER_NAME = 'clawly-model-gateway'
18
18
 
19
+ /** Additional models available through the model gateway (beyond env-configured defaults). */
20
+ export const EXTRA_GATEWAY_MODELS: Array<{
21
+ id: string
22
+ name: string
23
+ alias: string
24
+ input: string[]
25
+ }> = [
26
+ {
27
+ id: 'anthropic/claude-sonnet-4.6',
28
+ name: 'anthropic/claude-sonnet-4.6',
29
+ alias: 'Claude Sonnet 4.6',
30
+ input: ['text', 'image'],
31
+ },
32
+ {
33
+ id: 'anthropic/claude-opus-4.6',
34
+ name: 'anthropic/claude-opus-4.6',
35
+ alias: 'Claude Opus 4.6',
36
+ input: ['text', 'image'],
37
+ },
38
+ {
39
+ id: 'z-ai/glm-5',
40
+ name: 'z-ai/glm-5',
41
+ alias: 'GLM-5',
42
+ input: ['text', 'image'],
43
+ },
44
+ {
45
+ id: 'minimax/minimax-m2.1',
46
+ name: 'minimax/minimax-m2.1',
47
+ alias: 'MiniMax M2.1',
48
+ input: ['text', 'image'],
49
+ },
50
+ {
51
+ id: 'minimax/minimax-m2.5',
52
+ name: 'minimax/minimax-m2.5',
53
+ alias: 'MiniMax M2.5',
54
+ input: ['text', 'image'],
55
+ },
56
+ {
57
+ id: 'qwen/qwen3.5-plus-02-15',
58
+ name: 'qwen/qwen3.5-plus-02-15',
59
+ alias: 'Qwen3.5 Plus',
60
+ input: ['text', 'image'],
61
+ },
62
+ ]
63
+
19
64
  export function resolveStateDir(api: PluginApi): string {
20
65
  return api.runtime.state?.resolveStateDir?.(process.env) ?? process.env.OPENCLAW_STATE_DIR ?? ''
21
66
  }
@@ -52,9 +97,47 @@ export function setupModelGateway(api: PluginApi): void {
52
97
  const configPath = path.join(stateDir, 'openclaw.json')
53
98
  const config = readOpenclawConfig(configPath)
54
99
 
55
- // Already configured skip
56
- if (config.models?.providers?.[PROVIDER_NAME]) {
57
- api.logger.info('Model gateway provider already configured.')
100
+ // If provider already exists, check if extra models or aliases need updating
101
+ const existingProvider = (config.models as any)?.providers?.[PROVIDER_NAME]
102
+ if (existingProvider) {
103
+ let dirty = false
104
+ const existingModels: Array<{id: string}> = existingProvider.models ?? []
105
+ const existingIds = new Set(existingModels.map((m: {id: string}) => m.id))
106
+
107
+ // Append any missing extra models
108
+ for (const m of EXTRA_GATEWAY_MODELS) {
109
+ if (!existingIds.has(m.id)) {
110
+ existingModels.push({id: m.id, name: m.name, input: m.input} as any)
111
+ dirty = true
112
+ }
113
+ }
114
+
115
+ // Ensure aliases exist for all models
116
+ const agents = (config.agents ?? {}) as any
117
+ const defaults = agents.defaults ?? {}
118
+ const existingAliases: Record<string, {alias: string}> = defaults.models ?? {}
119
+ for (const m of EXTRA_GATEWAY_MODELS) {
120
+ const key = `${PROVIDER_NAME}/${m.id}`
121
+ if (!existingAliases[key]) {
122
+ existingAliases[key] = {alias: m.alias}
123
+ dirty = true
124
+ }
125
+ }
126
+
127
+ if (dirty) {
128
+ existingProvider.models = existingModels
129
+ defaults.models = existingAliases
130
+ agents.defaults = defaults
131
+ config.agents = agents
132
+ try {
133
+ writeOpenclawConfig(configPath, config)
134
+ api.logger.info(`Model gateway updated: appended missing extra models/aliases.`)
135
+ } catch (err) {
136
+ api.logger.error(`Failed to update model gateway: ${(err as Error).message}`)
137
+ }
138
+ } else {
139
+ api.logger.info('Model gateway provider already configured.')
140
+ }
58
141
  return
59
142
  }
60
143
 
@@ -75,7 +158,7 @@ export function setupModelGateway(api: PluginApi): void {
75
158
  return
76
159
  }
77
160
 
78
- const models =
161
+ const defaultModels =
79
162
  defaultModel === imageModel || !imageModel
80
163
  ? [{id: defaultModel, name: defaultModel, input: ['text', 'image']}]
81
164
  : [
@@ -83,6 +166,11 @@ export function setupModelGateway(api: PluginApi): void {
83
166
  {id: imageModel, name: imageModel, input: ['text', 'image']},
84
167
  ]
85
168
 
169
+ const models = [
170
+ ...defaultModels,
171
+ ...EXTRA_GATEWAY_MODELS.map(({id, name, input}) => ({id, name, input})),
172
+ ]
173
+
86
174
  if (!config.models) config.models = {}
87
175
  if (!(config.models as any).providers) (config.models as any).providers = {}
88
176
  ;(config.models as any).providers[PROVIDER_NAME] = {
@@ -92,6 +180,22 @@ export function setupModelGateway(api: PluginApi): void {
92
180
  models,
93
181
  }
94
182
 
183
+ // Write agents.defaults.models map for UI dropdown aliases
184
+ const agents = (config.agents ?? {}) as any
185
+ const defaults = agents.defaults ?? {}
186
+ const modelsMap: Record<string, {alias: string}> = {
187
+ [`${PROVIDER_NAME}/${defaultModel}`]: {alias: defaultModel},
188
+ ...(imageModel && imageModel !== defaultModel
189
+ ? {[`${PROVIDER_NAME}/${imageModel}`]: {alias: imageModel}}
190
+ : {}),
191
+ }
192
+ for (const m of EXTRA_GATEWAY_MODELS) {
193
+ modelsMap[`${PROVIDER_NAME}/${m.id}`] = {alias: m.alias}
194
+ }
195
+ defaults.models = modelsMap
196
+ agents.defaults = defaults
197
+ config.agents = agents
198
+
95
199
  try {
96
200
  writeOpenclawConfig(configPath, config)
97
201
  api.logger.info(`Model gateway provider configured: ${baseUrl} with ${models.length} model(s).`)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@2en/clawly-plugins",
3
- "version": "1.18.2",
3
+ "version": "1.19.1",
4
4
  "module": "index.ts",
5
5
  "type": "module",
6
6
  "repository": {