#Full harness (bootstrap files) with google-gemini-cli backend — is it possible?

1 messages · Page 1 of 1 (latest)

soft copper
#

Context: OpenClaw gateway on WSL/Ubuntu, backend google-gemini-cli (gemini-3.1-pro-preview) via oauth-personal. Workspace at ~/.openclaw/workspace/ has populated IDENTITY.md, USER.md, SOUL.md, BOOTSTRAP.md, MEMORY.md.

On /new the agent responds in English with the stock Gemini CLI persona and doesn't know its configured name/emoji. I installed a shim on the gemini binary that logs argv, ENV, and the contents of
GEMINI_CLI_SYSTEM_SETTINGS_PATH before exec-ing the real binary. Findings:

  • --prompt on /new carries only
    BARE_SESSION_RESET_PROMPT_BASE + Current time line
  • settings.json carries only MCP config (filesystem +
    openclaw) — no persona
  • ENV only has tokens/paths — no persona
    Reading dist/, prepare.runtime calls
    resolveBootstrapContextForRun, builds a systemPrompt
    with contextFiles, then
    applySystemPromptOverrideToSession
    (model-context-tokens-.js) mutates
    session.agent.state.systemPrompt. That's the embedded
    Pi Agent's session — not the spawned gemini child.
    cli-backend-
    .js exposes only --prompt / --resume /
    --output-format. So for embedded backends bootstrap
    lands as systemInstruction, but on google-gemini-cli
    there's no channel that carries it.
    Occasional "correct" answers come from Telegram Sender
    (untrusted metadata) in the prompt or from --resume
    pulling residual content from older
    ~/.gemini/tmp/.../session-*.json — not from the
    OpenClaw harness.
    Question: Is there an official way (config / plugin /
    extension hook) to get full harness behavior (bootstrap
    injected as systemInstruction, with
    cache-by-sessionKey, heartbeat, continuation-skip,
    agent-scoped filtering) on google-gemini-cli? If
    intentionally partial for spawn-based backends, is the
    recommended workaround a workspace GEMINI.md with
    @IDENTITY.md/@USER.md refs — or switching to a
    direct-API Gemini backend? And is prepending bootstrap
    to --prompt on this backend on the roadmap, or avoided
    (token cost per turn)?
wraith skyBOT
distant latchBOT
#

To help others find answers, you can mark your question as solved via Right click solution message -> Apps -> ✅ Mark Solution

wraith skyBOT
soft copper
#

what to do?

twin merlinBOT
#

Short answer: no, not on the stock google-gemini-cli CLI backend.

I checked current docs/source on 2026.4.9 plus current ref, and your reading matches it:

  • CLI backends are documented as a text-only fallback runtime, not the full embedded/provider path: https://docs.openclaw.ai/gateway/cli-backends
  • prepare.ts still builds the OpenClaw system prompt from bootstrap/context files.
  • But cli-runner/helpers.ts only sends that prompt if the backend has systemPromptArg or systemPromptFileConfigKey.
  • The bundled Gemini CLI backend (extensions/google/cli-backend.ts) defines neither. It only uses:
    • --prompt {prompt}
    • --resume {sessionId}
    • Gemini settings file for MCP
  • And bundle-mcp.ts writes GEMINI_CLI_SYSTEM_SETTINGS_PATH with MCP config, not persona/systemInstruction.

So today there is no config-only switch that makes google-gemini-cli behave like the direct embedded google/... provider.

What that means in practice:

#
  1. If you want full OpenClaw persona/bootstrap fidelity for normal replies, use the direct google/... provider.
    That is the clean recommendation.
    Docs: https://docs.openclaw.ai/providers/google

  2. If you must stay on Gemini CLI OAuth, a Gemini-side instruction file (GEMINI.md, etc.) is the pragmatic workaround.
    But it is only a workaround, not true OpenClaw harness injection. You will still get Gemini-owned resume/state behavior, not OpenClaw-owned systemInstruction semantics.

  3. If you want Gemini CLI specifically with full harness/runtime controls, use ACP Gemini CLI, not CLI backends.
    Docs: https://docs.openclaw.ai/tools/acp-agents

On the roadmap question: I do not see a shipped feature or docs note for “prepend bootstrap to --prompt” on this backend. Also, the current code looks more like a missing transport path than an intentional token-saving choice, because OpenClaw already builds the system prompt and then drops it when the backend has no system-prompt channel.

So the honest answer is:

  • Official full-harness on google-gemini-cli CLI backend: no
  • Recommended workaround if staying on CLI OAuth: Gemini-side instruction file
  • Recommended real fix: switch normal agent replies to direct google/...
#

If you want, I can also help you sketch the cleanest config migration from google-gemini-cli/... to google/... without losing the rest of your setup.

#

If this is your main OpenClaw agent, I’d do this:

  1. Switch to direct google/... for normal replies.
    That’s the only clean way to get the real OpenClaw bootstrap/persona path today.
    https://docs.openclaw.ai/providers/google

  2. Only keep google-gemini-cli/... if you specifically need Gemini CLI OAuth.
    In that case, treat it as a partial/fallback runtime and use a Gemini-side instruction file (GEMINI.md) as a workaround, not a full fix.
    https://docs.openclaw.ai/gateway/cli-backends

  3. If you want “Gemini CLI, but with real harness/session controls”, use ACP Gemini CLI, not the CLI backend path.
    https://docs.openclaw.ai/tools/acp-agents

And if the missing bootstrap injection matters for your use case, I’d file a feature request for:

  • google-gemini-cli prompt-prepend fallback, or
  • a generic CLI-backend systemPrompt -> prompt transport mode
soft copper
#

"Set acp.enabled=true + agents.list[{id:main,
runtime:{type:acp, acp:{agent:gemini}}}].
Gateway still routes via [agent/cli-backend] cli
exec provider=google-gemini-cli. What else is
required for agent main to dispatch via ACP
instead of CLI backend? Is agents.list ignored
when an agent already exists under
~/.openclaw/agents/main/? Does /acp spawn gemini
work for on-demand sessions but not default
message routing?"

twin merlinBOT
#

Yep, this part is the key: agents.list[].runtime.type="acp" does not by itself replace normal inbound/default-agent routing.

What it does today is:

  • provide ACP defaults for an agent
  • when the conversation is already on the ACP path
    • via /acp spawn ... --bind here
    • or via a top-level bindings[] entry with type: "acp"

So your behavior is expected:

  • normal messages route to main
  • main then uses its normal reply/model pipeline
  • if that model is google-gemini-cli/..., you see [agent/cli-backend]

Direct answers

#
  • No, ~/.openclaw/agents/main/ existing is not why this happens.
  • No, agents.list is not being ignored.
  • Yes, /acp spawn gemini is the on-demand ACP path.
  • Yes, default message routing stays non-ACP unless the conversation is ACP-bound.

What to do

Option A, easiest for this thread/channel

Run:

/acp spawn gemini --bind here

Then follow-up messages in this same conversation should route to the Gemini ACP session.

Option B, persistent config for a specific channel/thread

#

Use a top-level ACP binding, for example:

{
  agents: {
    list: [
      {
        id: "main",
        runtime: {
          type: "acp",
          acp: {
            agent: "gemini",
            backend: "acpx",
            mode: "persistent",
            cwd: "~/.openclaw/workspace",
          },
#
        },
      },
    ],
  },
  bindings: [
    {
      type: "acp",
      agentId: "main",
      match: {
        channel: "discord",
        accountId: "default",
        peer: { kind: "channel", id: "1495586444524261406" }
      }
    }
  ]
#
}

That is the piece you were missing.

One more check

Make sure:

acp: {
  enabled: true,
  dispatch: { enabled: true }
}

dispatch.enabled defaults to true, but worth checking.

soft copper
#

Observed behavior:

  • /new → bot replies ✅ ACP session reset in
    place. (ACP resolved the reset).
  • Subsequent turns → gateway log shows
    [agent/cli-backend] cli exec:
    provider=google-gemini-cli, i.e. turns routed via
    cli-backend, not ACP. No IDENTITY/SOUL/USER
    bootstrap. Only mcp_openclaw_memory_search
    available.

Dist-code trace:

  • targets-Ouj9LpnX.js:23
    resolveRawConfiguredAcpSessionKey iterates
    listAcpBindings(cfg) raw, accepts any peer.id
    explains why /new works.
  • channel-vcOTUZws.js:466-472
    normalizeTelegramAcpConversationId (Telegram
    plugin's ACP binding compiler):
    if (!parsed || !parsed.chatId.startsWith("-"))
    return null;
  • i.e. only compiles ACP bindings for chat IDs
    starting with - (groups/supergroups). DMs have
    positive IDs, so the binding is dropped silently
    by compileConfiguredBindingRegistry — turn
    dispatch falls back to cli-backend.

Docs (docs.openclaw.ai/tools/acp-agents) only show
Telegram peer.kind: "group" examples
(topic-based, negative chat IDs). No DM example.

Question:
Is this restriction (ACP on Telegram = groups
only, never DMs) intentional in v2026.4.14, or a
gap/regression? Is there a supported way to get
full ACP harness in a 1:1 DM conversation — a
config flag, alternative adapter, or recipe — or
is the only path today to move the workflow into a
private group/supergroup?

twin merlinBOT
#

I checked the current docs + adapter code, and the answer is a bit annoying:

Short version

  • Telegram bindings[] { type: "acp" } is currently group/supergroup topic scoped, not 1:1 DM scoped.
  • So for config-declared persistent ACP bindings, your DM case is not supported today.
  • The fact that /new sees it but normal turn dispatch does not looks like an inconsistent code path / bug, not a supported DM ACP mode.

Why I’m saying that

The Telegram adapter currently does this:

  • extensions/telegram/src/channel.ts
    • normalizeTelegramAcpConversationId(...)
    • returns null unless chatId.startsWith("-")
  • same for inbound matching, it rejects non-- chat IDs there too
#

So configured ACP bindings only compile for negative Telegram chat IDs, meaning groups/supergroups.

That lines up with the Telegram channel docs, which explicitly say the ACP binding example is:

“currently scoped to forum topics in groups and supergroups.”

See: https://docs.openclaw.ai/channels/telegram

Important distinction

There are two different paths here:

  1. Configured ACP binding via top-level bindings[]

    • Telegram DM: not supported today
    • Telegram group/supergroup topic: supported
  2. Current-conversation ACP bind via chat command

#
  • Telegram advertises supportsCurrentConversationBinding: true
    • so the supported recipe for a DM is to try:
/acp spawn gemini --bind here

That is the best-supported DM recipe right now.

So, what should you do?

If you need config-driven always-on ACP

Use a private supergroup/forum topic.
That is the supported Telegram ACP binding path today.

If you just need ACP in a 1:1 Telegram conversation

Use:

#
/acp spawn gemini --bind here

That should use the current-conversation binding path instead of the top-level configured-binding compiler.

What will not fix it

  • channels.telegram.direct.<id>.topics.<threadId>.agentId
    • that only routes to a specific agent
    • it does not turn the DM into an ACP harness conversation

My read on intent

  • Configured Telegram ACP in DMs: effectively not supported
  • /new partially honoring the DM ACP binding anyway: likely a gap/bug/inconsistency

So if you want this fixed properly, I’d file a GitHub issue with exactly the trace you posted:

willow ferry
#

@twin merlin what this mean? don't use gemini cli?

twin merlinBOT
#

Not exactly “don’t use Gemini CLI”.

More like:

  • Use google/... if you want full OpenClaw behavior as your main agent
    (IDENTITY/SOUL/USER/bootstrap, cleaner harness behavior).

  • Use google-gemini-cli/... if you want:

    • Gemini OAuth
    • a CLI/fallback style runtime
    • or Gemini CLI specifically for ACP / external harness work

The problem is: Gemini CLI is not the same integration path.
So as a primary default reply model, it currently behaves more like a partial CLI backend than a full embedded OpenClaw provider.

So my practical recommendation is:

#
  • main everyday assistantgoogle/...
  • Gemini CLI because you specifically want Gemini CLI → okay, but expect quirks
  • ACP/coding-harness style Gemini session → Gemini CLI is fine there

So, bluntly: don’t use Gemini CLI as your main default agent if you care about full bootstrap/persona fidelity.

willow ferry
twin merlinBOT
#

Yeah, fair question 😅

“full bootstrap/persona fidelity” just means:

OpenClaw can fully teach the model:

  • who it is (IDENTITY.md)
  • how it should behave (SOUL.md)
  • who the user is (USER.md)
  • startup/session context (BOOTSTRAP.md)
  • extra system instructions, skills, heartbeat stuff, etc.

So if that works properly, the bot actually behaves like your configured assistant, not like generic Gemini.

“not the same integration path” means

There are 2 different ways OpenClaw can talk to Gemini:

#
  1. google/...

    • OpenClaw talks to Gemini more directly
    • easier to pass full system prompt / persona / bootstrap
  2. google-gemini-cli/...

    • OpenClaw launches the Gemini CLI app
    • that CLI only exposes a limited interface
    • so some OpenClaw instructions never make it through cleanly

In plain English

With direct google/...:

  • “you are Krill 🦐”
  • “use SOUL.md
  • “this is the user”
  • “follow bootstrap context”
#

all reach the model much more reliably.

With Gemini CLI:

  • OpenClaw is kind of talking through another app
  • that app does not currently expose a good place for all that persona/bootstrap context
  • so you can get “stock Gemini” behavior instead

Simple version

If you want:

  • assistant feels like your assistant → use google/...
  • Gemini CLI specifically → okay, but expect it to feel less customized

So “fidelity” here just means how faithfully the model follows the assistant identity OpenClaw tried to give it.

willow ferry
twin merlinBOT
#

No, not fully.

ACP gives you better session/harness behavior, like:

  • persistent bound sessions
  • better external harness control
  • coding-agent style workflows
  • routing a conversation to Gemini CLI as a harness

But ACP still means:

  • OpenClaw is talking to an external harness/runtime
  • not using the normal native model-provider path

So:

  • google/... = most “fully OpenClaw assistant”
#
  • Gemini CLI via ACP = most “fully Gemini CLI harness inside OpenClaw”
  • Gemini CLI as plain CLI backend = least faithful to OpenClaw persona/bootstrap

Easy rule

If you want:

  • personal assistant that really feels like OpenClaw → use google/...
  • Gemini CLI as a coding/runtime tool inside OpenClaw → use ACP

So ACP improves the workflow, not magically makes Gemini CLI become the same thing as native OpenClaw model integration.

willow ferry
twin merlinBOT
#

Yeah, roughly, yes.

Not literally the website, but closer to “plain Gemini with some OpenClaw wrapping” than to “full native OpenClaw assistant.”

As a plain Gemini CLI backend you still get some OpenClaw stuff, like:

  • chat routing
  • session handling
  • some MCP/tool bridging
  • delivery back to Discord/Telegram/etc.

But the core personality/instruction layer can feel a lot more like stock Gemini, similar to using Gemini directly.

So:

  • plain Gemini CLI backend = “Gemini, wrapped by OpenClaw”
  • direct google/... = “OpenClaw assistant using Gemini underneath”
#

That’s the real difference.

willow ferry
twin merlinBOT
#

Honestly, there isn’t a perfect “free + full OpenClaw-assistant feel” setup right now.

Best practical split is:

  • Want it to feel like OpenClaw?
    Use a native/direct provider integration for your main assistant, and keep CLI backends as fallback only.

  • Want it as free as possible?
    Gemini CLI is the closest, but you give up some of the OpenClaw identity/persona fidelity.

So the compromise I’d recommend is:

  1. main assistant → direct/native provider path
  2. Gemini CLI → fallback or ACP harness use
  3. don’t use Gemini CLI as the primary everyday assistant if the “personal OpenClaw assistant” feel matters most

For up-to-date free/cheap provider choices, ask in #models and check:

willow ferry
twin merlinBOT
#

Yep, more or less:

What Gemini CLI is lacking vs a native provider path

Mostly the clean OpenClaw instruction path, especially:

  • full system prompt delivery
  • IDENTITY / SOUL / USER / BOOTSTRAP context reaching the model cleanly
  • more reliable “assistant behaves like your assistant” behavior

So the gap is less “tools” and more personality + instruction fidelity.

OpenRouter / NVIDIA

Yes, those are much closer to the native provider path in OpenClaw than Gemini CLI is.

So if you use:

  • openrouter/...
#
  • nvidia/...

that is generally in the “full OpenClaw assistant personality can be carried properly” bucket, unlike google-gemini-cli/....

That said:

  • OpenRouter is a router, so quality depends a lot on which upstream model you pick.
  • NVIDIA is also a normal provider integration, not a CLI shim, so it’s better for this than Gemini CLI.

Docs:

“what model would be best?”

That part changes too fast, so I don’t want to give you stale advice.

willow ferry
twin merlinBOT
#

Easiest way to think about it:

“personality fidelity” =

does it feel like your OpenClaw assistant, or does it feel like generic Gemini?

For example:

  • says the right name/emoji
  • follows your identity files
  • keeps the tone you configured
  • acts like OpenClaw, not stock Gemini

How much does Gemini CLI + ACP help?

A lot for workflow.
Not that much for personality.

#

So:

  • Gemini CLI plain backend

    • weak OpenClaw personality
    • weak customization
    • feels more like stock Gemini
  • Gemini CLI + ACP

    • better session behavior
    • better persistent harness/workspace flow
    • still not the same as native OpenClaw personality injection
  • native provider

    • best chance of actually feeling like your OpenClaw assistant

Super short version

#

ACP helps with:

  • session continuity
  • harness behavior
  • coding workflow

ACP does not fully solve:

  • “why does this still sound like Gemini instead of my configured assistant?”

So if your question is:

“Will Gemini CLI + ACP make it feel fully like OpenClaw?”

Answer: no, only partially.
It helps the workflow much more than the personality.

willow ferry
twin merlinBOT
#

Easiest path right now:

1) Make sure ACP is on

{
  acp: { enabled: true }
}

2) Make sure Gemini CLI already works on the host

If gemini login/auth is broken, ACP won’t fix that.

3) In chat, run:

/acp doctor
#

4) Then start a Gemini ACP session

If you want this same chat to become Gemini-backed:

/acp spawn gemini --bind here

If you want a separate thread/topic instead:

/acp spawn gemini --mode persistent --thread auto

5) After that, use:

/acp status
#
/acp steer continue with X
/acp close

Important

If your goal is Gemini CLI as ACP, do not rely on the normal google-gemini-cli/... model routing for that conversation.
Use /acp spawn gemini ... explicitly.

Telegram note

For Telegram, --thread auto|here needs:

channels: {
  telegram: {
    threadBindings: {
#
      spawnAcpSessions: true
    }
  }
}

If you are in a Telegram 1:1 DM and the configured ACP binding path is weird, try:

/acp spawn gemini --bind here

That is the cleaner path than relying on top-level ACP bindings there right now.

Docs: https://docs.openclaw.ai/tools/acp-agents

#

If you want, I can give you the exact minimal config for Discord or Telegram for Gemini ACP.

willow ferry
twin merlinBOT
#

No.

If you set your model to:

google-gemini-cli/...

that means:

  • use Gemini CLI as a model/backend
  • not “use Gemini CLI through ACP”

Those are separate paths:

  • google-gemini-cli/... = CLI backend model
  • /acp spawn gemini ... = ACP harness session
#

So ACP is not automatic just because the model is Gemini CLI.

If you want ACP, you need to do it explicitly, for example:

/acp spawn gemini --bind here

or configure an ACP binding for that conversation.

Super short version

  • model config → picks the normal reply backend
  • ACP → starts/binds a separate harness session

So: Gemini CLI model != Gemini ACP automatically.

willow ferry
#

@twin merlin so what about using browser as a model?

twin merlinBOT
#

Browser is not a model in OpenClaw, it’s a tool.

So:

  • model = the brain that reasons and writes
  • browser = the tool it uses to open pages, click, type, inspect sites

You don’t replace the model with browser.
You use:

  • a real model/provider
  • plus the browser tool

Example mental model

  • google/... or openrouter/... or nvidia/... = model
  • browser = lets that model interact with websites
#

So if you want “OpenClaw assistant, but it can use the web”, the setup is:

  • native provider model
  • browser tool enabled

Not “browser as model”.

If you want, I can explain the difference between:

  • model
  • CLI backend
  • ACP harness
  • tool/browser

in one tiny diagram.

willow ferry
twin merlinBOT
#

Ah, got it. Technically you could hack something like that, but I would not recommend it, and I wouldn’t treat it as a supported OpenClaw setup.

Why:

  • super brittle , any UI change breaks it
  • CAPTCHAs / login / anti-bot checks
  • likely terms/account-risky
  • bad latency
  • poor structured output / tool reliability
  • still not a real native provider path, so it won’t magically become “full OpenClaw assistant”

So yes, you could build a website-automation proxy, but it would be:

  • a custom unofficial bridge
  • fragile
  • hard to maintain
  • not something I’d suggest as the main assistant backend
#

Practical recommendation

If you want OpenClaw to work well, use one of these:

  1. native provider
  2. Gemini CLI
  3. Gemini CLI via ACP

If you want “free by automating gemini.google.com in a browser and pretending it’s Ollama/OpenAI”, that’s firmly in hacky unsupported proxy territory.

So my honest answer is: don’t build your main setup around that.
It’ll be more pain than it’s worth.

Docs:

willow ferry
twin merlinBOT
#

The simplest way to explain it:

Native provider = proper protocol

OpenClaw talks to the model through an API that is meant for apps.

That usually gives OpenClaw:

  • system prompt support
  • structured tool calling
  • machine-readable outputs
  • token/usage info
  • clearer errors/retries
  • stable request/response format

Browser-automation proxy = pretending to be a human in the website

Your script is basically:

#
  1. open website
  2. paste message
  3. wait
  4. scrape text off the page

That means OpenClaw loses a lot of the clean app-to-app contract.


“poor structured output” means

OpenClaw likes it when the model can return something predictable, like:

  • proper tool call objects
  • parseable JSON
  • stable assistant messages
  • usage metadata
#

A website UI usually just gives you:

  • whatever text appeared on screen
  • maybe streaming chunks
  • maybe extra UI junk
  • maybe formatting that changes tomorrow

So parsing becomes flaky.


“poor tool reliability” means

With a native provider, OpenClaw can often say:

here are the available tools, call one with exact arguments

#

With a browser-script proxy, you often only get plain text like:

“I want to use the browser tool to search for X”

Now your wrapper has to guess:

  • was that really a tool call?
  • what are the arguments?
  • did the model finish?
  • did the page truncate the output?
  • did the website change the HTML?

That’s why tool use becomes unreliable.


Why it still won’t become “full OpenClaw assistant”

#

Because the problem is not just “getting messages in and out”.

The native provider path lets OpenClaw inject things cleanly, like:

  • assistant identity
  • system prompt
  • tool schemas
  • bootstrap context
  • retries/continuations in a structured way

A browser website proxy mostly gives you a chat box.

So even if it works, it’s still:

OpenClaw → hacky browser wrapper → website chat UI → model

instead of:

#

OpenClaw → real provider API → model

That middle hacky layer is the whole problem.


Tiny analogy

  • native provider = calling a restaurant and placing an order with a proper menu + order number
  • browser automation = sending someone to stand in line, read the menu board, shout your order, then text you back what they think happened

Both can work. One is way messier 😅

willow ferry
#

@twin merlin what about modal glm 5.1 free or modelrelay

twin merlinBOT
#

Short version:

  • If it’s a real API/OpenAI-compatible provider path, it’s closer to the good/native side than Gemini CLI.
  • If it’s another website/login/chatbox wrapper, it’s back in the hacky/brittle side.

So for your examples:

  • GLM through a proper provider/API path → generally better than Gemini CLI for OpenClaw-assistant feel
  • ModelRelaycan be fine if it gives OpenClaw a real compatible API contract
    (not just browser automation or weird scraping)

What matters most is not the brand name, it’s:

  1. does OpenClaw talk to it through a proper API?
  2. does tool calling / structured output work well?
  3. does it behave like a normal provider, not a UI wrapper?