mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-19 09:01:39 -06:00
561effac2ea514121271e753d5bf87bc192564c3
7 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
55ce95fac8 |
feat(sessions): three-layer session ownership — agent attribution, assignable owner, participants (#125057)
* feat(sessions): stamp agent identity on spawned sessions and return spawn receipts Agent-spawned sessions recorded the requesting session key as createdActor.id, so the Control UI creator chip rendered an opaque key. Spawn producers now stamp the canonical requester agent id; parent-authority validation moves to a new trusted requesterSessionKey field. projectSessionActor enriches agent actors with configured identity name/avatar at read time, and visible sessions_spawn returns a sessionUrl + owner receipt with URL-first acknowledgement guidance. * feat(sessions): assignable session ownership with owner facet and menus GitHub-assignee-style ownership: sessions get a mutable owner (defaulting to the immutable createdActor) stored in additive bare-nullable SQLite columns with first-use lazy ensure. New operator.write sessions.assignOwner validates targets, requires an identified caller, authorizes by session visibility, and records assignedBy/assignedAt inside the write transaction. The sessions agent tool gains assign_owner; the Control UI adds Assign-to-me/Assign-to menus in sidebar rows and chat headers, renders the effective owner chip, and the creator facet/filter now keys on effective owner. Sharing authority stays anchored on createdActor. * feat(sessions): record session participants and stack them in the owner chip Records every distinct external prompter (human profile/channel sender, or a requesting agent) per session in an additive session_participants table at the turn-admission boundary — best-effort, deferred, never blocking the turn; the session's own agent and viewers are never recorded, capped at 32 per session. The session row projects a bounded participants list (owner excluded) plus a total count with the same actor enrichment as owner/createdActor. The sidebar chip becomes a pair-stack when others have prompted (owner front, one peeking participant or +N behind), the chat header shows the full facepile, and an authenticated involvingMe list filter adds an Involving-me sidebar predicate. Participant projection is excluded from logical-session CAS equality so display history never invalidates session writes. * fix(sessions): identify built-in agent tool callers for owner assignment The sessions tool's assign_owner dispatched through the in-process synthetic client, which carries neither a signed agent-runtime identity nor a human profile, so agent-initiated reassignment always failed with FORBIDDEN. The tool now captures its trusted requester agent identity and carries it across in-process dispatch as internal client state (never wire params); the handler derives assignedBy as signed runtime identity, then trusted agent-tool caller, then authenticated human. Live-verified end-to-end on a dev gateway. * fix(ci): split oversized session modules and refresh prompt snapshots Split the max-lines offenders at concept boundaries for session equality, tool overrides, and protocol owner schemas. Remove the redundant Number conversion from the node:sqlite participant count. Refresh prompt snapshots after drift from the sessions and sessions_spawn tool description updates. * fix(ci): restore solo-mode chip suppression and conform new method descriptors Solo-mode root cause: owner-assignment submenu options reused the permanent owner-chip custom element, so hidden menu avatars were counted as attribution chrome. Menus now use viewer avatars while gateway-gated owner chips remain exclusive to collaborative sessions. Conform sessions.assignOwner to the 2026.8 descriptor and append-only advertised-method inventories, and regenerate the Swift and Kotlin protocol surfaces. Keep historical v15/v14 fixtures frozen by stripping the new owner columns; the existing range already excludes the participant table. Replace the new raw SQLite schema probes with synchronous Kysely queries. Clear max-lines by splitting the organizer host contract, pure agent-navigation projections, and ownership/filtering sidebar cases at their concept boundaries. * fix(ci): integrate ownership series with latest main surfaces Wire the sessions-page assign-owner action, merge capability imports, narrow the navigation export scope, and apply sessions-create formatting. The owner-presence regression came from hidden assign-owner menu avatars emitting data-viewer-id, so owner and menu chrome now opt out of presence markers while real facepiles retain them. * fix(sessions): scope the involving-me filter to profile-backed participants Session participant history mixed channel-native sender ids with authenticated Gateway profile ids, so involving-me missed real sessions and could accept numeric collisions. Record the actor_source namespace at each producer, carry it through the internal SQLite projection, and match authenticated viewers only against profile-backed human participants. Legacy NULL sources fail closed for filtering, while channel ids remain available for display. * build(ui): raise startup budget baseline for session ownership surfaces Ownership chips, assignment menus, and the participant stack add ~0.7 KiB gzip to the startup path; CI compression landed just over the previous baseline+tolerance. Hard cap (350 KiB) unchanged. * refactor(sessions): drop raw NULL projection for the lazy actor_source column The Kysely guardrail rejects typed raw sql snippets outside allowlisted boundaries; select the lazily-ensured column only when present and let the row projection treat its absence as unknown/legacy. * build(ui): refresh combined startup baseline |
||
|
|
fc4d5d744f |
fix(sessions): prevent cleanup from deleting readable transcripts (#123495)
* fix(sessions): make transcript archival atomic * fix(sessions): stabilize SQLite archive CI * test(gateway): synchronize lifecycle patch race * fix(sessions): finish archive recovery accounting * fix: key transcript archives by generation Remeasure physical disk usage after archive publication so budget results and pruning use the bytes actually present on disk. Refs oc-8e9 * fix(sessions): normalize doctor archive generations (oc-a28) --------- Co-authored-by: Josh Lehman <550978+jalehman@users.noreply.github.com> |
||
|
|
c5a2220d37 |
refactor(sessions): restructure per-agent SQLite schema (#113071)
* refactor(sessions): restructure agent session schema * fix(sessions): preserve sharing across node ownership * refactor: split session node artifact helpers * test: track session cleanup temp directories * fix(sessions): preserve fresher alias artifacts * fix(sessions): reject placeholder membership writes * test(sessions): align schema ownership fixtures * fix(sessions): align incognito and heartbeat ownership * test(sessions): preserve retained window rehoming coverage |
||
|
|
7d71d7cf6b |
fix(sessions): large histories no longer load entire transcripts (#108851)
* perf(sessions): bound SQLite history reads * fix(sessions): keep history pagination gap-free * test(sessions): use shared temp cleanup * fix(sessions): reconcile mixed transcript projections * fix(sessions): preserve strict schema migration * refactor(sessions): trim internal export surface * refactor(sessions): keep reader helpers private * fix(sessions): reconcile transcript projections off requests * test(sessions): await transcript projection repair * fix(sessions): normalize projection worker failures * fix(sessions): satisfy projection release gates |
||
|
|
bae9752c5a | refactor(deadcode): enforce repository hard zero (#108641) | ||
|
|
e580275464 |
feat(tooling): enforce noUncheckedIndexedAccess in the scripts lane (NUIA phase 5) (#105180)
* feat(tooling): enforce noUncheckedIndexedAccess in the scripts lane Burns down all 153 scripts-lane errors (bench aggregation, release checks, i18n inventories, argv indexing) and flips the flag in tsconfig.scripts.json. Direct-Node-executed release harness scripts use local narrowing instead of workspace imports, which do not resolve under plain node execution. Benchmark measured loops untouched. * fix(scripts): import expect helpers via relative package sources tsconfig path aliases resolve from cwd under tsx, so release wrapper scripts running against old release target cwds could not resolve @openclaw/normalization-core (not a linked root dependency). Relative package-source imports match the established pattern on the adjacent lines and are cwd-independent; old-target planning verified directly. |
||
|
|
0a8e3604ba |
refactor: flip sessions and transcripts to sqlite storage (#98236)
* refactor(sessions): migrate runtime storage to sqlite * test(sessions): fix sqlite CI regressions * test(sessions): align remaining sqlite fixtures * fix(codex): require sqlite trajectory recorder * test(sessions): align orphan recovery sqlite fixture * test(sessions): align sqlite rebase fixtures * fix(sessions): finish current-main integration of the sqlite flip Resolve the whole-store SDK removal across its owner boundary: drop the loadSessionStore re-export and the registry whole-store wrappers, wire hasTrackedActiveSessionRun into gateway chat, complete the preserveLockedHarnessIds cleanup contract, flip the codex thread-history import to storePath targets, and port remaining main-side tests from file-store helpers to session accessor reads. * chore: drop committed pebbles log, revert plugin-inspector bump, refresh generated docs Remove the 1.8k-line .pebbles/events.jsonl work log from the branch, restore the plugin-inspector advisory lane to main's pinned 0.3.10 so the supply-chain bump gets its own review, and regenerate docs_map, the plugin SDK API baseline, and the export-surface ratchet for the merged tree. * feat(sessions): keep archived transcripts by default with zstd cold storage Codex-style retention: deleting or resetting a session archives its transcript as a zstd-compressed JSONL artifact (plain when the runtime lacks node:zlib zstd) and keeps it until the disk budget evicts oldest first. resetArchiveRetention now governs both deleted and reset archives and defaults to keep; maxDiskBytes defaults to 2gb so retention stays bounded, with archives evicted before live sessions. The cron reaper follows the same knob instead of deleting archives on its own timer. * fix(state): converge agent DB migration lineages and bound database growth Merge coherence: run both structure-gated legacy memory-schema repairs (flip-lineage drop, main-lineage identity rebuild) before the flip migration so pre-flip v1/v2 and pre-merge flip v1/v4 databases all converge, and hoist foreign_keys=OFF outside the schema transaction where the pragma was silently ignored and the v1 sessions rebuild cascade-deleted session_entries. Growth guards: fresh agent DBs enable auto_vacuum=INCREMENTAL, WAL maintenance releases freed pages in bounded passes (never a blocking full VACUUM), and doctor reports state/agent DB bloat from freelist stats. * fix(codex): resolve the store path for thread-history import via the SDK The supervision catalog passed the legacy sessionFile locator to the storePath-targeted transcript mirror; resolve the agent store path with the session-store SDK helper instead of a runtime-object seam so test fakes and headless callers need no extra surface. Drop the obsolete missing-session-id preprocessing case: sessions rows are NOT NULL on session_id and upsert repairs id-less patches at write time. * fix(sessions): fail safe on malformed disk-budget config and doctor stat errors A malformed explicit maxDiskBytes disables the budget instead of falling back to the destructive 2gb default the user never chose, and the doctor bloat check skips databases whose paths stat-fail instead of aborting doctor. * fix(sessions): complete sqlite conflict translations * test(sqlite): align hardening checks with maintenance * test(sessions): inspect compressed transcript archives * fix(tests): await session seeds and drop unused helpers flagged by CI lint The five unawaited writeSessionStoreSeed calls raced their SQLite seeds against the assertions, failing compact shards; the bloat probe drops a useless initializer and the merged tests drop now-unused helpers. * test(sessions): type legacy proof events directly * test(sessions): align hardening contracts * perf(sessions): read usage transcript sizes from SQL aggregates Usage/cost scans walked every session and materialized every transcript event just to re-stringify it for a byte estimate — the #86718 stall class reborn on the DB. readTranscriptStatsSync sums stored JSON bytes in SQLite without loading a single row. * fix(sessions): re-root foreign-root transcript paths onto the current sessions dir Restored backups, moved OPENCLAW_STATE_DIR, and rehearsal copies carry absolute sessionFile paths from the old root; the containment fallback kept those foreign paths, so migration read (and would archive) files in the original root and reported local copies missing. Re-root the canonical agents/<id>/sessions suffix onto the current dir when the file exists there; genuine cross-root layouts still fall through unchanged. * test(agents): seed harness admission through sqlite * fix(sqlite): close agent db on pragma setup failure * fix(doctor): compact and retrofit incremental auto-vacuum after session import The migration is the sanctioned offline window: post-import compact reclaims import churn and applies auto_vacuum=INCREMENTAL to databases created before the fresh-DB pragma existed, so runtime maintenance can release pages in bounded passes on every install. --------- Co-authored-by: Peter Steinberger <steipete@gmail.com> |