Skip to content

fix: add Authorization Bearer header to remote generate requests#17

Open
Oliverbot26 wants to merge 1 commit into
yoloshii:mainfrom
Oliverbot26:fix/generate-remote-auth-header
Open

fix: add Authorization Bearer header to remote generate requests#17
Oliverbot26 wants to merge 1 commit into
yoloshii:mainfrom
Oliverbot26:fix/generate-remote-auth-header

Conversation

@Oliverbot26

Copy link
Copy Markdown
Contributor

Problem

generateRemote() never sends Authorization header — 401 on authenticated endpoints.

Changes

  • src/llm.ts: remoteLlmApiKey field + Bearer header in generateRemote + env in getDefaultLlamaCpp
  • src/openclaw/index.ts: inject CLAWMEM_LLM_API_KEY from gpuLlmApiKey

Follows embed auth pattern (remoteEmbedApiKey / CLAWMEM_EMBED_API_KEY). Verified HTTP 200 with z.ai.

generateRemote() never sent an Authorization header, causing 401 errors
on API endpoints that require auth. This patch:

- Adds remoteLlmApiKey config field + env var (CLAWMEM_LLM_API_KEY)
- Sends Authorization: Bearer header when key is present
- Injects CLAWMEM_LLM_API_KEY from plugin config (gpuLlmApiKey)
- Follows existing pattern used for embed (remoteEmbedApiKey)

@konradre konradre left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The core of this is right, and the missing Authorization header on remote generate is a real gap. The llm.ts side mirrors the embed path well: remoteLlmApiKey on the config, a Bearer header only when the key is set, and the CLAWMEM_LLM_API_KEY env read in getDefaultLlamaCpp. I checked the error paths too, and the key doesn't leak. The HTTP error branch logs only status and statusText, and the returned model comes from the response body, not the key. So the generate-side change is good as is.

The OpenClaw half is what I'd like reworked before this lands.

The plugin reads pluginCfg.gpuLlmApiKey, but that field isn't declared in the manifest, and the manifest is a closed schema. openclaw.plugin.json sets "additionalProperties": false, so a strict config validator can drop gpuLlmApiKey before register() ever sees it. As written, that injection may silently do nothing.

It's also redundant with a path that already works. OpenClaw spawns the clawmem subprocess with the parent environment spread in (see shell.ts and the two sibling spawn sites), so a CLAWMEM_LLM_API_KEY set on the gateway process already reaches generate once your llm.ts change is in. The plugin-config route adds a second way in that needs the manifest fixed to actually fire.

There's a secrets angle on top of that. The embed key has always been env-only, and putting an API key into plugin config as a plain string parks it wherever that config gets persisted. I'd rather not introduce a plaintext-secret config field unless OpenClaw gives us a redacted type for it.

Two ways forward, either works for me:

  1. Drop the gpuLlmApiKey plugin-config block and rely on the ambient CLAWMEM_LLM_API_KEY env, with a README line pointing people at it. Smallest change, and it works today.
  2. Keep the plugin-config route, but declare gpuLlmApiKey in the manifest, and only if we're comfortable storing it as a plain config string (or it gets proper secret handling).

Either way, could you add a couple of tests? One for remoteLlmApiKey passed directly on the config producing the Bearer header, and one for the CLAWMEM_LLM_API_KEY env path through getDefaultLlamaCpp. That pins down the behavior we actually want.

Happy to merge once the OpenClaw side is sorted.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants