Skip to content

Persist Automation session provenance for session-list filtering - #337757

Draft
Ulugbek Abdullaev (ulugbekna) wants to merge 8 commits into
mainfrom
agents/investigate-legacy-client-automation-removal
Draft

Ulugbek Abdullaev (ulugbekna) wants to merge 8 commits into
mainfrom
agents/investigate-legacy-client-automation-removal

Conversation

@ulugbekna

Copy link
Copy Markdown
Contributor

Summary

Use the existing typed AHP session origin to identify Automation-created sessions instead of joining the client session list against currently available run history.

  • Record Automation/run origin at host session creation and preserve it through session storage, the catalogue, state, listings, notifications, protocol mappings, and client caches.
  • Derive the Automation marker in the shared session adapter for local, remote, and Dev Container providers; remove the local-provider run-ledger join. Keep the existing ordinary-list filter and Automation history opening behavior.
  • Backfill older Agent Host sessions from retained full run membership, including secondary sessions and history beyond the initial page. Persist recovered origin so classification no longer depends on retaining that history.

Compatibility and scope

Sessions without recoverable origin remain visible by design. This does not add AHP protocol fields, promotion behavior, or a new host visibility mechanism. Legacy renderer-owned Automation execution is not changed by this PR.

Validation

Previously executed on this patch:

  • Electron unit tests: 575 passing, 18 pre-existing pending.
  • npm run transpile-client and npm run typecheck-client passed.
  • Targeted ESLint for all 24 changed TypeScript files passed.
  • git diff --check passed; pre-commit hygiene passed when committing.

Tests cover host creation and persistence, restart and historical recovery, deletion races, protocol and cache propagation, ordinary-list exclusion, and history opening. No live Agents Window walkthrough or real remote/Dev Container end-to-end validation was performed.

Outstanding review findings

This draft publishes the current implementation as-is. These findings from the static Opus 5.5 review remain unresolved:

Carry existing AHP automation origins from creation through persistence, listings, notifications, and client caches. Classify sessions from host-owned provenance instead of joining the client run ledger, with evidence-based backfill for retained host history.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI balanced review requested due to automatic review settings September 24, 2026 17:39
Preserve Automation session provenance while integrating upstream catalogue metadata, protocol, and provider test changes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI 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.

Copilot review overview

🔵 Needs a closer look

Provenance backfill failures can break listings or restoration, discard metadata overlays, and leave a downgrade-recovery path dependent on retained run history.

Review effort: Balanced
Findings: None

What changed in this PR

Persists Agent Host Automation provenance so Sessions can reliably classify and filter Automation-created sessions without relying on run history.

Changes:

  • Persists and recovers typed SessionOrigin through host storage and catalogs.
  • Propagates provenance through protocol, providers, state, and client caches.
  • Filters Automation sessions from the main list and adds regression coverage.
File Description
src/​vs/​sessions/​contrib/​sessions/​test/​browser/​sessionsList.test.ts Tests list filtering and history opening.
src/​vs/​sessions/​contrib/​providers/​remoteAgentHost/​test/​browser/​remoteAgentHostSessionsProvider.test.ts Tests remote cache persistence.
src/​vs/​sessions/​contrib/​providers/​agentHost/​test/​browser/​localAgentHostSessionsProvider.test.ts Tests local origin propagation and hydration.
src/​vs/​sessions/​contrib/​providers/​agentHost/​browser/​localAgentHostSessionsProvider.ts Removes run-ledger classification.
src/​vs/​sessions/​contrib/​providers/​agentHost/​browser/​baseAgentHostSessionsProvider.ts Adapts and caches session origin.
src/​vs/​sessions/​AUTOMATIONS.md Documents provenance persistence contract.
src/​vs/​platform/​agentHost/​test/​node/​protocolServerHandler.test.ts Tests listing protocol mapping.
src/​vs/​platform/​agentHost/​test/​node/​agentService.test.ts Tests creation, recovery, and deletion races.
src/​vs/​platform/​agentHost/​test/​node/​agentHostStateManager.test.ts Tests state and notification propagation.
src/​vs/​platform/​agentHost/​test/​node/​agentHostCatalogSourceResolver.test.ts Tests metadata persistence and validation.
src/​vs/​platform/​agentHost/​test/​node/​agentHostCatalogProjection.test.ts Tests catalog encoding and validation.
src/​vs/​platform/​agentHost/​test/​node/​agentHostCatalogListReader.test.ts Tests catalog-only listing.
src/​vs/​platform/​agentHost/​test/​node/​agentHostAutomationService.test.ts Tests full-history provenance recovery.
src/​vs/​platform/​agentHost/​test/​electron-browser/​agentHostProtocolClient.test.ts Tests client protocol preservation.
src/​vs/​platform/​agentHost/​node/​shared/​persistSessionMetadata.ts Defines the origin metadata key.
src/​vs/​platform/​agentHost/​node/​protocolServerHandler.ts Maps origin into list responses.
src/​vs/​platform/​agentHost/​node/​agentService.ts Creates, persists, backfills, and restores provenance.
src/​vs/​platform/​agentHost/​node/​agentHostStateManager.ts Carries origin through state summaries.
src/​vs/​platform/​agentHost/​node/​agentHostCatalogSourceResolver.ts Resolves persisted catalog origin.
src/​vs/​platform/​agentHost/​node/​agentHostCatalogProjection.ts Adds origin to catalog payloads.
src/​vs/​platform/​agentHost/​node/​agentHostCatalogListReader.ts Reads origin from catalog rows.
src/​vs/​platform/​agentHost/​node/​agentHostAutomationService.ts Indexes retained run membership.
src/​vs/​platform/​agentHost/​common/​state/​sessionState.ts Copies origin into session state.
src/​vs/​platform/​agentHost/​common/​agent.ts Extends session metadata with origin.
src/​vs/​platform/​agentHost/​browser/​agentHostProtocolClient.ts Maps listed origin into client metadata.

💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

Forward the existing catalogue row, including a known missing row, into provenance resolution instead of reading it again during fallback listing. Preserve the one-read coalescing invariant and cover catalogue results independently of listing eligibility.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Preserve metadata overlays and session restoration when optional provenance backfill fails, and omit concurrently deleted entries without rejecting the entire listing. Cover the failure paths and configure catalog test modes before provider registration.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
An eligible row's origin backfill already synchronizes the session database and catalogue. Do not dirty the row again and trigger another provider metadata read.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Version the provenance-aware projection so older origin-less rows cannot hide persisted origin on the first listing. Preserve old central-only metadata through migration-only decoding and verify that repaired listings return to the catalogue-only fast path.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI 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.

Copilot review overview

🟡 Changes recommended

Invalidating all v1 catalog rows can make existing sessions disappear when provider metadata is temporarily unavailable.

Get a fresh assessment by requesting another Copilot review.

Review effort: Balanced
Findings: 1 High severity

Open (1)


export const AGENT_HOST_CATALOG_PAYLOAD_VERSION = 1;
// Version 1 writers did not consult persisted session origin before projecting a row.
export const AGENT_HOST_CATALOG_PAYLOAD_VERSION = 2;
Keep validated v1 catalogue metadata available to the fallback reader until provider migration completes. Preserve ordinary central-only session titles, read/archive state and multi-root metadata without unnecessary provider metadata reads.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Resolve conflicts on top of upstream remote-session delegation while retaining Automation origin persistence and regression coverage.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>

Copilot AI 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.

Copilot review overview

🟡 Changes recommended

Three correctness gaps can misclassify sessions or leave Automation-created sessions inaccessible.

Get a fresh assessment by requesting another Copilot review.

Review effort: Balanced
Findings: 4 High severity

Open (4)

Comment on lines +116 to +120
for (const run of this._runs.values()) {
const origin: SessionOrigin = { kind: SessionOriginKind.Automation, automation: run.automation, run: run.resource };
for (const session of run.sessions) {
this._legacySessionOrigins.set(session, origin);
}
Comment on lines +814 to 818
}, {
kind: SessionOriginKind.Automation,
automation: run.automation,
run: run.resource,
}),
Comment on lines +1931 to +1947
const decoded = catalog && decodeAgentHostCatalogPayload(catalog.payload, { forMigration: true });
if (decoded && !decoded.ok) {
this._logService.warn(`[AgentService] Failed to read session origin from catalog for ${session}: ${decoded.error}`);
}
recovered ??= (decoded?.ok ? decoded.value.data.origin : undefined)
?? this._automationService.getLegacySessionOrigin(session.toString());
if (!recovered || (origin && (!decoded?.ok || equals(decoded.value.data.origin, origin)))) {
return recovered;
}
// Share the catalogue's deletion fence without recreating missing session databases.
return await this._catalogSyncService.runMigrationExclusive(session, async (database, synchronize) => {
if (await this._sessionRegistry.isTombstoned(session)) {
throw new ProtocolError(AHP_SESSION_NOT_FOUND, `Session not found: ${session}`);
}
const persistedOrigin = readPersistedSessionOrigin(await database?.object.getMetadata(SESSION_ORIGIN_KEY));
const currentCatalog = await this._orchestratorDatabase.getSessionV2(session.toString());
const current = currentCatalog && decodeAgentHostCatalogPayload(currentCatalog.payload, { forMigration: true });

Copilot AI 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.

Copilot review overview

🔵 Needs a closer look

A failed run-link persistence can leave an Automation-marked session hidden without any run-history entry through which users can open it.

Review effort: Balanced
Findings: 4 High severity

Open (4)

@github-actions

Copy link
Copy Markdown
Contributor

Screenshot Changes

Base: bdc5ebe5 Current: 8d4be7db

Changed (4)

chat/scrollAnchoring/chatScrollAnchoring/CompletedVisibleHeader/Dark
Before After
before after
chat/scrollAnchoring/chatScrollAnchoring/CompletedVisibleHeader/Light
Before After
before after
chat/scrollAnchoring/chatScrollAnchoring/CompletedOffscreenHeader/Light
Before After
before after
imageCarousel/imageCarousel/MultipleSections/Dark
Before After
before after

1 insignificant change(s) omitted (≤20 px, Δ≤2). See CI logs for details.

This branch has not been deployed

No deployments
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