Skip to content

fix: repair model provider edge cases#89347

Merged
steipete merged 11 commits into
mainfrom
fix/model-provider-sweep
Jun 2, 2026
Merged

fix: repair model provider edge cases#89347
steipete merged 11 commits into
mainfrom
fix/model-provider-sweep

Conversation

@steipete

@steipete steipete commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Summary

  • repair additive SQLite state schema upgrades uncovered during live inference testing on an older state DB
  • honor OPENAI_BASE_URL / ANTHROPIC_BASE_URL defaults across OpenAI, Anthropic, and native PDF paths
  • honor OpenRouter Anthropic cache retention for long / none without forwarding OpenAI-incompatible cache params
  • make apply_patch provider-neutral while preserving explicit disable and allow-model gates
  • let provider-scoped configure cleanup show and prune stale configured model allowlist entries
  • expose GitHub Copilot bundled thinking policy so dashboard/offline policy lookups retain xhigh-capable profiles
  • detect same-size log rotation in incremental tooling readers so CI artifact-build log tailers reset on Linux inode reuse

Refs #74427, #74432, #79370, #88359, #88357, #45269, #80366, #80347, #79894.

Verification

  • node scripts/run-vitest.mjs src/state/openclaw-state-db.test.ts -- --reporter=verbose
  • node scripts/run-vitest.mjs extensions/openai/base-url.test.ts extensions/openai/openai-provider.test.ts src/agents/anthropic-transport-stream.test.ts src/agents/tools/pdf-native-providers.test.ts -- --reporter=verbose
  • node scripts/run-vitest.mjs src/agents/embedded-agent-runner/prompt-cache-retention.test.ts src/agents/embedded-agent-runner/extra-params.openrouter-cache-control.test.ts src/agents/embedded-agent-runner-extraparams-openrouter.test.ts src/agents/anthropic-payload-policy.test.ts src/llm/providers/stream-wrappers/proxy.test.ts src/llm/providers/stream-wrappers/anthropic-cache-control-payload.test.ts -- --reporter=verbose
  • node scripts/run-vitest.mjs src/agents/agent-tools.create-openclaw-coding-tools.test.ts src/agents/agent-tools-agent-config.test.ts -- --reporter=verbose
  • node scripts/run-vitest.mjs src/commands/model-picker.test.ts src/commands/configure.gateway-auth.prompt-auth-config.test.ts -- --reporter=verbose
  • node scripts/run-vitest.mjs extensions/github-copilot/provider-policy-api.test.ts extensions/github-copilot/index.test.ts extensions/github-copilot/models.test.ts -- --reporter=verbose -t "provider-policy-api|xhigh|reasoning efforts|static overrides"
  • node scripts/run-vitest.mjs test/scripts/codex-media-path-client.test.ts test/scripts/config-reload-log-scanner.test.ts -- --reporter=verbose
  • node scripts/run-oxlint.mjs scripts/e2e/lib/incremental-line-reader.mjs
  • pnpm check:changed via Blacksmith Testbox tbx_01kt3em5r9vd7g0bnykrff6jdk (provider blacksmith-testbox, exit 0)

Notes

@openclaw-barnacle openclaw-barnacle Bot added commands Command implementations agents Agent runtime and tooling extensions: openai extensions: github-copilot size: XL maintainer Maintainer-authored PR labels Jun 2, 2026
@clawsweeper

clawsweeper Bot commented Jun 2, 2026

Copy link
Copy Markdown
Contributor

Codex review: needs real behavior proof before merge. Reviewed June 2, 2026, 2:23 AM ET / 06:23 UTC.

Summary
The PR repairs model/provider edge cases across SQLite state upgrades, provider base URL defaults, OpenRouter cache retention, apply_patch gating, configure cleanup, and GitHub Copilot thinking policy lookup.

PR surface: Source +477, Tests +505. Total +982 across 27 files.

Reproducibility: yes. from source inspection: adding wake_mode as auto and then loading it through rowToCronJob produces a value outside the documented cron wake-mode union. I did not run tests because this is a read-only review.

Review metrics: 1 noteworthy metric.

  • Upgrade-sensitive surfaces: 1 SQLite migration path changed, 2 provider env defaults changed, 1 configure cleanup path changed. These surfaces affect existing installations during startup or setup, so upgrade behavior matters beyond unit tests.

Merge readiness
Overall: 🦐 gold shrimp
Proof: 🐚 platinum hermit
Patch quality: 🦐 gold shrimp
Result: ready for maintainer review.

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

Rank-up moves:

  • [P2] Fix the cron wake-mode migration default/normalization and add the malformed legacy row regression test.
  • [P2] Rerun the focused state DB test and changed-check lane after the repair.

Risk before merge

  • [P1] The SQLite state upgrade path can leave older cron rows with a non-canonical wake_mode, changing when main-session cron jobs wake after startup.
  • [P1] The provider base URL default changes are compatibility-sensitive because existing environments with OPENAI_BASE_URL or ANTHROPIC_BASE_URL now affect default provider routing.

Maintainer options:

  1. Normalize the cron wake-mode migration (recommended)
    Change the additive column default and any post-backfill cleanup so every persisted cron row has wake_mode set to now or next-heartbeat before the scheduler reads it.
  2. Split the state repair if needed
    If the cron migration shape needs owner review, pause or split the state DB commit and land the lower-risk provider fixes separately.
Copy recommended automerge instruction
@clawsweeper automerge

Special instructions:
Fix the state DB cron migration so added `wake_mode` columns never leave rows with `auto`: use a valid default such as `now`, normalize any invalid existing values after backfill, and add a focused regression test for a legacy cron row whose `job_json` cannot be backfilled.

Next step before merge

  • [P1] A narrow automated repair can normalize the cron wake-mode migration without deciding new product behavior; the maintainer label means a human should choose whether to promote that repair.

Security
Cleared: No concrete security or supply-chain issue was found in the patch; the main concern is upgrade/runtime compatibility.

Review findings

  • [P2] Use a valid cron wake-mode default — src/state/openclaw-state-db.ts:525
Review details

Best possible solution:

Keep the useful provider fixes, but normalize the cron migration so upgraded rows only persist now or next-heartbeat, with regression coverage for malformed legacy cron rows.

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

Yes from source inspection: adding wake_mode as auto and then loading it through rowToCronJob produces a value outside the documented cron wake-mode union. I did not run tests because this is a read-only review.

Is this the best way to solve the issue?

No; most fixes are on plausible owner surfaces, but the state migration is not safe until added cron columns are normalized to canonical values before runtime reads them.

Full review comments:

  • [P2] Use a valid cron wake-mode default — src/state/openclaw-state-db.ts:525
    For older cron_jobs tables, this added column can leave rows with wake_mode = 'auto' whenever job_json is malformed or fails the strict backfill path. CronWakeMode only allows now or next-heartbeat, and the timer path treats anything other than now as a deferred heartbeat event, so affected legacy jobs can silently stop waking immediately after the DB is opened. Default this column to now or force-normalize invalid values after the backfill.
    Confidence: 0.88

Overall correctness: patch is incorrect
Overall confidence: 0.86

AGENTS.md: found and applied where relevant.

Codex review notes: model gpt-5.5, reasoning high; reviewed against 5be282e459ee.

Label changes

Label changes:

  • add P2: The PR addresses real provider and state upgrade bugs, but the remaining blocker is scoped and repairable before merge.
  • add merge-risk: 🚨 compatibility: The PR changes SQLite upgrade behavior and can leave upgraded legacy cron rows with a non-canonical wake-mode value.
  • add merge-risk: 🚨 auth-provider: The PR changes provider routing defaults by honoring OpenAI and Anthropic base URL environment variables in more paths.
  • add merge-risk: 🚨 availability: Invalid cron wake-mode values can defer jobs that should wake immediately after startup.
  • add rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🐚 platinum hermit and patch quality is 🦐 gold shrimp.
  • add status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Not applicable: This is a maintainer-labeled protected PR with targeted tests and Testbox proof recorded in the body, so the external-contributor proof gate is not applied here.

Label justifications:

  • P2: The PR addresses real provider and state upgrade bugs, but the remaining blocker is scoped and repairable before merge.
  • merge-risk: 🚨 compatibility: The PR changes SQLite upgrade behavior and can leave upgraded legacy cron rows with a non-canonical wake-mode value.
  • merge-risk: 🚨 availability: Invalid cron wake-mode values can defer jobs that should wake immediately after startup.
  • merge-risk: 🚨 auth-provider: The PR changes provider routing defaults by honoring OpenAI and Anthropic base URL environment variables in more paths.
  • rating: 🦐 gold shrimp: Overall readiness is 🦐 gold shrimp; proof is 🐚 platinum hermit and patch quality is 🦐 gold shrimp.
  • status: ⏳ waiting on author: ClawSweeper has contributor-facing work open and is waiting for author action. Not applicable: This is a maintainer-labeled protected PR with targeted tests and Testbox proof recorded in the body, so the external-contributor proof gate is not applied here.
Evidence reviewed

PR surface:

Source +477, Tests +505. Total +982 across 27 files.

View PR surface stats
Area Files Added Removed Net
Source 13 527 50 +477
Tests 14 524 19 +505
Docs 0 0 0 0
Config 0 0 0 0
Generated 0 0 0 0
Other 0 0 0 0
Total 27 1051 69 +982

Acceptance criteria:

  • [P1] node scripts/run-vitest.mjs src/state/openclaw-state-db.test.ts -- --reporter=verbose.
  • [P1] node scripts/crabbox-wrapper.mjs run -- env OPENCLAW_CHECK_CHANGED_REMOTE_CHILD=1 OPENCLAW_CHANGED_LANES_RAW_SYNC=1 corepack pnpm check:changed.

What I checked:

  • Root and scoped policy applied: Root AGENTS.md plus the relevant extensions, agents, agent-tools, gateway, plugins, and plugin-sdk scoped guides were read; their provider/config/state-migration compatibility guidance applies to this PR. (AGENTS.md:1, 5be282e459ee)
  • Wake mode contract: CronWakeMode only allows next-heartbeat and now, so the PR's new auto additive default is outside the runtime contract. (src/cron/types.ts:23, 5be282e459ee)
  • Cron row load path: rowToCronJob casts persisted wake_mode directly into the cron job object, so invalid stored values are not normalized before scheduler decisions. (src/cron/store/row-codec.ts:233, 5be282e459ee)
  • Scheduler behavior: The timer only runs the immediate path when job.wakeMode === "now"; any other value falls through to the event heartbeat request path. (src/cron/service/timer.ts:1405, 5be282e459ee)
  • PR patch default: The PR adds the missing wake_mode column as TEXT NOT NULL DEFAULT 'auto'; malformed or non-backfillable legacy rows can keep that value. (src/state/openclaw-state-db.ts:525, 35ea3ca49c9c)
  • Feature history sample: Local blame/history in this shallow checkout attributes the current cron row codec, cron type contract, and state DB migration area to commit a355c88. (src/cron/store/row-codec.ts:233, a355c8897d1a)

Likely related people:

  • steipete: The local blame/history sample attributes the central cron store/state DB code in this shallow checkout to Peter Steinberger, and the PR context maps the current branch author to steipete. (role: recent area contributor; confidence: medium; commits: a355c8897d1a; files: src/cron/store/row-codec.ts, src/cron/types.ts, src/state/openclaw-state-db.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.

@steipete steipete force-pushed the fix/model-provider-sweep branch from e8437a5 to 2248511 Compare June 2, 2026 06:15

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: e8437a55cc

ℹ️ 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".

ensureColumn(db, "cron_jobs", "at TEXT");
ensureColumn(db, "cron_jobs", "stagger_ms INTEGER");
ensureColumn(db, "cron_jobs", "session_target TEXT NOT NULL DEFAULT 'main'");
ensureColumn(db, "cron_jobs", "wake_mode TEXT NOT NULL DEFAULT 'auto'");

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Use a valid cron wake-mode default

For older cron_jobs tables, this ADD COLUMN can leave rows with wake_mode = 'auto' whenever job_json is malformed or fails the strict backfill path. CronWakeMode only allows now or next-heartbeat (src/cron/types.ts:23), and the timer path treats anything other than now as a deferred heartbeat event, so affected legacy jobs can silently stop waking immediately after the DB is opened. Default this column to now (matching normalizeCronJobInput) or force-normalize invalid values after the backfill.

Useful? React with 👍 / 👎.

@openclaw-barnacle openclaw-barnacle Bot added the gateway Gateway runtime label Jun 2, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 35ea3ca49c

ℹ️ 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".

failure_alert_include_skipped = ?,
failure_alert_mode = ?,
failure_alert_account_id = ?,
runtime_updated_at_ms = ?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Badge Backfill cron runtime state too

When opening a legacy cron_jobs table that only has job_json, this backfill extracts the config fields but never writes state_json or the split runtime columns such as next_run_at_ms, last_run_at_ms, and delivery/error state. loadCronRows reconstructs job state from those columns/state_json, not from job_json, so existing scheduled jobs on this upgrade path lose their persisted nextRunAtMs and run history and can be skipped or rescheduled incorrectly. Copy job.state into state_json/the state columns during this backfill before considering the row migrated.

Useful? React with 👍 / 👎.

@clawsweeper clawsweeper Bot added 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. labels Jun 2, 2026
@openclaw-barnacle openclaw-barnacle Bot added the scripts Repository scripts label Jun 2, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot 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.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 66d8b1c17e

ℹ️ 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".

}
const update = db.prepare(
`UPDATE cron_jobs
SET name = ?,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Backfill cron descriptions

When upgrading a legacy cron_jobs table that only has job_json, this backfill copies name and other config fields but never sets the new description column. rowToCronJob reconstructs store.jobs from the split columns and only reads row.description, so any legacy job with a description in job_json loses it in list/search/update flows immediately after the DB is opened. Include description = ? populated from job.description in this migration path.

Useful? React with 👍 / 👎.

delivery ? textField(delivery, "mode") : null,
delivery ? textField(delivery, "channel") : null,
delivery ? textField(delivery, "to") : null,
delivery ? textField(delivery, "threadId") : null,

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Preserve numeric cron thread ids

For legacy cron jobs whose delivery used a numeric threadId (allowed by CronDelivery and normally stringified by bindDeliveryColumns), this backfill calls textField(delivery, "threadId"), so the value becomes NULL and subsequent delivery no longer targets the configured thread/topic. Coerce finite numeric thread ids to strings here like the normal persistence path does.

Useful? React with 👍 / 👎.

@steipete

steipete commented Jun 2, 2026

Copy link
Copy Markdown
Contributor Author

Land-ready proof for exact head 46514909b00c8b3672b9c2fe181d5322fec0ade9:

  • GitHub PR checks: green on the exact head, including CI build-artifacts, check-lint, check-dependencies, check-test-types, security/codeql critical lanes, and real behavior proof.
  • Remote changed gate: Crabbox delegated Blacksmith Testbox tbx_01kt3em5r9vd7g0bnykrff6jdk, exit 0.
  • Focused local proof covered OpenAI/Anthropic base URL env handling, OpenRouter Anthropic cache retention, provider-neutral apply_patch, model-picker stale scoped entries, GitHub Copilot bundled thinking policy, SQLite additive upgrades, and same-size log rotation readers.

Known scope note: issue #88201 was live-checked and is not closed here; direct API vs local inference overhead is improved from the original report but still materially different.

@steipete steipete merged commit 732d697 into main Jun 2, 2026
159 checks passed
@steipete steipete deleted the fix/model-provider-sweep branch June 2, 2026 06:35
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

agents Agent runtime and tooling commands Command implementations extensions: github-copilot extensions: openai gateway Gateway runtime maintainer Maintainer-authored PR rating: 🦐 gold shrimp Decent PR readiness signal, but merge confidence is limited. scripts Repository scripts size: XL 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.

1 participant