feat(providers): operator-driven provider selection, switching, and memory migration - #2756
Merged
Conversation
…emory migration Make the agent provider a first-class, operator-chosen property instead of a Claude-only assumption. Trunk gains the seams; the actual non-default payloads (Codex first) install from the `providers` branch. Setup - A provider registry feeds a hard-wired setup picker (Claude | Codex). Picking a non-default provider installs its payload (setup/add-codex.sh, channel-style), runs a vault-only auth walkthrough (--step provider-auth), and records the pick on the first agent before its first spawn. - Picking Claude changes nothing — default installs are byte-for-byte unaffected. Provider as a DB property - Provider lives on container_configs.provider (materialized to container.json, read by resolveProviderName). Creation stays provider-agnostic; the picked provider is applied via the picked-provider seam. The deprecated agent_groups.agent_provider path is not used. Switching + memory - Switch a live group with `ncl groups config update --provider` + restart. - Memory never migrates at runtime — each provider keeps its own store. The /migrate-memory skill carries a group's memory across a switch in either direction (flat CLAUDE.local.md <-> memory/ scaffold). group-init seeds an imported-agent-memory note for non-default providers; the runner's memory definition reads it first turn. See docs/provider-migration.md. No install-wide default, no runtime provider guard — switching is operator-by- convention, consistent with the no-install-gating posture. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
gavrielc
reviewed
Jun 14, 2026
Comment on lines
+25
to
+33
| ## Imported agent memory | ||
|
|
||
| If `memory/memories/imported-agent-memory.md` exists, it holds this group's seed | ||
| instructions and/or memory carried over from a previous agent provider — placed | ||
| there by the operator's tooling (group creation, or the operator running | ||
| `/migrate-memory`). Read it on your first turn and treat its contents as binding: | ||
| it may define who you are and how to behave. Integrate its facts into your memory | ||
| files as you work. Files it references live in the workspace root and remain | ||
| readable; never modify files that belong to another provider's memory system. |
Collaborator
There was a problem hiding this comment.
I think we can add this info as part of the migration when relevant, instead of having it always there, no?
Collaborator
Author
There was a problem hiding this comment.
Yes thats possible, looking into it
Collaborator
Author
There was a problem hiding this comment.
Moved it into /migrate-memory (the step that writes the imported file + its index pointer) and dropped the always-on block from definition.md.
It now shows up only when an import actually happened. 6d521a9
The "read imported-agent-memory.md, treat it as binding" doctrine sat in the memory definition that every group loads, but it only matters when an import actually happened. Move it into the /migrate-memory skill — the step that writes the imported file and its index pointer (which the agent inlines into its prompt each turn) — and drop the always-on block from definition.md. Addresses review feedback on #2756. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
gavrielc
reviewed
Jun 14, 2026
This was referenced Jun 15, 2026
technicalpickles
pushed a commit
to technicalpickles/nanoclaw
that referenced
this pull request
Jul 12, 2026
The "read imported-agent-memory.md, treat it as binding" doctrine sat in the memory definition that every group loads, but it only matters when an import actually happened. Move it into the /migrate-memory skill — the step that writes the imported file and its index pointer (which the agent inlines into its prompt each turn) — and drop the always-on block from definition.md. Addresses review feedback on nanocoai#2756. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
technicalpickles
pushed a commit
to technicalpickles/nanoclaw
that referenced
this pull request
Jul 12, 2026
feat(providers): operator-driven provider selection, switching, and memory migration
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What this does
Turns the agent provider into an explicit, operator-chosen property. Trunk ships the seams — a provider registry, a setup picker, an installer, a vault auth walkthrough, and the memory-migration skill — while the non-default provider payloads (Codex first) install from the
providersbranch.Picking Claude changes nothing. Default installs are unaffected; everything here is additive.
Surface area
Setup
setup/providers/registry.ts(+ tests) — provider registry behind the pickersetup/provider-auth.ts,setup/lib/picked-provider.ts— vault auth walkthrough + the seam that carries the pick to agent creationsetup/add-codex.sh— channel-style installer that copies the Codex payload from theprovidersbranch, wires the barrels, and pins the Codex CLIsetup/auto.ts,setup/cli-agent.ts,setup/environment.ts,setup/register.ts— picker wiringProvider as a DB property
scripts/init-first-agent.ts,scripts/init-cli-agent.ts,src/modules/agent-to-agent/create-agent.ts— setcontainer_configs.providerat creation; creation itself stays provider-agnosticsrc/container-restart.ts,src/container-runner.ts,src/group-init.ts— restart + per-group scaffold honor the chosen providerSwitching + memory
.claude/skills/migrate-memory/SKILL.md— bidirectional memory carry across a provider switchcontainer/agent-runner/src/memory-templates/definition.md— read the imported-memory seed first turndocs/provider-migration.md— what carries over, how to roll backCompatibility
Additive. Existing Claude installs need no action. Provider choice is per-group (
ncl groups config update --provider+ restart), never install-wide, and memory is carried explicitly via/migrate-memory— never silently at runtime. Full notes inCHANGELOG.mdanddocs/provider-migration.md.Testing
pnpm test(host) + container suite green. Validated end-to-end on a clean VM: setup → pick Codex → install → build → a live Codex agent answering, vault-only auth, zero credential in-container.