free-coding-models 0.1.83 → 0.1.84

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.
@@ -0,0 +1,131 @@
1
+ /**
2
+ * @file openclaw.js
3
+ * @description OpenClaw config helpers for setting NVIDIA NIM defaults.
4
+ *
5
+ * @details
6
+ * This module owns the OpenClaw integration logic:
7
+ * - Read/write ~/.openclaw/openclaw.json
8
+ * - Ensure the NVIDIA provider block exists under models.providers
9
+ * - Patch the OpenClaw allowlist for NVIDIA models when needed
10
+ * - Set the selected model as the default primary model
11
+ *
12
+ * → Functions:
13
+ * - `loadOpenClawConfig` — read OpenClaw config as JSON
14
+ * - `saveOpenClawConfig` — persist OpenClaw config safely
15
+ * - `startOpenClaw` — set NVIDIA model as OpenClaw default
16
+ *
17
+ * @exports { loadOpenClawConfig, saveOpenClawConfig, startOpenClaw }
18
+ * @see ../patch-openclaw-models.js
19
+ */
20
+
21
+ import chalk from 'chalk'
22
+ import { copyFileSync, existsSync, mkdirSync, readFileSync, writeFileSync } from 'fs'
23
+ import { homedir } from 'os'
24
+ import { join } from 'path'
25
+ import { patchOpenClawModelsJson } from '../patch-openclaw-models.js'
26
+
27
+ // 📖 OpenClaw config: ~/.openclaw/openclaw.json (JSON format, may be JSON5 in newer versions)
28
+ const OPENCLAW_CONFIG = join(homedir(), '.openclaw', 'openclaw.json')
29
+
30
+ export function loadOpenClawConfig() {
31
+ if (!existsSync(OPENCLAW_CONFIG)) return {}
32
+ try {
33
+ // 📖 JSON.parse works for standard JSON; OpenClaw may use JSON5 but base config is valid JSON
34
+ return JSON.parse(readFileSync(OPENCLAW_CONFIG, 'utf8'))
35
+ } catch {
36
+ return {}
37
+ }
38
+ }
39
+
40
+ export function saveOpenClawConfig(config) {
41
+ const dir = join(homedir(), '.openclaw')
42
+ if (!existsSync(dir)) {
43
+ mkdirSync(dir, { recursive: true })
44
+ }
45
+ writeFileSync(OPENCLAW_CONFIG, JSON.stringify(config, null, 2))
46
+ }
47
+
48
+ // 📖 startOpenClaw: sets the selected NVIDIA NIM model as default in OpenClaw config.
49
+ // 📖 Also ensures the nvidia provider block is present with the NIM base URL.
50
+ // 📖 Does NOT launch OpenClaw — OpenClaw runs as a daemon, so config changes are picked up on restart.
51
+ export async function startOpenClaw(model, apiKey) {
52
+ console.log(chalk.rgb(255, 100, 50)(` 🦞 Setting ${chalk.bold(model.label)} as OpenClaw default…`))
53
+ console.log(chalk.dim(` Model: nvidia/${model.modelId}`))
54
+ console.log()
55
+
56
+ const config = loadOpenClawConfig()
57
+
58
+ // 📖 Backup existing config before touching it
59
+ if (existsSync(OPENCLAW_CONFIG)) {
60
+ const backupPath = `${OPENCLAW_CONFIG}.backup-${Date.now()}`
61
+ copyFileSync(OPENCLAW_CONFIG, backupPath)
62
+ console.log(chalk.dim(` 💾 Backup: ${backupPath}`))
63
+ }
64
+
65
+ // 📖 Patch models.json to add all NVIDIA models (fixes "not allowed" errors)
66
+ const patchResult = patchOpenClawModelsJson()
67
+ if (patchResult.wasPatched) {
68
+ console.log(chalk.dim(` ✨ Added ${patchResult.added} NVIDIA models to allowlist (${patchResult.total} total)`))
69
+ if (patchResult.backup) {
70
+ console.log(chalk.dim(` 💾 models.json backup: ${patchResult.backup}`))
71
+ }
72
+ }
73
+
74
+ // 📖 Ensure models.providers section exists with nvidia NIM block.
75
+ // 📖 Per OpenClaw docs (docs.openclaw.ai/providers/nvidia), providers MUST be nested under
76
+ // 📖 "models.providers", NOT at the config root. Root-level "providers" is ignored by OpenClaw.
77
+ // 📖 API key is NOT stored in the provider block — it's read from env var NVIDIA_API_KEY.
78
+ // 📖 If needed, it can be stored under the root "env" key: { env: { NVIDIA_API_KEY: "nvapi-..." } }
79
+ if (!config.models) config.models = {}
80
+ if (!config.models.providers) config.models.providers = {}
81
+ if (!config.models.providers.nvidia) {
82
+ config.models.providers.nvidia = {
83
+ baseUrl: 'https://integrate.api.nvidia.com/v1',
84
+ api: 'openai-completions',
85
+ models: [],
86
+ }
87
+ console.log(chalk.dim(' ➕ Added nvidia provider block to OpenClaw config (models.providers.nvidia)'))
88
+ }
89
+ // 📖 Ensure models array exists even if the provider block was created by an older version
90
+ if (!Array.isArray(config.models.providers.nvidia.models)) {
91
+ config.models.providers.nvidia.models = []
92
+ }
93
+
94
+ // 📖 Store API key in the root "env" section so OpenClaw can read it as NVIDIA_API_KEY env var.
95
+ // 📖 Only writes if not already set to avoid overwriting an existing key.
96
+ const resolvedKey = apiKey || process.env.NVIDIA_API_KEY
97
+ if (resolvedKey) {
98
+ if (!config.env) config.env = {}
99
+ if (!config.env.NVIDIA_API_KEY) {
100
+ config.env.NVIDIA_API_KEY = resolvedKey
101
+ console.log(chalk.dim(' 🔑 Stored NVIDIA_API_KEY in config env section'))
102
+ }
103
+ }
104
+
105
+ // 📖 Set as the default primary model for all agents.
106
+ // 📖 Format: "provider/model-id" — e.g. "nvidia/deepseek-ai/deepseek-v3.2"
107
+ if (!config.agents) config.agents = {}
108
+ if (!config.agents.defaults) config.agents.defaults = {}
109
+ if (!config.agents.defaults.model) config.agents.defaults.model = {}
110
+ config.agents.defaults.model.primary = `nvidia/${model.modelId}`
111
+
112
+ // 📖 REQUIRED: OpenClaw requires the model to be explicitly listed in agents.defaults.models
113
+ // 📖 (the allowlist). Without this entry, OpenClaw rejects the model with "not allowed".
114
+ // 📖 See: https://docs.openclaw.ai/gateway/configuration-reference
115
+ if (!config.agents.defaults.models) config.agents.defaults.models = {}
116
+ config.agents.defaults.models[`nvidia/${model.modelId}`] = {}
117
+
118
+ saveOpenClawConfig(config)
119
+
120
+ console.log(chalk.rgb(255, 140, 0)(` ✓ Default model set to: nvidia/${model.modelId}`))
121
+ console.log()
122
+ console.log(chalk.dim(' 📄 Config updated: ' + OPENCLAW_CONFIG))
123
+ console.log()
124
+ // 📖 "openclaw restart" does NOT exist. The gateway auto-reloads on config file changes.
125
+ // 📖 To apply manually: use "openclaw models set" or "openclaw configure"
126
+ // 📖 See: https://docs.openclaw.ai/gateway/configuration
127
+ console.log(chalk.dim(' 💡 OpenClaw will reload config automatically (gateway.reload.mode).'))
128
+ console.log(chalk.dim(' To apply manually: openclaw models set nvidia/' + model.modelId))
129
+ console.log(chalk.dim(' Or run the setup wizard: openclaw configure'))
130
+ console.log()
131
+ }