Skip to content

chore(migrations): phase out PROFILE.md from disk on schema_version=1#1734

Merged
senamakel merged 5 commits into
tinyhumansai:mainfrom
sanil-23:chore/phase-out-profile-md
May 14, 2026
Merged

chore(migrations): phase out PROFILE.md from disk on schema_version=1#1734
senamakel merged 5 commits into
tinyhumansai:mainfrom
sanil-23:chore/phase-out-profile-md

Conversation

@sanil-23
Copy link
Copy Markdown
Contributor

@sanil-23 sanil-23 commented May 14, 2026

Summary

  • Adds a one-shot startup migration that retires the legacy PROFILE.md injection across all on-disk artifacts.
  • Introduces Config::schema_version (default 0) as the gate; bumped to 1 after the migration completes.
  • Wires the runner into Config::load_or_init so it fires before any agent turn can resume a session.

Problem

Earlier builds wrote PROFILE.md into the workspace and rendered ### PROFILE.md into the system prompt for any agent with omit_profile = false (orchestrator, welcome, trigger_*, help). Once injected, the runtime loader (agent/harness/session/turn.rs:1295 try_load_session_transcript) replays those bytes verbatim on every resume for KV-cache stability. A renderer-only fix leaves existing JSONL transcripts and their .md companions replaying the leaked content forever. The producer side (learning/profile_md_renderer.rs, composio/providers/traits.rs:115 merge_provider_into_profile_md) is being retired separately; this PR handles every consumer surface so the leak cannot replay even if the file briefly resurfaces.

Solution

New src/openhuman/migrations/ module (sibling to the existing user-triggered migration/ OpenClaw import) with a runner gated by schema_version:

  1. Delete {workspace}/PROFILE.mdinject_workspace_file_capped skips silently when the file is missing, so the renderer becomes a no-op for the 5 omit_profile = false agents without touching their agent.toml.
  2. Walk every session_raw/**/*.jsonl (flat + legacy DDMMYYYY/), read via transcript::read_transcript, strip ### PROFILE.md from the first system message via strip_profile_md_block, rewrite via transcript::write_transcript (also re-renders the companion .md).
  3. Walk every sessions/**/*.md and alter in place — same stripper, with a broader boundary set (### , ---, ## [, <!--/MSG-->) so it cleanly bounds both the new JSONL-companion format and the legacy HTML-comment format. The rest of each transcript (all messages, all metadata) is preserved.

Hook lives in Config::load_or_init (config/schema/load.rs) at the end of the existing-config and first-launch branches; the pre-login in-memory branch is deliberately skipped. Idempotent in two ways: the version gate is a fast check on every subsequent call, and each step is self-idempotent (file already gone → no-op, transcript already clean → skipped, .md already clean → byte-identical). Best-effort: any per-file failure folds into stats.errors and the walk continues; runner-level failures log and never block startup.

Live verified against my real workspace (24 JSONLs, 100 .md companions): scanned=24 cleaned=1 skipped=23 errors=0 profile_md_removed=true md_companions_altered=1, second launch instant no-op. Tests in tempdirs cover the stripper for new-format .md (--- boundary), legacy HTML-comment .md (<!--/MSG--> boundary), JSONL with next ### heading, JSONL terminating at EOF, JSONL with the truncation footer, plus the version-gate idempotency on run_pending.

Submission Checklist

  • Tests added or updated (happy path + failure / edge case) per Testing Strategy — 22 new unit tests covering stripper boundaries, JSONL walk, .md sweep (both formats), file deletion, version-gate, fresh-install short-circuit, idempotency.
  • Diff coverage ≥ 80% — diff is Rust-only inside the new migrations/ module; every public path has direct tests via cargo test openhuman::migrations:: (15/15 lib tests + 7 stripper tests pass).
  • N/A: behaviour-only change — Coverage matrix updated. The migration changes on-disk state during startup, not user-facing UI/RPC behavior; TEST-COVERAGE-MATRIX.md rows track product features, not internal startup migrations.
  • N/A: no matrix rows — All affected feature IDs from the matrix are listed under ## Related.
  • No new external network dependencies introduced.
  • N/A: no release-cut surface change — Manual smoke checklist updated.
  • N/A: no linked issue — Linked issue closed via Closes #NNN.

Impact

  • Runtime/platform: desktop (only surface that runs openhuman-core serve). Fires once per workspace on first launch of the new build.
  • Performance: walks all transcripts once on the first post-update launch (typically <100 files; my workspace: 24 JSONL + 100 .md cleaned in ~5ms). Every subsequent launch hits the schema_version >= 1 early-return and exits the runner in microseconds.
  • Migration: one-way (schema_version: 0 → 1). No rollback path; if a user re-installs an older build, the field is silently ignored (no deny_unknown_fields).
  • Compatibility: config.toml files written by older builds load unchanged — #[serde(default)] defaults missing schema_version to 0 so they pick up the migration on the next launch.
  • Producer side untouched: merge_provider_into_profile_md (composio/providers/traits.rs:115) and ProfileMdRenderer (learning/profile_md_renderer.rs) still exist. If they ever fire, the file reappears and the 5 omit_profile = false agents will re-inject. That cleanup is the explicit v2 follow-up.

Related

  • Closes:
  • Follow-up PR(s)/TODOs:
    • v2: disable or remove the PROFILE.md writer paths (merge_provider_into_profile_md, ProfileMdRenderer) and flip the 5 omit_profile = false flags in welcome / trigger_triage / trigger_reactor / orchestrator / help agent.toml files.
    • Remove this migration module in a later release once active workspaces have rolled forward past schema_version=1.

AI Authored PR Metadata (required for Codex/Linear PRs)

Keep this section for AI-authored PRs. For human-only PRs, mark each field N/A.

Linear Issue

  • N/A: no Linear issue — Key
  • N/A: no Linear issue — URL

Commit & Branch

  • Branch: chore/phase-out-profile-md
  • Commit SHA: 09265034313af9f42dd27c96a6af9aff62e90f3b

Validation Run

  • N/A: no app/ changes — pnpm --filter openhuman-app format:check
  • N/A: no app/ changes — pnpm typecheck
  • Focused tests: cargo test --lib openhuman::migrations:: → 22 passed; 0 failed
  • Rust fmt/check (if changed): cargo fmt --check (clean) + cargo check (only pre-existing warnings)
  • N/A: no Tauri-shell changes — Tauri fmt/check (if changed)

Validation Blocked

  • command: N/A
  • error: N/A
  • impact: N/A

Behavior Changes

  • Intended behavior change: one-time cleanup of legacy PROFILE.md state on disk; future agent system prompts are produced from a workspace with no PROFILE.md and no tainted persisted transcripts.
  • User-visible effect: none directly. The first launch on the new build silently strips any leaked content from past sessions; conversations and transcript proofs are preserved.

Parity Contract

  • Legacy behavior preserved: yes for everything outside the ### PROFILE.md block; the renderer code path is unchanged, only the file it would read is gone.
  • Guard/fallback/dispatch parity checks: load_or_init still falls back to Default::default() on config-load failure (line 798); migration simply doesn't run that launch and retries on the next.

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features

    • Introduced automatic workspace data migrations that run on startup to keep your data schema up-to-date.
    • Removed legacy PROFILE.md content from session transcripts and related files.
  • Tests

    • Added comprehensive test coverage for the migration system.

Review Change Stack

Adds a one-shot startup migration that retires the legacy PROFILE.md
system-prompt injection. On the first launch of the new build it:

1. Deletes {workspace}/PROFILE.md so the renderer's
   inject_workspace_file_capped silently short-circuits even for agents
   that still have omit_profile = false.
2. Strips ### PROFILE.md blocks from every JSONL transcript under
   session_raw/ (flat + legacy DDMMYYYY/), rewriting via the existing
   write_transcript so the on-disk shape stays byte-compatible.
3. Alters in place any .md companion / legacy HTML-comment transcript
   under sessions/**/*.md that still carries the block — preserving the
   conversation messages around it (proofs intact).

The migration is gated by a new Config::schema_version (default 0,
bumped to CURRENT_SCHEMA_VERSION=1 on success) and wired into
Config::load_or_init so the first call from run_server_inner fires it
before any agent turn can resume a session. It is idempotent
end-to-end: clean transcripts are byte-identical, fresh installs still
bump the version, second invocations no-op via the version gate.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@sanil-23 sanil-23 requested a review from a team May 14, 2026 12:08
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 14, 2026

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: f2fafb65-88c4-41e7-ae29-5c51b708ddd8

📥 Commits

Reviewing files that changed from the base of the PR and between 0926503 and c8f5c55.

📒 Files selected for processing (5)
  • src/openhuman/config/schema/load.rs
  • src/openhuman/migrations/mod.rs
  • src/openhuman/migrations/mod_tests.rs
  • src/openhuman/migrations/phase_out_profile_md.rs
  • src/openhuman/migrations/phase_out_profile_md_tests.rs
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/openhuman/migrations/mod.rs
  • src/openhuman/migrations/mod_tests.rs
  • src/openhuman/config/schema/load.rs
  • src/openhuman/migrations/phase_out_profile_md.rs
  • src/openhuman/migrations/phase_out_profile_md_tests.rs

📝 Walkthrough

Walkthrough

The PR adds startup schema-versioning (Config.schema_version), runs pending migrations during Config::load_or_init, and implements a 0→1 migration that removes legacy ### PROFILE.md blocks from session JSONL transcripts and companion markdown files.

Changes

Startup Schema Versioning and Phase-Out Migration

Layer / File(s) Summary
Config schema versioning and startup integration
src/openhuman/config/schema/types.rs, src/openhuman/config/schema/load.rs, src/openhuman/mod.rs
Config adds schema_version: u32 (serde default, default = 0). Config::load_or_init invokes migrations::run_pending(&mut config).await in both existing-config and fresh-install paths; openhuman::migrations is exported.
Migration dispatcher and run_pending orchestrator
src/openhuman/migrations/mod.rs
Defines CURRENT_SCHEMA_VERSION = 1 and pub async fn run_pending(config: &mut Config) which gates migrations by config.schema_version, runs the 0→1 phase_out_profile_md migration in a blocking task, updates config.schema_version on success, persists via config.save().await, and logs failures without propagating them.
Phase-out PROFILE.md migration logic
src/openhuman/migrations/phase_out_profile_md.rs
Implements run(workspace_dir) to remove {workspace}/PROFILE.md, rewrite session_raw/*.jsonl transcripts to strip ### PROFILE.md from the first system message, sweep one-level sessions/*.md companions to strip blocks, and return PhaseOutStats. The stripper locates PROFILE_HEADING and removes until concrete boundary markers (### , ---, ## [, <!--/MSG-->), trimming blank lines and avoiding no-op rewrites.
Migration dispatcher integration tests
src/openhuman/migrations/mod_tests.rs
Integration tests and helpers that seed tainted transcripts and temp configs; test cases cover: no-op when version current, 0→1 migration with transcript cleaning and persisted schema_version = 1, fresh-install bump, save-failure rollback (in-memory rollback), and idempotent second invocation (no re-save).
Phase-out migration comprehensive test suite
src/openhuman/migrations/phase_out_profile_md_tests.rs
Unit tests for strip_profile_md_block (section boundary, end-of-prompt, truncation footer, absence, inline false-match) and integration tests for process_transcript and run (first-system-message-only mutation, flat+legacy layouts, PROFILE.md removal idempotency, companion markdown rewrites, clean-file byte-identity, non-.jsonl ignored).

Sequence Diagram(s)

sequenceDiagram
  participant App as Application
  participant Load as Config::load_or_init
  participant RunPending as run_pending
  participant PhaseOut as phase_out_profile_md::run
  participant Persist as config.save()
  App->>Load: load or create config
  Load->>RunPending: check schema_version
  alt version < CURRENT
    RunPending->>PhaseOut: run migration for 0→1
    PhaseOut->>PhaseOut: delete PROFILE.md
    PhaseOut->>PhaseOut: rewrite session JSONL transcripts
    PhaseOut->>PhaseOut: strip PROFILE.md from markdown companions
    PhaseOut-->>RunPending: return PhaseOutStats
    RunPending->>RunPending: update config.schema_version
    RunPending->>Persist: persist bumped version
    Persist-->>RunPending: success/fail logged
  end
  RunPending-->>Load: complete (no-op on errors)
  Load-->>App: return Config
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~60 minutes

Possibly related PRs

  • tinyhumansai/openhuman#1497: Modifies Config::load_or_init recovery/path handling in the same startup function where migrations::run_pending is now inserted.
  • tinyhumansai/openhuman#1563: Also edits Config::load_or_init corruption-handling and save timing, overlapping startup control paths changed here.

Suggested reviewers

  • senamakel

Poem

🐰 I hopped through configs at break of day,
Found PROFILE blocks that got in the way.
A version check, a tidy rewrite,
Transcripts now clean and bright.
One startup migration — tidy, polite. ✨

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately and specifically describes the main change: a migration that phases out PROFILE.md from disk triggered on schema_version=1.
Docstring Coverage ✅ Passed Docstring coverage is 100.00% which is sufficient. The required threshold is 80.00%.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.


Comment @coderabbitai help to get the list of available commands and usage tips.

coderabbitai[bot]
coderabbitai Bot previously approved these changes May 14, 2026
@sanil-23 sanil-23 marked this pull request as draft May 14, 2026 12:44
@sanil-23 sanil-23 marked this pull request as ready for review May 14, 2026 13:01
@sanil-23 sanil-23 changed the title chore(migrations): phase out PROFILE.md from disk on schema_version=1 chore(migrations): phase out old PROFILE.md from on schema_version=1 May 14, 2026
Copy link
Copy Markdown
Contributor

@graycyrus graycyrus left a comment

Choose a reason for hiding this comment

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

Walkthrough

This PR introduces a one-shot startup migration framework gated by Config::schema_version. The first migration (0 → 1) retires the legacy PROFILE.md injection by: (1) deleting {workspace}/PROFILE.md, (2) stripping ### PROFILE.md blocks from JSONL transcripts under session_raw/, and (3) sweeping .md companions under sessions/. The runner is wired into Config::load_or_init so it fires before any agent turn can resume a session.

Changes

File Change
types.rs Add schema_version: u32 to Config with #[serde(default)]
load.rs Call migrations::run_pending() in both config-load branches
migrations/mod.rs Migration runner: version gate, dispatch, config save, retry
migrations/phase_out_profile_md.rs The migration: file deletion, JSONL walk+strip, .md sweep
migrations/mod_tests.rs 4 integration tests for the runner
migrations/phase_out_profile_md_tests.rs 18 unit tests for the migration
mod.rs Add pub mod migrations;

Strengths

  • Well-structured module: follows CLAUDE.md dedicated-subdirectory rule, light mod.rs, impl in own file
  • 22 tests covering happy paths, edge cases (truncation footer, legacy HTML format, fresh install), idempotency
  • Excellent [migration:phase-out-profile-md] prefixed logging — easy to diagnose in production
  • Best-effort: per-file errors fold into stats without aborting; runner failures don't block startup
  • No .unwrap() in production code, no hardcoded PII in tests

Issues

See inline comments — 1 major, 4 minor, 1 nit.

initialized = true,
"Config loaded"
);
crate::openhuman::migrations::run_pending(&mut config).await;
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.

[minor] Fresh installs run the migration over an empty workspace. The new-config branch creates Config with schema_version: 0 (from Default), so run_pending walks an empty workspace. It short-circuits fast, but the intent is wrong — fresh installs have nothing to migrate.

Suggestion: set schema_version: CURRENT_SCHEMA_VERSION in the fresh-install branch so new workspaces skip all legacy migrations by definition.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Done in c8f5c55 — fresh-install branch now sets schema_version: CURRENT_SCHEMA_VERSION directly so new workspaces skip the migration by definition. The defensive run_pending call stays for symmetry (short-circuits on the gate).

);
}
Err(err) => {
stats.errors += 1;
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.

[minor] sweep_tainted_md_companions only walks one level of subdirectories under sessions/. If deeper nesting exists (e.g. sessions/2026/05/14/*.md), those files are missed. The JSONL walk has the same single-level assumption. If the layout is guaranteed at most one level deep, worth documenting the assumption explicitly so future contributors know.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Documented the one-level-deep assumption in c8f5c55 — added a "Layout assumption" paragraph to sweep_tainted_md_companions rustdoc referencing the matching assumption in collect_jsonl_transcripts. Both walkers descend exactly into sessions/<date>/*.md and session_raw/<legacy-date>/*.jsonl, matching the layout produced by agent/harness/session/transcript.

//!
//! When `session_raw/` does not exist or contains no transcripts the
//! migration short-circuits without scanning. The caller still bumps
//! `schema_version` so future launches don't re-check.
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.

[minor] run() is synchronous blocking I/O called from async context. run_pending is an async fn, but phase_out_profile_md::run() does synchronous filesystem I/O (read_dir, read_to_string, write, remove_file). On a workspace with hundreds of transcripts this blocks the tokio runtime thread.

Suggestion: wrap in tokio::task::spawn_blocking in run_pending.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in c8f5c55run_pending now wraps the migration in tokio::task::spawn_blocking(move || phase_out_profile_md::run(&workspace_dir)) so the fs walk runs on a blocking thread instead of stalling the executor.

let Some(first) = session.messages.first_mut() else {
return false;
};
if first.role != "system" {
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.

[major] strip_profile_md_block always returns Some when the heading exists, even if the reconstructed output is byte-identical to the input. This means process_transcript will rewrite files unnecessarily, and the skipped counter under-counts.

Add a guard before returning:

if out == prompt {
    return None;
}
Some(out)

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch, fixed in c8f5c55strip_profile_md_block now returns None when out == prompt even after the heading was located, so degenerate-whitespace cases no longer churn the file. Added strip_block_returns_none_when_reconstruction_is_byte_identical to lock the behavior.

Comment thread src/openhuman/migrations/mod.rs Outdated
if let Err(err) = config.save().await {
log::warn!(
"[migrations] phase_out_profile_md ran but config.save failed: \
{err:#} — will retry on next launch"
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.

[minor] In-memory schema_version not rolled back on save failure. Line 63 sets config.schema_version = 1, but if config.save() fails (line 64), the early return at line 68 leaves the in-memory config at version 1 while disk says 0. Benign with one migration, but when migration 2 is added the caller sees version 1 in memory and might skip re-running migration 1 on the next code path.

Suggestion: roll back on save failure:

Err(err) => {
    config.schema_version = 0;
    log::warn!(...);
    return;
}

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed in c8f5c55 — added the rollback path. If config.save() fails we now reset config.schema_version to its pre-migration value before logging+returning, so the in-memory state never diverges ahead of disk. Added run_pending_rolls_back_schema_version_when_save_fails (forces save() to fail by pointing config_path through a non-directory) to lock the semantics.

/// the field) load as version `0` and pick up pending migrations on
/// the first launch of the new build.
#[serde(default)]
pub schema_version: u32,
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.

[nit] PR title says phase out old PROFILE.md from on schema_version=1 — the from on looks like a leftover edit. Should be on schema_version=1 or from schema_version=0.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Fixed the PR title — was phase out old PROFILE.md from on schema_version=1, now phase out PROFILE.md from disk on schema_version=1 (matches the commit message).

- load.rs: fresh-install branch stamps `schema_version: CURRENT_SCHEMA_VERSION`
  up front so new workspaces skip the migration walk by definition. The
  defensive `run_pending` call stays for symmetry — it short-circuits on
  the version gate.
- mod.rs: wrap `phase_out_profile_md::run` in `tokio::task::spawn_blocking`
  so the synchronous fs walk doesn't stall the tokio executor when a
  workspace carries many transcripts. Roll the in-memory
  `schema_version` back to the pre-migration value if `config.save()`
  fails, so a later call doesn't see a higher in-memory version than
  what's on disk.
- phase_out_profile_md.rs: `strip_profile_md_block` now returns `None`
  when the reconstructed string is byte-identical to the input. Document
  the one-level-deep walk assumption in `sweep_tainted_md_companions`
  rustdoc.
- tests: add `strip_block_returns_none_when_reconstruction_is_byte_identical`
  and `run_pending_rolls_back_schema_version_when_save_fails`. 24 tests pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@sanil-23 sanil-23 changed the title chore(migrations): phase out old PROFILE.md from on schema_version=1 chore(migrations): phase out PROFILE.md from disk on schema_version=1 May 14, 2026
@sanil-23
Copy link
Copy Markdown
Contributor Author

@graycyrus thanks for the review. All six points addressed in c8f5c551:

# Finding Resolution
1 Fresh-install branch ran migration over empty workspace load.rs:743 fresh-install branch now stamps schema_version: CURRENT_SCHEMA_VERSION directly so new workspaces skip the walk by definition. The run_pending call stays for symmetry — short-circuits on the version gate.
2 One-level-deep walk under sessions/ undocumented Added a "Layout assumption (one level deep)" paragraph to sweep_tainted_md_companions rustdoc, referencing the matching assumption in collect_jsonl_transcripts. Both walkers descend exactly into sessions/<date>/*.md and session_raw/<legacy-date>/*.jsonl, matching what agent/harness/session/transcript writes.
3 Synchronous I/O on async runtime run_pending wraps phase_out_profile_md::run in tokio::task::spawn_blocking(move || phase_out_profile_md::run(&workspace_dir)) so the fs walk runs on a blocking thread instead of stalling the executor.
4 (major) strip_profile_md_block returned Some even when output was byte-identical Added if out == prompt { return None; } guard. New test strip_block_returns_none_when_reconstruction_is_byte_identical locks the behavior.
5 In-memory schema_version not rolled back on save() failure Captured previous_version before bumping; on save() error we restore it and log the rollback, so the in-memory value never gets ahead of disk. New test run_pending_rolls_back_schema_version_when_save_fails forces save() to fail (config_path through a non-directory) and asserts schema_version == 0 after.
6 (nit) PR title typo from on Edited title to chore(migrations): phase out PROFILE.md from disk on schema_version=1 (matches the commit message).

24 tests pass (up from 22), cargo fmt --check clean, cargo clippy --lib --tests clean in the diff cone.

Mind taking another look when you have a minute?

@senamakel senamakel merged commit a7a262b into tinyhumansai:main May 14, 2026
20 of 21 checks passed
AusAgentSmith pushed a commit to AusAgentSmith/openhuman that referenced this pull request May 23, 2026
…tinyhumansai#1734)

Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants