Skip to content

external sessions: an imported task does not record where it came from #3081

Closed

Description

@Astro-Han

Importing an external conversation is a one-shot conversion (packages/storage/src/external-sessions.ts). createImportedSession takes a CreateSessionInput plus messages; nothing on the resulting Session records the adapterId + sourceSessionId it came from. (session.ts's sourceSessionId is revision lineage, a different thing.)

So the import page cannot know what it has already done. That single gap shows up as four separate-looking problems:

Shape of a fix

Persist the external origin on the imported session, and let the Host answer "what is the import state of this external session" (never imported / imported N times, with ids / import in flight). Then:

  • each row has a real three-state, and the duplicate consequence becomes a per-row fact
  • an unconfirmed import stays locked across remounts, and the banner can offer the task instead of asking the user to search
  • the in-flight label survives remount, and survives a second window or the CLI, which page-level state never could
  • a count alongside the cursor makes "还剩 12 个" possible

Scope

Touches storage schema, the external-session protocol, HostExternalSessionCoordinator and the Desktop page. Per AGENTS.md this is a public contract change: it needs independent human review and cannot take the self-merge fast path. Worth deciding whether the import page justifies it before anyone starts.

Refs #2984, #3033, #3075

Activity

  1. Sun-GLiang commented on Aug 16, 2026

    @Sun-GLiang
    Member

    I’m interested in taking this issue once the direction is confirmed.

    I reviewed the current import path and would propose the following approach.

    Durable provenance

    Persist an immutable external origin on Sessions created through the dedicated import path:

    externalOrigin?: {
      adapterId: string;
      sourceSessionId: string;
    };

    The origin should be persisted atomically with the imported Session and its messages.

    I would keep this out of the general CreateSessionInput, so ordinary Session callers cannot manufacture external provenance.

    The origin should belong only to the Session directly created by the import and should not propagate to branches, revisions, subagents, or other derived Sessions.

    Storage could then expose an indexed lookup or projection keyed by (adapterId, sourceSessionId). This should not be unique, since repeated imports remain valid.

    Host projection

    Rather than introducing a separate per-row query, I suggest including import information in external-session.catalog.query, roughly:

    importState: {
      importedCount: number;
      importedSessionIds: string[]; // potentially bounded, newest first
      isImporting: boolean;
    };

    The ID list could be bounded to preserve the external-session protocol result-size limit, while importedCount would still report the complete number of recorded imports.

    I prefer orthogonal fields over a strict never-imported | imported | importing union, because a source conversation may already have one or more imported copies while another import is currently in flight.

    The Host would derive this state from:

    • durable published Sessions found through the origin lookup; and
    • the existing #importsInFlight map for live operations.

    This would make import state observable across page remounts, Desktop windows, and other clients instead of relying on page-local state.

    Desktop and legacy behavior

    The Desktop page could then stop treating importingId and uncertainIds as authoritative and refetch Host state after a commit_outcome_unknown result.

    Existing imports cannot be reliably backfilled because their external source identity was never persisted. An empty lookup should therefore mean “no recorded import” rather than implying that the source was never imported historically.

    Pagination

    The totalCount / “N remaining” problem appears independent from provenance. Since the Host already materializes the adapter result before paging, I think this could be handled separately, ideally in a follow-up PR unless the intended scope of this issue is explicitly to address all four UI problems together.

    If this overall direction and the pagination split look reasonable, I’d be happy to take this issue. Please assign it to me, and I’ll coordinate the Desktop-side changes with #3075 to avoid overlapping work.

  2. Astro-Han commented on Aug 16, 2026

    @Astro-Han
    ContributorAuthor

    Assigned!

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

Metadata

Metadata

Assignees

Labels

enhancementNew feature or request

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions