Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
54 changes: 39 additions & 15 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@ The happy-path installer interactively prompts only for:
- a `gp-...` API key
- a model picker from the curated registry

After the API key is entered, the installer fetches `GET /v1/models` from GonkaGate, requires the live catalog to contain every code-owned curated model, and uses that live metadata to populate the OpenClaw provider model catalog.

If the active OpenClaw config path does not exist yet, the installer runs `openclaw setup` automatically to initialize the base OpenClaw config and workspace, ensures a minimal local Gateway mode when OpenClaw setup did not already pick one, and then applies GonkaGate-managed settings.

After setup, users can run a read-only verification command:
Expand All @@ -31,7 +33,7 @@ After setup, users can run a read-only verification command:
npx @gonkagate/openclaw verify
```

That command checks the current active OpenClaw config path, confirms that the managed GonkaGate provider fields, curated primary model, and owner-only file permissions still match the supported setup, and then verifies that the active local OpenClaw runtime is healthy enough to load that config through read-only CLI probes.
That command checks the current active OpenClaw config path, confirms that the managed GonkaGate provider fields, curated provider model catalog, curated `/models` allowlist, curated primary model, and owner-only file permissions still match the supported setup, and then verifies that the active local OpenClaw runtime is healthy enough to load that config through read-only CLI probes.

If the installer finishes but the local OpenClaw Gateway is not running yet, that is still a successful install outcome. In that case the installer prints one exact next command:

Expand All @@ -51,7 +53,7 @@ These decisions are part of the repo contract. Changing them is not a small refa

- `models.providers.openai.baseUrl` is always `https://api.gonkagate.com/v1`
- `models.providers.openai.api` is always `openai-completions`
- `models.providers.openai.models` must always end up as a valid array for current OpenClaw releases
- `models.providers.openai.models` must always end up as a valid array containing the curated GonkaGate model catalog entries returned by `GET /v1/models`, while preserving unrelated existing entries
- users do not choose the base URL and cannot override it in the public flow
- the provider is always `openai`, not `anthropic`
- model choice comes only from a code-owned curated registry
Expand All @@ -70,7 +72,8 @@ These decisions are part of the repo contract. Changing them is not a small refa
- config files must be written with owner-only permissions
- backup files must be written with owner-only permissions
- `agents.defaults.model.primary` must be updated to the selected curated model
- `agents.defaults.models` should only be merged when it already exists
- `agents.defaults.models` must be created or updated with the curated GonkaGate allowlist so OpenClaw `/models` can switch between supported models
- the installer must never expose arbitrary live `GET /v1/models` entries as selectable models unless they are also in the code-owned curated registry

Current honest limitation:

Expand All @@ -85,6 +88,7 @@ This repo does:
- onboarding for local `OpenClaw`
- read-only verification for the managed GonkaGate OpenClaw config
- read-only runtime verification for the active local OpenClaw Gateway and resolved primary model
- live GonkaGate model catalog validation through `GET /v1/models` before prompting for a model
- first-run OpenClaw config bootstrap through `openclaw setup` when needed
- first-run minimal local Gateway bootstrap when `gateway.mode` is absent
- persistent config writing into the active OpenClaw config path resolved from the current environment
Expand Down Expand Up @@ -128,6 +132,7 @@ This repo does not do:
│ │ ├── check-openclaw.ts
│ │ ├── cli-display.ts
│ │ ├── file-permissions.ts
│ │ ├── gonkagate-models.ts
│ │ ├── install-use-case.ts
│ │ ├── load-settings.ts
│ │ ├── managed-settings-access.ts
Expand Down Expand Up @@ -157,6 +162,7 @@ This repo does not do:
└── test/
├── bootstrap-gateway.test.ts
├── cli-run.test.ts
├── gonkagate-models.test.ts
├── install-use-case.test.ts
├── load-settings.test.ts
├── merge-settings.test.ts
Expand Down Expand Up @@ -199,6 +205,7 @@ It is responsible for:
- applying first-run-only local Gateway bootstrap logic
- validating the current config before prompting for secrets
- running the hidden API key prompt
- fetching and validating the live GonkaGate model catalog before model selection
- selecting the model
- merging GonkaGate settings into the existing config
- validating the generated candidate config before replacing the live file
Expand Down Expand Up @@ -249,6 +256,19 @@ This file contains the interactive prompts built on top of `@inquirer/prompts`:

The key rule here is: do not log secrets and do not turn the main UX into CLI args for secrets.

### `src/install/gonkagate-models.ts`

This file owns the GonkaGate `GET /v1/models` trust boundary.

It must:

- call `https://api.gonkagate.com/v1/models` with the entered `gp-...` key
- reject authentication failures before config writes
- validate and normalize the external JSON response before the install use-case consumes it
- keep selectable models restricted to the code-owned curated registry
- require the live catalog to contain every curated supported model
- map live metadata into OpenClaw provider model catalog entries without trusting unrelated response fields

### `src/install/check-openclaw.ts`

Verifies that the local `openclaw` CLI exists and is callable through `openclaw --version`.
Expand Down Expand Up @@ -319,11 +339,11 @@ It must:
- preserve unrelated top-level keys
- preserve unrelated provider entries
- overwrite only OpenClaw-managed `openai` provider fields
- preserve an existing `models.providers.openai.models` array when present
- initialize `models.providers.openai.models` to `[]` when missing so the resulting config remains valid for current OpenClaw releases
- preserve unrelated existing `models.providers.openai.models` entries when present
- add or update curated GonkaGate provider model catalog entries under `models.providers.openai.models`
- set `agents.defaults.model.primary`
- preserve unrelated keys inside `agents.defaults.model`
- merge `agents.defaults.models` only when it already exists
- create or update `agents.defaults.models` with every curated GonkaGate allowlist entry needed by OpenClaw `/models`

It must consume the shared managed-settings boundary instead of re-deriving managed object shapes locally.

Expand Down Expand Up @@ -395,7 +415,8 @@ It must:
- fail if GonkaGate-managed provider fields do not match the fixed product values
- fail if `models.providers.openai.apiKey` is missing or malformed
- fail if `agents.defaults.model.primary` does not point at a curated supported model
- fail if `agents.defaults.models` exists but the managed allowlist entry is missing or mismatched
- fail if `models.providers.openai.models` omits a curated GonkaGate model catalog entry
- fail if `agents.defaults.models` is missing or any managed curated allowlist entry is missing or mismatched
- fail if the config file permissions are not owner-only
- never rewrite the config during verification

Expand Down Expand Up @@ -439,6 +460,7 @@ Baseline tests cover:
- first-run minimal Gateway bootstrap behavior
- merge behavior
- model selection behavior
- live GonkaGate model catalog parsing and filtering behavior
- read-only verification behavior
- verify orchestration ownership
- invalid JSON5 handling
Expand All @@ -457,13 +479,14 @@ Baseline tests cover:
6. If Gateway mode is still unset after that bootstrap, the installer sets `gateway.mode` to `local`
7. The installer validates the current config through `openclaw config validate --json`
8. The installer securely prompts for a `gp-...` API key
9. The installer shows the curated model picker
10. The config is merged with GonkaGate-managed OpenAI settings
11. The generated candidate config is validated through `openclaw config validate --json`
12. A backup is created only when an existing config is being overwritten
13. JSON is written back to disk
14. The installer performs a best-effort runtime probe
15. If the local Gateway is not running yet, install still succeeds and prints the exact next command `openclaw gateway`
9. The installer fetches `GET /v1/models` and confirms every curated supported model is live
10. The installer shows the curated model picker
11. The config is merged with GonkaGate-managed OpenAI settings, provider model catalog entries, and `/models` allowlist entries
12. The generated candidate config is validated through `openclaw config validate --json`
13. A backup is created only when an existing config is being overwritten
14. JSON is written back to disk
15. The installer performs a best-effort runtime probe
16. If the local Gateway is not running yet, install still succeeds and prints the exact next command `openclaw gateway`

Optional follow-up verification path:

Expand All @@ -472,7 +495,7 @@ Optional follow-up verification path:
3. The CLI resolves the active OpenClaw config path from the current environment
4. The CLI loads that config file without modifying it
5. The CLI validates the current config through `openclaw config validate --json`
6. The CLI verifies the managed GonkaGate provider fields, curated primary model, and owner-only file permissions
6. The CLI verifies the managed GonkaGate provider fields, curated provider model catalog entries, curated `/models` allowlist, curated primary model, and owner-only file permissions
7. The CLI confirms that the local OpenClaw Gateway RPC is reachable and the health snapshot is healthy
8. The CLI confirms that OpenClaw resolves the expected primary model through `openclaw models status --plain`
9. The CLI reports success or exits with a clear error
Expand All @@ -482,6 +505,7 @@ Optional follow-up verification path:
- Do not add a base URL prompt
- Do not add free-form custom model input
- Do not make `--api-key` a recommended or supported path
- Do not expose arbitrary `GET /v1/models` results as selectable models outside the curated registry
- Do not require `openclaw onboard` in the main public flow
- Do not modify shell rc files
- Do not write `.env`
Expand Down
4 changes: 3 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
## [Unreleased]

- Added `moonshotai/Kimi-K2.6` to the curated GonkaGate model registry under the `kimi-k2.6` model key and made it the default model.
- The installer now fetches GonkaGate `GET /v1/models` after API key entry, requires every curated model to be live, and uses the live metadata for OpenClaw provider model catalog entries.
- The installer now creates or updates `agents.defaults.models` with the curated GonkaGate allowlist so OpenClaw `/models` can switch between supported models.
- Raised the minimum supported Node.js runtime for this package to Node 22.14+ so it matches current OpenClaw install support expectations.
- CI and publish workflows now both run on Node 22.14.0, and runtime documentation no longer advertises Node 18 support.
- Upgraded `@inquirer/prompts`, `commander`, and `write-file-atomic` to current releases that are now appropriate for a Node 22.14+ baseline.
Expand All @@ -16,7 +18,7 @@
- Installer runtime probes now distinguish a not-yet-running local Gateway from real runtime mismatches; when the Gateway is simply not running yet, install succeeds and prints `openclaw gateway` as the exact next step.
- Runtime verification now treats malformed or shape-drifted OpenClaw probe output as a strict compatibility failure instead of downgrading it to a benign Gateway-not-running result.
- The installer now validates both the current config and the generated candidate config through `openclaw config validate --json` before writing.
- The managed OpenAI provider config now preserves an existing `models.providers.openai.models` array and initializes it to `[]` when missing so configs stay valid on current OpenClaw releases.
- The managed OpenAI provider config now preserves unrelated existing `models.providers.openai.models` entries while adding or updating curated GonkaGate catalog entries required by OpenClaw's model picker.
- The CLI now resolves the active config path compatibly with stable OpenClaw 2026.4.1 by preferring existing legacy config candidates locally before falling back to canonical `openclaw.json`, so install and verify stay aligned on legacy hosts.

## [0.1.0] - 2026-04-01
Expand Down
15 changes: 9 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ npx @gonkagate/openclaw
You will be asked for:

- your GonkaGate API key (`gp-...`) in a hidden interactive prompt
- a model from the curated GonkaGate registry
- a model from the curated GonkaGate registry after the installer confirms the live catalog through `GET /v1/models`

If the active OpenClaw config path does not exist yet, the installer will run `openclaw setup` automatically, ensure a minimal local Gateway mode, and then apply the GonkaGate-specific provider settings.

Expand All @@ -53,8 +53,9 @@ This command checks:
- that `models.providers.openai.baseUrl` is `https://api.gonkagate.com/v1`
- that `models.providers.openai.api` is `openai-completions`
- that `models.providers.openai.apiKey` exists and still looks like a `gp-...` key
- that `models.providers.openai.models` includes the curated GonkaGate model catalog entries needed by OpenClaw
- that `agents.defaults.model.primary` points at a curated GonkaGate model
- that `agents.defaults.models` stays in sync when that allowlist exists
- that `agents.defaults.models` contains the curated GonkaGate switcher allowlist used by OpenClaw `/models`
- that the config file still uses owner-only permissions
- that the local OpenClaw Gateway RPC is reachable through `openclaw gateway status --require-rpc --json`
- that `openclaw health --json` reports a healthy runtime
Expand Down Expand Up @@ -86,13 +87,14 @@ It also:
- bootstraps `gateway.mode: "local"` on true first-run installs when OpenClaw has not already set a gateway mode
- refuses to overwrite an invalid JSON5 config
- refuses to overwrite a config that fails current OpenClaw schema validation
- fetches `GET /v1/models` with the entered GonkaGate API key, requires every curated model to be present, and keeps model selection inside the code-owned curated registry
- creates a backup before overwriting an existing config
- preserves unrelated top-level config keys
- preserves other provider entries under `models.providers`
- overwrites only the managed `models.providers.openai` fields
- preserves an existing `models.providers.openai.models` array and initializes it to `[]` when missing so the resulting config remains valid for current OpenClaw releases
- merges live curated GonkaGate entries into `models.providers.openai.models` while preserving unrelated existing entries
- sets `agents.defaults.model.primary` to the chosen curated model
- merges `agents.defaults.models` only when that allowlist already exists
- creates or updates `agents.defaults.models` with the curated GonkaGate switcher allowlist so `/models` can switch between supported models
- validates the generated config with `openclaw config validate --json` before replacing the live file
- writes the config atomically with owner-only permissions
- writes backup files with owner-only permissions
Expand All @@ -106,9 +108,9 @@ This installer manages only these OpenClaw surfaces:
- `models.providers.openai.baseUrl`
- `models.providers.openai.apiKey`
- `models.providers.openai.api`
- `models.providers.openai.models` as a valid array, while preserving any existing entries
- `models.providers.openai.models` as a valid array containing the live curated GonkaGate model catalog, while preserving unrelated existing entries
- `agents.defaults.model.primary`
- `agents.defaults.models["openai/<model-id>"].alias` only when `agents.defaults.models` already exists
- `agents.defaults.models["openai/<model-id>"].alias` for curated GonkaGate models

Everything else is left intact.

Expand Down Expand Up @@ -157,6 +159,7 @@ Implementation choices in this repository were aligned to these primary sources:
- [OpenClaw Configuration Reference](https://docs.openclaw.ai/gateway/configuration-reference)
- [GonkaGate OpenClaw Integration Guide](https://gonkagate.com/en/docs/guides/openclaw-integration)
- [GonkaGate Model Selection Guide](https://gonkagate.com/en/docs/guides/overview/models)
- [GonkaGate GET /v1/models API Reference](https://gonkagate.com/en/docs/api/api-reference/models/get-models)

## Development

Expand Down
Loading
Loading