Skip to content

fix(agents): bootstrap non-main models.json on skip to prevent Unknown model after agents.create#58373

Open
xiangri678 wants to merge 4 commits into
openclaw:mainfrom
xiangri678:fix/non-main-models-bootstrap
Open

fix(agents): bootstrap non-main models.json on skip to prevent Unknown model after agents.create#58373
xiangri678 wants to merge 4 commits into
openclaw:mainfrom
xiangri678:fix/non-main-models-bootstrap

Conversation

@xiangri678

@xiangri678 xiangri678 commented Mar 31, 2026

Copy link
Copy Markdown

Summary

  • Problem: agents.create creates a valid non-main agent (config/workspace), but does not create models.json by design. Under a narrow startup path, this can later fail with Unknown model.
  • Why it matters: newly created non-main agents can hit a hard runtime failure even when auth fallback/inheritance is available.
  • What changed: when models planning returns action: "skip", ensureOpenClawModelsJson now performs a one-time bootstrap from main agent models.json only if target is non-main and target models.json is missing.
  • What did NOT change (scope boundary): no continuous global-to-agent sync, no overwrite of existing per-agent models.json, no change to agents.create behavior itself.

Change Type (select all)

  • Bug fix
  • Feature
  • Refactor required for the fix
  • Docs
  • Security hardening
  • Chore/infra

Scope (select all touched areas)

  • Gateway / orchestration
  • Auth / tokens
  • Skills / tool execution
  • Memory / storage
  • Integrations
  • API / contracts
  • UI / DX
  • CI/CD / infra

Linked Issue/PR

Root Cause / Regression History (if applicable)

  • Root cause: planOpenClawModelsJson returns skip when providers resolve empty; ensureOpenClawModelsJson previously returned early (wrote: false) without creating/bootstrapping missing non-main models.json.
  • Missing detection / guardrail: no fallback path for missing non-main models.json in the skip branch.
  • Prior context (git blame, prior PR, issue, or refactor if known): auth store already supports main→non-main inheritance/fallback, but model registry bootstrap was asymmetric.
  • Why this regressed now: non-main startup can rely on inherited auth while lacking model catalog file.
  • If unknown, what was ruled out: not a request for full global sync; this is a narrow runtime-failure prevention path.

Regression Test Plan (if applicable)

  • Coverage level that should have caught this:
  • Unit test
  • Seam / integration test
  • End-to-end test
  • Existing coverage already sufficient
  • Target test or file: src/agents/models-config.skips-writing-models-json-no-env-token.test.ts
  • Scenario the test should lock in: non-main + missing target models.json + plan.action === "skip" + existing non-empty main models.json => target file is created from main.
  • Why this is the smallest reliable guardrail: it exercises the exact skip branch and validates one-time bootstrap behavior.
  • Existing test that already covers this (if any): none specific to this branch.
  • If no new test is added, why not: N/A (new test added).

User-visible / Behavior Changes

  • After agents.create, a newly created non-main agent that enters the empty-provider skip path no longer proceeds with a missing model catalog and Unknown model hard failure.

Diagram (if applicable)

Before:
agents.create -> non-main agent exists (no models.json by design)
-> startup path (providers empty -> skip)
-> no models.json
-> runtime Unknown model

After:
agents.create -> non-main agent exists (no models.json by design)
-> startup path (providers empty -> skip)
-> one-time bootstrap from main models.json (if missing)
-> runtime proceeds without missing-catalog hard failure

Security Impact (required)

  • New permissions/capabilities? No
  • Secrets/tokens handling changed? No
  • New/changed network calls? No
  • Command/tool execution surface changed? No
  • Data access scope changed? No
  • If any Yes, explain risk + mitigation: N/A

Repro + Verification

Environment

  • OS: macOS 26 / Windows 11 (repro path observed in Windows packaging workflow)
  • Runtime/container: Node 22+
  • Model/provider: any provider/model requiring model registry lookup
  • Integration/channel (if any): N/A
  • Relevant config (redacted): standard multi-agent config with non-main agent created via agents.create
  • Reproduced on: v2026.3.28 and main (HEAD as of 2026-03-31)

Steps

  1. Call agents.create to create a new non-main agent.
  2. Confirm new agent dir exists and models.json is initially absent (current expected behavior of create path).
  3. Ensure provider planning resolves empty for that non-main startup path (plan.action === "skip").
  4. Start/spawn session for that non-main agent.

Expected

  • Startup should not continue into runtime with missing non-main model catalog in this narrow path.

Actual

  • Before fix: non-main models.json remains missing and runtime can fail with Unknown model: <provider>/<model>.

Evidence

  • Failing test/log before + passing after
  • Trace/log snippets
  • Screenshot/recording
  • Perf numbers (if relevant)
  • Evidence notes:
  • agents.create success path does not create models.json (by design).
  • Scoped test added for skip branch bootstrap path.
  • Local verification run:
  • pnpm test -- src/agents/models-config.skips-writing-models-json-no-env-token.test.ts -t "inherits models.json from main agent for new secondary agents when plan skips"
  • pnpm build
  • pnpm check

Real behavior proof

  • Behavior or issue addressed: A non-main agent created through agents.create can have a valid agent directory but no models.json; when provider planning returns skip, chat/session startup can later fail with Unknown model even though auth fallback is available.
  • Real environment tested: Windows 11 packaged OpenClaw Gateway workflow plus a local OpenClaw checkout with Node 22. Local paths, agent names, and provider configuration are redacted.
  • Exact steps or command run after this patch: Created the non-main HR agent through agents.create, confirmed the target agent models.json was absent before startup, started the non-main chat/session path that enters ensureOpenClawModelsJson, and checked the target agent directory after startup.
  • Evidence after fix: Redacted terminal/log excerpt from the real verification:
agents.create: created non-main agent id=<redacted-hr-agent>
before startup: <state-dir>/agents/<redacted-hr-agent>/agent/models.json missing
ensureOpenClawModelsJson: plan.action=skip
ensureOpenClawModelsJson: inherited models.json from default/main agent
after startup: <state-dir>/agents/<redacted-hr-agent>/agent/models.json exists
chat startup: completed without Unknown model
  • Observed result after fix: The non-main agent no longer continues into runtime with a missing model catalog in this narrow skip path; models.json is bootstrapped once from the main/default agent and existing per-agent files remain untouched.
  • What was not tested: Full provider/channel matrix e2e and continuous global-to-agent sync, which is intentionally outside this PR scope.

Human Verification (required)

  • Verified scenarios:
  • non-main + missing target models + skip branch + existing main models => target created and copied.
  • existing per-agent target models remains untouched.
  • main agent path does not self-copy.
  • Edge cases checked:
  • missing main models file => no bootstrap.
  • empty main models file => no bootstrap.
  • What you did not verify:
  • full provider/channel matrix e2e.

Review Conversations

  • I replied to or resolved every bot review conversation I addressed in this PR.
  • I left unresolved only the conversations that still need reviewer or maintainer judgment.

Compatibility / Migration

  • Backward compatible? Yes
  • Config/env changes? No
  • Migration needed? No
  • If yes, exact upgrade steps: N/A

Risks and Mitigations

  • Risk: accidentally overwriting per-agent custom models.json.
  • Mitigation: bootstrap runs only when target file is missing; existing file is never overwritten.

@openclaw-barnacle openclaw-barnacle Bot added agents Agent runtime and tooling size: S labels Mar 31, 2026
@greptile-apps

greptile-apps Bot commented Mar 31, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes a narrow but real startup failure: when agents.create produces a non-main agent (intentionally without models.json) and the provider planning path later resolves to action: "skip", the model catalog file was never created, leading to an Unknown model runtime error. The fix introduces inheritModelsJsonFromMainAgent, which runs only when the skip branch is reached, the target is a non-main agent, and the target models.json is absent — making the write a one-time bootstrap from the main agent's catalog. It correctly skips self-copy, skips if the target file already exists, and skips if the main source is empty.

Key changes:

  • inheritModelsJsonFromMainAgent in src/agents/models-config.ts: new helper that bootstraps a secondary agent's models.json from the main agent's copy under the described narrow conditions.
  • ensureOpenClawModelsJson: the skip branch now delegates to the helper instead of returning early with wrote: false.
  • New test in models-config.skips-writing-models-json-no-env-token.test.ts directly exercises the skip-branch bootstrap path (mock planner → skip, seed main models.json, assert secondary file created and matches source).

Confidence Score: 5/5

Safe to merge; only a P2 hardening suggestion remains (use the existing atomic write helper instead of a direct fs.writeFile).

The fix is logically correct and well-scoped. All guard conditions (identity check, existing-file check, empty-source check) are sound, and the write lock ensures serialization. The sole P2 concern — using fs.writeFile directly instead of writeModelsFileAtomic — only risks corruption on a process crash mid-write, which is a narrow edge case and does not block merge.

src/agents/models-config.ts line 121-122: consider switching to writeModelsFileAtomic for crash-safety consistency.

Important Files Changed

Filename Overview
src/agents/models-config.ts Adds inheritModelsJsonFromMainAgent helper and wires it into the skip branch of ensureOpenClawModelsJson. Logic and guard conditions are correct; the only concern is a direct fs.writeFile instead of the existing atomic write helper, leaving a narrow crash-corruption window.
src/agents/models-config.skips-writing-models-json-no-env-token.test.ts New test correctly exercises the skip-branch bootstrap scenario: mocks the planner to return skip, seeds a main agent models.json, calls ensureOpenClawModelsJson against a secondary dir, and asserts both wrote: true and content equality. Coverage is targeted and sufficient for the stated scope.
Prompt To Fix All With AI
This is a comment left during a code review.
Path: src/agents/models-config.ts
Line: 121-122

Comment:
**Non-atomic write inconsistent with existing helper**

`inheritModelsJsonFromMainAgent` writes the bootstrapped file with `fs.writeFile` directly, while every other write path in this module goes through `writeModelsFileAtomic` (write-to-temp + `rename`). If the process is killed between `mkdir` and `writeFile` completing, the target file could be left partially written. On the *next* startup, `fs.access` at line 103 will succeed (the corrupt file exists), causing `inheritModelsJsonFromMainAgent` to return `false` early — so the bootstrap won't re-run and the corrupt file persists, which is exactly the "Unknown model" failure mode this PR is fixing.

`writeModelsFileAtomic` already exists in this file and the directory is created just before, so using it here is straightforward:

```suggestion
  await fs.mkdir(params.agentDir, { recursive: true, mode: 0o700 });
  await writeModelsFileAtomic(params.targetPath, sourceRaw);
```

How can I resolve this? If you propose a fix, please make it concise.

Reviews (1): Last reviewed commit: "fix(agents): bootstrap non-main models.j..." | Re-trigger Greptile

Re-review progress:

Comment thread src/agents/models-config.ts Outdated
Comment on lines +121 to +122
await fs.mkdir(params.agentDir, { recursive: true, mode: 0o700 });
await fs.writeFile(params.targetPath, sourceRaw, { mode: 0o600 });

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Non-atomic write inconsistent with existing helper

inheritModelsJsonFromMainAgent writes the bootstrapped file with fs.writeFile directly, while every other write path in this module goes through writeModelsFileAtomic (write-to-temp + rename). If the process is killed between mkdir and writeFile completing, the target file could be left partially written. On the next startup, fs.access at line 103 will succeed (the corrupt file exists), causing inheritModelsJsonFromMainAgent to return false early — so the bootstrap won't re-run and the corrupt file persists, which is exactly the "Unknown model" failure mode this PR is fixing.

writeModelsFileAtomic already exists in this file and the directory is created just before, so using it here is straightforward:

Suggested change
await fs.mkdir(params.agentDir, { recursive: true, mode: 0o700 });
await fs.writeFile(params.targetPath, sourceRaw, { mode: 0o600 });
await fs.mkdir(params.agentDir, { recursive: true, mode: 0o700 });
await writeModelsFileAtomic(params.targetPath, sourceRaw);
Prompt To Fix With AI
This is a comment left during a code review.
Path: src/agents/models-config.ts
Line: 121-122

Comment:
**Non-atomic write inconsistent with existing helper**

`inheritModelsJsonFromMainAgent` writes the bootstrapped file with `fs.writeFile` directly, while every other write path in this module goes through `writeModelsFileAtomic` (write-to-temp + `rename`). If the process is killed between `mkdir` and `writeFile` completing, the target file could be left partially written. On the *next* startup, `fs.access` at line 103 will succeed (the corrupt file exists), causing `inheritModelsJsonFromMainAgent` to return `false` early — so the bootstrap won't re-run and the corrupt file persists, which is exactly the "Unknown model" failure mode this PR is fixing.

`writeModelsFileAtomic` already exists in this file and the directory is created just before, so using it here is straightforward:

```suggestion
  await fs.mkdir(params.agentDir, { recursive: true, mode: 0o700 });
  await writeModelsFileAtomic(params.targetPath, sourceRaw);
```

How can I resolve this? If you propose a fix, please make it concise.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 1b0d95b761

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/models-config.ts Outdated
Comment on lines +208 to +210
if (plan.action === "skip") {
return { fingerprint, result: { agentDir, wrote: false } };
const inherited = await inheritModelsJsonFromMainAgent({ agentDir, targetPath });
return { fingerprint, result: { agentDir, wrote: inherited } };

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Badge Recompute skip-cache when main models file changes

This skip branch now depends on inheritModelsJsonFromMainAgent, but the cached fingerprint it returns was computed before this check and only tracks the target agent files. If a secondary agent calls this once before main models.json exists, inherited is cached as false; later calls in the same process can keep hitting the cache path and never retry inheritance even after main models.json is created, so the intended bootstrap fix can remain inactive until restart.

Useful? React with 👍 / 👎.

Comment thread src/agents/models-config.ts Outdated
}

await fs.mkdir(params.agentDir, { recursive: true, mode: 0o700 });
await fs.writeFile(params.targetPath, sourceRaw, { mode: 0o600 });

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Badge Preserve atomic writes when bootstrapping inherited models

The inheritance path writes directly with fs.writeFile, unlike the normal generation path which uses writeModelsFileAtomic. In the plan.action === "skip" + missing-target case, an interrupted write (process crash, I/O error) can leave a partially written models.json, which then breaks JSON parsing/model discovery for that agent; using the existing atomic writer here would avoid introducing this corruption path.

Useful? React with 👍 / 👎.

@xiangri678
xiangri678 force-pushed the fix/non-main-models-bootstrap branch 3 times, most recently from 43e378b to 3332a97 Compare March 31, 2026 15:25
@xiangri678

Copy link
Copy Markdown
Author

Thanks for the reviews. I’ve addressed the feedback and rebased this branch onto the latest main. Could you please take another look?

For the current failing checks: they appear to be outside the scope of this PR’s changes (this PR only touches src/agents/models-config*). Would you mind helping confirm whether these are baseline/CI issues and re-running the failed jobs if appropriate?

@xiangri678
xiangri678 force-pushed the fix/non-main-models-bootstrap branch from 3332a97 to 493bdbb Compare April 1, 2026 13:30

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 493bdbbedb

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/agents/models-config.ts Outdated
Comment on lines +109 to +113
try {
await fs.access(params.targetPath);
// Keep existing per-agent models.json untouched.
return false;
} catch {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P2 Badge Prevent bootstrap from overwriting concurrently created models.json

The non-main bootstrap path has a TOCTOU race: it checks fs.access(targetPath) and later writes via atomic rename, but there is no cross-process lock, so another process can create models.json in between and this rename will overwrite it. In multi-process startup (for example, two commands initializing the same agent), this can clobber a freshly generated or user-customized per-agent catalog despite the intent to keep existing files untouched.

Useful? React with 👍 / 👎.

@xiangri678
xiangri678 force-pushed the fix/non-main-models-bootstrap branch from 0a3fbb4 to 7b43e3c Compare April 6, 2026 07:29
@openclaw-barnacle

Copy link
Copy Markdown

This pull request has been automatically marked as stale due to inactivity.
Please add updates or it will be closed.

@openclaw-barnacle openclaw-barnacle Bot added the stale Marked as stale due to inactivity label Apr 30, 2026
@clawsweeper

clawsweeper Bot commented May 1, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs changes before merge. Reviewed July 3, 2026, 9:02 PM ET / July 4, 2026, 01:02 UTC.

Summary
The PR adds a sanitized one-time main-agent models.json bootstrap for non-main skip paths, relaxes custom model validation to allow stored auth, adds regression tests, and restores required deadcode allowlist entries.

PR surface: Source +168, Tests +350, Other +7. Total +525 across 5 files.

Reproducibility: yes. Source inspection on current main shows the empty-provider skip branch returns without creating root models.json, and the registry treats a missing file as an empty catalog that can still lead to Unknown model.

Review metrics: 2 noteworthy metrics.

  • Required deadcode allowlist: 5 added, 2 no longer tracked on current main. Required allowlist entries are exact; stale entries fail the deadcode check instead of being harmless comments.
  • Provider auth behavior: 1 validation rule changed, 1 sanitized bootstrap path added. Both affect model availability and credential resolution for existing non-main agent setups.

Stored data model
Persistent data-model change detected: persistent cache schema: scripts/deadcode-unused-files.allowlist.mjs, serialized state: src/agents/models-config.ts, serialized state: src/agents/sessions/model-registry.test.ts, unknown-data-model-change: src/agents/sessions/model-registry.test.ts. Confirm migration or upgrade compatibility proof before merge.

Root-cause cluster
Relationship: fixed_by_candidate
Canonical: #58289
Summary: This PR is a candidate fix for the canonical missing non-main root models.json skip-path issue; adjacent reports cover broader sync or catalog-present cases.

Members:

Proposal only: this assessment does not dispatch repair, suppress jobs, mutate sibling items, close, or merge anything.

Merge readiness
Overall: 🦐 gold shrimp
Proof: 🦞 diamond lobster
Patch quality: 🦐 gold shrimp
Result: needs maintainer review before merge.

Overall follows the weaker of proof and patch quality, so missing proof can cap an otherwise strong patch.

Rank-up moves:

  • [P2] Remove or regenerate the required deadcode allowlist hunk against current main.
  • Get maintainer acceptance on persisted sanitized bootstrap versus read-through inheritance or early actionable failure.

Risk before merge

  • [P1] The PR adds required deadcode allowlist entries for two agent cache files that no longer exist on current main, so deadcode:unused-files will report stale required entries until the hunk is regenerated or removed.
  • [P1] The runtime change intentionally persists a sanitized main-agent model catalog into a non-main agent and changes custom model availability to depend on stored/env auth, which is compatibility-sensitive provider/auth behavior that maintainers should explicitly accept.
  • [P1] The adjacent fix(agents): inherit default agent model catalog for secondary agents #90903 covers a catalog-present-but-model-less secondary-agent case, not this missing root models.json case, so it is related context rather than a replacement.

Maintainer options:

  1. Clean the stale deadcode allowlist first (recommended)
    Remove or freshly regenerate the required deadcode allowlist hunk so it contains only entries that a current-main Knip scan actually reports.
  2. Accept the provider/auth compatibility behavior
    A maintainer can decide that persisted sanitized bootstrap plus stored-auth validation is the intended upgrade behavior for non-main agents.
  3. Pause if read-through inheritance is preferred
    If maintainers prefer runtime read-through or an early actionable failure over persisted bootstrap, this PR should pause or be replaced by the chosen owner-boundary fix.
Copy recommended automerge instruction
@clawsweeper automerge

Special instructions:
Remove stale required `KNIP_UNUSED_FILE_ALLOWLIST` additions for untracked `src/agents/cache/agent-cache-store.sqlite.ts` and `src/agents/cache/agent-cache-store.ts`; keep only entries still required by a fresh deadcode unused-file scan, and do not change runtime model/auth behavior.

Next step before merge

  • [P2] A narrow repair can remove or regenerate the stale required deadcode allowlist entries; provider/auth compatibility still needs maintainer acceptance after that repair.

Security
Cleared: No concrete security or supply-chain issue was found; the PR strips inline credential/request fields before inheritance, though provider/auth behavior remains a merge-risk decision.

Review findings

  • [P2] Remove stale required deadcode allowlist entries — scripts/deadcode-unused-files.allowlist.mjs:5-9
Review details

Best possible solution:

Remove the stale allowlist entries, refresh the branch against current main, and land a maintainer-approved missing-file fix with regression coverage for sanitized inheritance and stored-auth request resolution.

Do we have a high-confidence way to reproduce the issue?

Yes. Source inspection on current main shows the empty-provider skip branch returns without creating root models.json, and the registry treats a missing file as an empty catalog that can still lead to Unknown model.

Is this the best way to solve the issue?

Unclear. The persisted sanitized bootstrap is a focused mitigation for the missing-file case, but maintainers still need to confirm that this provider/auth compatibility boundary is preferable to read-through inheritance or an early actionable failure.

Full review comments:

  • [P2] Remove stale required deadcode allowlist entries — scripts/deadcode-unused-files.allowlist.mjs:5-9
    This hunk adds src/agents/cache/agent-cache-store.sqlite.ts and src/agents/cache/agent-cache-store.ts to the required Knip unused-file allowlist, but current main no longer tracks either path. The deadcode checker treats required allowlist entries that are absent from the scan as stale and fails, so this PR needs to remove or freshly regenerate the allowlist before merge.
    Confidence: 0.9

Overall correctness: patch is incorrect
Overall confidence: 0.84

AGENTS.md: found and applied where relevant.

Codex review notes: model internal, reasoning high; reviewed against f59310a555d7.

Label changes

Label justifications:

  • P1: The PR targets a linked workflow-blocking non-main agent startup failure where sessions can still fail with Unknown model on current main.
  • merge-risk: 🚨 automation: The PR changes the required deadcode allowlist and currently adds stale entries that can keep repository automation red.
  • merge-risk: 🚨 compatibility: Persisting sanitized main-agent model catalogs into non-main agent state changes upgrade behavior for existing per-agent model configuration.
  • merge-risk: 🚨 auth-provider: The PR changes model availability and request auth resolution by allowing custom models without inline apiKey when AuthStorage has provider auth.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🦞 diamond lobster and patch quality is 🦐 gold shrimp.
  • status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Sufficient (logs): The PR body includes after-fix real-environment terminal/log proof showing a non-main agent bootstrapping models.json and starting without the previous Unknown model failure.
  • proof: sufficient: Contributor real behavior proof is sufficient. The PR body includes after-fix real-environment terminal/log proof showing a non-main agent bootstrapping models.json and starting without the previous Unknown model failure.
Evidence reviewed

PR surface:

Source +168, Tests +350, Other +7. Total +525 across 5 files.

View PR surface stats
Area Files Added Removed Net
Source 2 170 2 +168
Tests 2 351 1 +350
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 1 7 0 +7
Total 5 528 3 +525

Acceptance criteria:

  • [P1] node scripts/check-deadcode-unused-files.mjs.
  • [P1] node scripts/run-vitest.mjs src/agents/models-config.skips-writing-models-json-no-env-token.test.ts src/agents/sessions/model-registry.test.ts.
  • [P1] git diff --check.

What I checked:

  • Root and scoped policy read: Root AGENTS.md, src/agents/AGENTS.md, and scripts/AGENTS.md were read; their review guidance treats provider routing, auth/session state, startup fallback behavior, and script allowlists as compatibility or automation-sensitive review surfaces. (AGENTS.md:1, f59310a555d7)
  • Current main still skips root models.json creation: On current main, plan.action === "skip" writes generated plugin catalog sidecars and returns without creating or bootstrapping the root agent models.json. (src/agents/models-config.ts:428, f59310a555d7)
  • Missing models.json still produces an empty registry: The current registry returns an empty custom-model result when the models.json path does not exist, and current validation still requires an inline apiKey unless the auth mode is aws-sdk or oauth. (src/agents/sessions/model-registry.ts:402, f59310a555d7)
  • PR diff targets the right runtime path: The PR wires a sanitized inheritModelsJsonFromMainAgent helper into the skip branch and adds tests for inheritance, retry after main appears, and concurrent target creation. (src/agents/models-config.ts, c678a20f38d1)
  • Required deadcode allowlist hunk is stale: Current main's required KNIP_UNUSED_FILE_ALLOWLIST is empty, the check fails on stale required entries, and two paths added by this PR are no longer tracked on current main. (scripts/deadcode-unused-files.allowlist.mjs:4, f59310a555d7)
  • Deadcode check treats stale required entries as failure: compareUnusedFilesToAllowlist reports allowed files absent from actual Knip output as stale, and checkUnusedFiles only passes when the stale list is empty. (scripts/check-deadcode-unused-files.mjs:92, f59310a555d7)

Likely related people:

  • steipete: GitHub file history shows repeated recent work on agent model/auth/runtime surfaces, including the large agent-runtime internalization and auth-profile SQLite refactor that shaped the current ownership boundary. (role: major area refactor owner; confidence: high; commits: bb46b79d3c14, e16ac0433092, 51b5f75b92f7; files: src/agents/models-config.ts, src/agents/sessions/model-registry.ts, src/agents/agent-auth-discovery.ts)
  • shakkernerd: Recent current-main history on src/agents/models-config.ts includes model catalog cache-key work directly adjacent to the fingerprint/cache behavior this PR touches. (role: recent model-catalog contributor; confidence: medium; commits: 55156a1241c1; files: src/agents/models-config.ts)
  • tangtaizong666: Recent current-main history on src/agents/sessions/model-registry.ts includes plugin catalog error isolation, which is adjacent to registry loading and catalog validation behavior changed by this PR. (role: recent model-registry contributor; confidence: medium; commits: c9f0bfd4764d; files: src/agents/sessions/model-registry.ts)
  • vincentkoc: Recent history on scripts/deadcode-unused-files.allowlist.mjs includes stale allowlist cleanup and removal of unused agent cache scaffolding, which is directly relevant to the PR's stale allowlist hunk. (role: recent script/deadcode owner; confidence: high; commits: 0e61c1112f37, a9ef3adeb3c8, ad304e790d0c; files: scripts/deadcode-unused-files.allowlist.mjs, src/agents/cache/agent-cache-store.ts)
What the crustacean ranks mean
  • 🦀 challenger crab: rare, exceptional readiness with strong proof, clean implementation, and convincing validation.
  • 🦞 diamond lobster: very strong readiness with only minor maintainer review expected.
  • 🐚 platinum hermit: good normal PR, likely mergeable with ordinary maintainer review.
  • 🦐 gold shrimp: useful signal, but proof or patch confidence is still limited.
  • 🦪 silver shellfish: thin signal; proof, validation, or implementation needs work.
  • 🧂 unranked krab: not merge-ready because proof is missing/unusable or there are serious correctness or safety concerns.
  • 🌊 off-meta tidepool: rating does not apply to this item.

Shiny media proof means a screenshot, video, or linked artifact directly shows the changed behavior. Runtime, network, CSP, and security claims still need visible diagnostics.

How this review workflow works
  • ClawSweeper keeps one durable marker-backed review comment per issue or PR.
  • Re-runs edit this comment so the latest verdict, findings, and automation markers stay together instead of adding duplicate bot comments.
  • A fresh review can be triggered by eligible @clawsweeper re-review comments, exact-item GitHub events, scheduled/background review runs, or manual workflow dispatch.
  • PR/issue authors and users with repository write access can comment @clawsweeper re-review or @clawsweeper re-run on an open PR or issue to request a fresh review only.
  • Maintainers can also comment @clawsweeper review to request a fresh review only.
  • Fresh-review commands do not start repair, autofix, rebase, CI repair, or automerge.
  • Maintainer-only repair and merge flows require explicit commands such as @clawsweeper autofix, @clawsweeper automerge, @clawsweeper fix ci, or @clawsweeper address review.
  • Maintainers can comment @clawsweeper explain to ask for more context, or @clawsweeper stop to stop active automation.

@openclaw-barnacle openclaw-barnacle Bot removed the stale Marked as stale due to inactivity label May 1, 2026
@xiangri678
xiangri678 force-pushed the fix/non-main-models-bootstrap branch from 7b43e3c to b191131 Compare May 9, 2026 12:32
@openclaw-barnacle openclaw-barnacle Bot added the triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. label May 9, 2026
@xiangri678
xiangri678 force-pushed the fix/non-main-models-bootstrap branch 2 times, most recently from 250e3b0 to fc46b1b Compare May 9, 2026 12:37
@openclaw-barnacle openclaw-barnacle Bot added proof: supplied External PR includes structured after-fix real behavior proof. and removed triage: needs-real-behavior-proof Candidate: external PR needs after-fix proof from a real setup. labels May 9, 2026
@xiangri678
xiangri678 force-pushed the fix/non-main-models-bootstrap branch from fc46b1b to bcdbda2 Compare May 9, 2026 12:38
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. and removed proof: sufficient ClawSweeper judged the real behavior proof convincing. labels May 9, 2026
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. merge-risk: 🚨 automation 🚨 May affect CI, automerge, proof capture, label sync, or maintainer automation. and removed rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. labels Jun 3, 2026
@openclaw-barnacle openclaw-barnacle Bot removed the proof: sufficient ClawSweeper judged the real behavior proof convincing. label Jun 3, 2026
@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. and removed rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. labels Jun 3, 2026
@xiangri678

Copy link
Copy Markdown
Author

What's different

  • Kept the inherited authHeader as-is — it's a transport policy flag, not a secret, so there's no reason to strip it.
  • Everything that actually carries credentials still gets stripped on inheritance: apiKey, provider/model headers, anything request/proxy/TLS related, and the key/token refs.
  • Added a runtime test that loads a sanitized inherited custom provider with no inline apiKey, relying on AuthStorage for the credentials — proving that path works.
  • Added another test covering stored auth + inherited authHeader: true, and checking we end up with the expected Authorization: Bearer ... header.
  • Rebased onto latest main.

How I checked it

node scripts/run-vitest.mjs src/agents/models-config.skips-writing-models-json-no-env-token.test.ts src/agents/sessions/model-registry.test.ts

node scripts/run-vitest.mjs src/agents/models-config.skips-writing-models-json-no-env-token.test.ts src/agents/sessions/model-registry.test.ts src/agents/model-auth.test.ts -t "injects Authorization Bearer header when authHeader is true"

pnpm deadcode:unused-files

pnpm exec oxfmt --check scripts/deadcode-unused-files.allowlist.mjs src/agents/models-config.ts src/agents/models-config.skips-writing-models-json-no-env-token.test.ts src/agents/sessions/model-registry.ts src/agents/sessions/model-registry.test.ts

pnpm exec oxlint scripts/deadcode-unused-files.allowlist.mjs src/agents/models-config.ts src/agents/models-config.skips-writing-models-json-no-env-token.test.ts src/agents/sessions/model-registry.ts src/agents/sessions/model-registry.test.ts

One note on the deadcode allowlist

I'm keeping the scripts/deadcode-unused-files.allowlist.mjs change in. The merge-commit CI flagged those five agent DB scaffold files as unexpected unused files, and with the allowlist restored the current head's check-dependencies job goes green again.

The 15 failed jobs did not reach the test shards and look like runner/setup infrastructure failures. Could you please rerun them or confirm the CI baseline?

@clawsweeper clawsweeper Bot added proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. P1 High-priority user-facing bug, regression, or broken workflow. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. and removed proof: sufficient ClawSweeper judged the real behavior proof convincing. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action. P2 Normal backlog priority with limited blast radius. rating: 🦪 silver shellfish Thin PR readiness signal; proof, validation, or implementation needs work. rating: 🧂 unranked krab Not merge-ready due to missing proof or serious correctness/safety concerns. labels Jun 16, 2026
@clawsweeper

clawsweeper Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper status: review started.

I am starting a fresh review of this pull request: fix(agents): bootstrap non-main models.json on skip to prevent Unknown model after agents.create This is item 1/1 in the current shard. Shard 0/1.

This placeholder means the worker is alive and reading the current context. I will edit this same comment with the actual review when the claws are done clicking.

Crustacean status: shell secured, claws on keyboard, evidence pebbles being sorted.

@clawsweeper

clawsweeper Bot commented Jul 22, 2026

Copy link
Copy Markdown
Contributor

ClawSweeper status: review started.

I am starting a fresh review of this pull request: fix(agents): bootstrap non-main models.json on skip to prevent Unknown model after agents.create This is item 1/1 in the current shard. Shard 0/1.

This placeholder means the worker is alive and reading the current context. I will edit this same comment with the actual review when the claws are done clicking.

Crustacean status: shell secured, claws on keyboard, evidence pebbles being sorted.

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

Labels

agents Agent runtime and tooling merge-risk: 🚨 auth-provider 🚨 May break OAuth, tokens, provider routing, model choice, or credentials. merge-risk: 🚨 automation 🚨 May affect CI, automerge, proof capture, label sync, or maintainer automation. merge-risk: 🚨 compatibility 🚨 May break existing users, config, migrations, defaults, or upgrade paths. P1 High-priority user-facing bug, regression, or broken workflow. proof: sufficient ClawSweeper judged the real behavior proof convincing. proof: supplied External PR includes structured after-fix real behavior proof. rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. size: L status: ⏳ waiting on author ClawSweeper has contributor-facing work open and is waiting for author action.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Non-main agent may miss models.json and fail with "Unknown model" when provider plan is empty

1 participant