세션 쿼리
라이브 우선 논리 세션 코퍼스에 대한 쿼리 어휘입니다. 서비스 정의 패키지는 정확한 읽기, 소스 우선순위, 관계 추적, 의미 추출 및 제공자 독립 필터를 담당하며, SQLite 제공자는 구체적인 전문 검색 인덱스 수명 주기를 담당합니다.
소스: packages/session-query/session-query/src/types.ts
논리 레코드
SessionRecord는 코퍼스 간 목록에서 반환됩니다. 복제된 라이브 우선 헤더와 독립적으로 소스 가용성을 노출합니다. SessionEventRecord는 경량 원시 로그 프로젝션이며, 분류는 모델 기록 파생과 동일한 foldSurface() 전환을 사용합니다.
/** Whether an event is current model context, replaced context, or raw-log-only. */
type SessionEventSurface = 'current' | 'shadowed' | 'log-only'/** Lightweight identity and source availability for one logical session. */
interface SessionRecord {
/** Cloned session header selected from the live-preferred corpus. */
header: SessionHeader
/** Whether the id currently exists in `ctx.sessions`. */
live: boolean
/** Whether the active persistence backend currently materializes the id. */
persisted: boolean
}SessionLogSnapshot는 재개 사전 점검에 사용되는, 분리되어 재생 검증된 완전한 원시 로그입니다. SessionSurfaceSnapshot는 유지되는 구독이 아니라 하나의 정확한 읽기 표면 관찰입니다.
/** One validated detached observation of a logical session's complete raw log. */
interface SessionLogSnapshot {
/** Cloned session header selected from the same observation as `events`. */
session: SessionHeader
/** Cloned contiguous raw events after persistence repair and replay validation. */
events: SessionEvent[]
}/** One atomic live-preferred observation of a session's current model surface. */
interface SessionSurfaceSnapshot {
/** Cloned session header selected from the same corpus observation as `events`. */
session: SessionHeader
/** Highest raw-log seq included in the observation, or `null` for an empty log. */
capturedThroughSeq: number | null
/** Cloned current surface events in model-history order. */
events: SurfaceEvent[]
}SessionTitleObservation는 제목 접기에도 동일한 원자적 관찰 규칙을 적용하므로, 권한 부여 소비자는 제목을 제공한 소스 헤더를 검증할 수 있습니다. 일괄 읽기는 고유하게 요청된 각 id마다 순서가 지정된 SessionTitleObservationResult 하나를 반환합니다. 운영 실패는 해당 id에 국한되지만, 취소는 전체 작업을 거부합니다.
/** Latest folded title bound to the same session-header observation. */
interface SessionTitleObservation {
/** Cloned header selected with the event log used for the title fold. */
session: SessionHeader
/** Latest title snapshot, absent when the observed log has no title. */
title?: SessionTitleSnapshot
}/** One ordered result from a batch title observation. */
type SessionTitleObservationResult =
| {
/** Requested session id. */
sessionId: SessionId
/** Successful atomic header/title observation. */
status: 'fulfilled'
/** Header and optional latest title from one logical source. */
value: SessionTitleObservation
}
| {
/** Requested session id. */
sessionId: SessionId
/** Operational failure isolated to this session. */
status: 'rejected'
/** Original failure from logical-source resolution or title folding. */
reason: unknown
}/** Lightweight metadata for one event within a logical session. */
interface SessionEventRecord {
/** Session that owns the event. */
sessionId: SessionId
/** Monotonic event seq within the session. */
seq: number
/** Discriminant of the session event. */
type: SessionEventType
/** Event timestamp in Unix epoch milliseconds. */
time: number
/** Event placement in the folded session surface. */
surface: SessionEventSurface
}제공자 독립 필터와 문서
세션 및 이벤트 필터 배열은 AND로 결합되며, 하나의 목록 절 내 값은 OR로 결합됩니다. 범위는 양 끝을 포함합니다. 이벤트 text 절은 전문 검색 제공자와 독립적으로 추출된 의미 텍스트에 대해 수행하는 리터럴 Unicode 대소문자 비구분, 공백 유연 정규식 스캔입니다.
/**
* One logical-session predicate. A filter array is ANDed; `values` within a
* clause are ORed.
*/
type SessionResultFilter =
| { kind: 'id'; values: readonly SessionId[] }
| { kind: 'cwd'; values: readonly (string | null)[] }
| ({ kind: 'created-at' } & SessionResultRange)
| { kind: 'parent'; values: readonly (SessionId | null)[] }
| { kind: 'availability'; values: readonly SessionAvailability[] }/**
* One event predicate. A filter array is ANDed; list-valued clauses are ORed.
* Text is a literal, case-insensitive, whitespace-flexible semantic-text scan.
*/
type SessionEventResultFilter =
| ({ kind: 'seq' } & SessionResultRange)
| ({ kind: 'time' } & SessionResultRange)
| { kind: 'type'; values: readonly SessionEventType[] }
| { kind: 'surface'; values: readonly SessionEventSurface[] }
| { kind: 'text'; text: string }/** Searchable semantic document derived from one session event. */
interface SessionEventSearchDocument extends SessionEventRecord {
/** First-party semantic text used by scan filters and full-text indexes. */
text: string
}ctx.sessionQuery.filterSessions(filters)는 전체 논리 코퍼스에 SessionResultFilter를 적용하고, ctx.sessionQuery.filterEvents(sessionId, filters)는 일치하는 문서를 seq 오름차순으로 반환합니다. 메시지, 추론, 도구 호출/결과, 차단된 프롬프트, 할 일 및 실패/상태 세부 정보는 의미 텍스트에 기여하지만, 구조 이벤트와 스트림 청크는 기여하지 않습니다.
전문 검색 페이지
결합된 ctx.sessionQuery 추상 심에는 두 가지 전문 검색 범위가 있습니다. searchSessions()는 가장 강하게 일치하는 이벤트별로 코퍼스를 그룹화하고, searchEvents()는 하나의 세션을 검색합니다. 요청은 불투명 커서를 정규화된 쿼리, 메타데이터 필터 및 제한에 바인딩합니다. 이벤트 텍스트 스캔은 의도적으로 제공자 메타데이터 필터에 포함되지 않습니다.
/** Provider-owned opaque continuation token returned by session search. */
type SessionSearchCursor = Branded<'SessionSearchCursor'>/** Cross-session full-text search request. */
interface SessionSearchRequest {
/** Full-text query interpreted as data, never executable FTS syntax. */
query: string
/** Logical-session predicates applied before event ranking. */
sessionFilters?: readonly SessionResultFilter[]
/** Event predicates applied before event ranking. */
eventFilters?: readonly SessionEventMetadataFilter[]
/** Maximum sessions in this page. */
limit?: number
/** Opaque cursor returned for the identical normalized request. */
cursor?: SessionSearchCursor
}/** Within-session full-text search request. */
interface SessionEventSearchRequest {
/** Session whose live-preferred logical log is searched. */
sessionId: SessionId
/** Full-text query interpreted as data, never executable FTS syntax. */
query: string
/** Event predicates applied before ranking. */
filters?: readonly SessionEventMetadataFilter[]
/** Maximum events in this page. */
limit?: number
/** Opaque cursor returned for the identical normalized request. */
cursor?: SessionSearchCursor
}/** One cursor-paginated result page. */
interface SessionSearchPage<T> {
/** Results for this page in contract-defined order. */
items: readonly T[]
/** Opaque continuation cursor, absent on the final page. */
nextCursor?: SessionSearchCursor
}그룹화된 세션 간 적중과 달리, 세션 내 검색은 페이지에 적중이 없더라도 관측된 대상 헤더를 노출해야 합니다.
/** Event-search results bound to the indexed target-session observation. */
interface SessionEventSearchPage extends SessionSearchPage<SessionEventSearchHit> {
/** Cloned target header from the same indexed generation as `items`. */
session: SessionHeader
}/** One event full-text search hit with a bounded plain-text excerpt. */
interface SessionEventSearchHit extends SessionEventRecord {
/** Plain text excerpt selected around the match. */
snippet: string
}/** One grouped cross-session hit, ranked by its strongest matching event. */
interface SessionSearchHit extends SessionRecord {
/** Strongest matching event for this session. */
bestMatch: SessionEventSearchHit
}세션 계보
SessionLineageTrace에는 가장 가까운 부모부터 바깥쪽 순서로 알려진 부모와 재귀적으로 중첩된 직계 자손의 포리스트가 포함됩니다. 완전성 판별자는 알려진 루트와 누락된 부모가 서로 배타적이도록 합니다.
/** Recursive descendant node in a session-lineage trace. */
interface SessionLineageNode {
/** Detached logical-corpus record for this descendant. */
session: SessionRecord
/** Direct children, each carrying its own recursive descendants. */
descendants: SessionLineageNode[]
}/** Known ancestry and descendants for one logical session. */
type SessionLineageTrace = {
/** Detached record for the session that was traced. */
target: SessionRecord
/** Known parents from the immediate parent outward. */
ancestors: SessionRecord[]
/** Complete known descendant trees rooted at the target's direct children. */
descendants: SessionLineageNode[]
} & (
| {
/** The complete parent chain is present in the logical corpus. */
complete: true
/** Detached record at the top of the complete lineage. */
root: SessionRecord
}
| {
/** The parent chain leaves the visible logical corpus. */
complete: false
/** First parent id that is not present in the logical corpus. */
unresolvedParentId: SessionId
}
)범위가 제한된 이벤트 읽기
요청은 원시 seq 하나와 선택적 인접 개수를 지정합니다. 결과는 가용성 플래그 대신 SessionHeader를 포함하므로, 알려진 라이브 대상은 영속성 상태와 독립적으로 유지될 수 있습니다.
/** Request for one event plus raw neighboring log context. */
interface SessionEventReadRequest {
/** Session that owns the target event. */
sessionId: SessionId
/** Target event seq. */
seq: number
/** Number of preceding raw events to include. */
before?: number
/** Number of following raw events to include. */
after?: number
}/** Full target event and a bounded raw-log window. */
interface SessionEventWindow {
/** Cloned header for the live-preferred source read. */
session: SessionHeader
/** Full cloned target event. */
target: SessionEvent
/** Full cloned events from `startSeq` through `endSeq`. */
events: SessionEvent[]
/** First seq included in `events`. */
startSeq: number
/** Last seq included in `events`. */
endSeq: number
}이벤트 관계
이벤트 추적은 위치적 표면 대체와 소스로 인용된 이벤트를 구분합니다. 모든 seq 목록에는 직접 링크가 포함되지만, replacementChain는 대상에서 최종 위치적 대체까지의 즉시 대체자를 따릅니다.
/** Request for direct surface replacements and relationships to cited source events around one event. */
interface SessionEventTraceRequest {
/** Session that owns the target event. */
sessionId: SessionId
/** Target event seq. */
seq: number
}/** Direct surface replacements and relationships to cited source events for one event. */
interface SessionEventTrace {
/** Lightweight target record. */
target: SessionEventRecord
/** Immediate positional replacement event, when the target was shadowed. */
replacedBy?: number
/** Positional replacers from the immediate replacement to the final replacement. */
replacementChain: number[]
/** Surface nodes directly removed when the target itself performed a replacement. */
replacedEventSeqs: number[]
/** Earlier events cited directly as sources, in their recorded order. */
sourceEventSeqs: number[]
/** Later events that directly cite the target as a source, in log order. */
derivedEventSeqs: number[]
}/** Event relationships bound to the same session-header observation. */
interface SessionEventTraceObservation extends SessionEventTrace {
/** Cloned header selected with the event log used for the trace. */
session: SessionHeader
}오류
닫힌 코드 유니온은 요청 검증, 누락된 대상, 잘못된 형식의 표면 로그, 선택적 백엔드 실패, 배포에서 비활성화된 검색 및 모순된 소스 메타데이터를 구분합니다.
/** Stable machine-routable failure taxonomy for session reads, traces, and search. */
type SessionQueryErrorCode =
| 'SESSION_QUERY_ABORTED'
| 'SESSION_QUERY_CORRUPT_SESSION'
| 'SESSION_QUERY_EVENT_NOT_FOUND'
| 'SESSION_QUERY_INDEX_FAILED'
| 'SESSION_QUERY_INVALID_CONFIG'
| 'SESSION_QUERY_INVALID_CURSOR'
| 'SESSION_QUERY_INVALID_FILTER'
| 'SESSION_QUERY_INVALID_LIMIT'
| 'SESSION_QUERY_INVALID_QUERY'
| 'SESSION_QUERY_INVALID_LINEAGE'
| 'SESSION_QUERY_INVALID_SURFACE'
| 'SESSION_QUERY_INVALID_WINDOW'
| 'SESSION_QUERY_PERSISTENCE_FAILED'
| 'SESSION_QUERY_SEARCH_DISABLED'
| 'SESSION_QUERY_SESSION_NOT_FOUND'
| 'SESSION_QUERY_STALE_CURSOR'
| 'SESSION_QUERY_SOURCE_CONFLICT'Cordis API
scripts/gen-cordis-catalog.ts에 의해 소스에서 생성됩니다(doc-sync에서 pnpm run verify-cordis-catalog로 최신 상태를 검증하며, pnpm run gen-cordis-catalog로 다시 생성). 이 섹션은 페이지의 두 언어 측면에서 바이트 단위로 동일합니다. 시그니처 블록은 ts cordis-catalog 펜스를 사용하고 원본 소스 JSDoc을 유지합니다. 디스패치 모드는 입문서에 정의되어 있으며, 프레임워크에서 상속된 ctx API는 cordis-api/inherited.md에 있습니다.
ctx.sessionQuery — SessionQueryEngine(추상 이음새)
통합된 라이브 우선 세션 쿼리 서비스입니다.
정확한 읽기, 필터 및 추적은 백엔드에 독립적인 구체적 동작입니다. 백엔드는 동일한 ctx.sessionQuery 서비스에서 전문 관측, 조정, 순위 지정, 커서 생성 및 쿼리 실행을 구현합니다.
/**
* Search the live-preferred logical corpus and group by session.
* @param request - query text, metadata filters, page size, and cursor.
* @param exec - optional cancellation control.
* @returns session hits ranked by their strongest matching event.
*/
abstract searchSessions( request: SessionSearchRequest, exec?: SessionSearchExecContext, ): Promise<SessionSearchPage<SessionSearchHit>>
/**
* Search events within one live-preferred logical session.
* @param request - target session, query text, filters, page size, and cursor.
* @param exec - optional cancellation control.
* @returns matching event hits and their target header from one indexed generation.
*/
abstract searchEvents( request: SessionEventSearchRequest, exec?: SessionSearchExecContext, ): Promise<SessionEventSearchPage>
/**
* List the complete logical corpus using live-preferred records.
* @param signal - optional cancellation for persistence listing.
* @returns deterministic newest-first cloned session records.
*/
listSessions(signal?: AbortSignal): Promise<SessionRecord[]>
/**
* Read and replay-validate one complete logical session log without making it live.
* @param sessionId - live or persisted session id to read.
* @returns cloned header and complete raw event log from one observation.
* @throws when persistence, header compatibility, or replay validation fails.
*/
async readSession(sessionId: SessionId): Promise<SessionLogSnapshot>
/**
* Filter the complete logical corpus with provider-independent predicates.
* @param filters - ANDed session metadata and availability clauses.
* @param signal - optional cancellation for persistence listing.
* @returns matching cloned records in deterministic newest-first order.
*/
async filterSessions( filters: readonly SessionResultFilter[], signal?: AbortSignal, ): Promise<SessionRecord[]>
/**
* Fold the latest log-backed title from one live-preferred logical session.
* @param sessionId - live or persisted session id to read.
* @param signal - optional cancellation for source resolution and title folding.
* @returns latest title snapshot, or `undefined` when the log has no title event.
*/
async readTitle( sessionId: SessionId, signal?: AbortSignal, ): Promise<SessionTitleSnapshot | undefined>
/**
* Fold the latest title and return its source header from one corpus observation.
* @param sessionId - live or persisted session id to read.
* @param signal - optional cancellation for source resolution and title folding.
* @returns cloned source header and optional latest title snapshot.
*/
async readTitleSnapshot( sessionId: SessionId, signal?: AbortSignal, ): Promise<SessionTitleObservation>
/**
* Fold titles for unique sessions from one cancellable corpus observation.
*
* Results preserve first-occurrence input order. Operational failures stay
* isolated per session, while cancellation rejects the complete operation.
* @param sessionIds - live or persisted session ids to observe.
* @param signal - optional cancellation shared by all source reads.
* @returns one fulfilled or rejected result per unique requested id.
*/
async readTitleSnapshots( sessionIds: readonly SessionId[], signal?: AbortSignal, ): Promise<SessionTitleObservationResult[]>
/**
* List lightweight raw-log event records for one logical session.
* @param sessionId - live-preferred session id to read.
* @returns event records in ascending seq order.
*/
async listEvents(sessionId: SessionId): Promise<SessionEventRecord[]>
/**
* Scan first-party semantic event documents with provider-independent filters.
* @param sessionId - live-preferred session id to scan.
* @param filters - ANDed metadata and literal-text predicates.
* @returns matching semantic documents in ascending seq order.
*/
async filterEvents( sessionId: SessionId, filters: readonly SessionEventResultFilter[], ): Promise<SessionEventSearchDocument[]>
/**
* Read one session's complete current model surface from one corpus observation.
* @param sessionId - live-preferred session id to read.
* @returns cloned header, current surface, and the last sequence number included in the raw-log capture.
* @throws when source resolution fails or the session surface is invalid.
*/
async readSurface(sessionId: SessionId): Promise<SessionSurfaceSnapshot>
/**
* Trace known ancestry and descendants from one corpus observation.
* @param sessionId - logical session id to trace.
* @param signal - optional cancellation for persistence listing.
* @returns a complete lineage or the first parent that could not be resolved.
* @throws when corpus resolution fails, the target is absent, or its known ancestry cycles.
*/
async traceSession(sessionId: SessionId, signal?: AbortSignal): Promise<SessionLineageTrace>
/**
* Trace one event's direct positional replacements and cited source events.
* @param request - target session id and event seq.
* @param signal - optional cancellation for persisted source resolution.
* @returns source header, direct links, and the target's positional replacement chain.
* @throws when source resolution fails, the target is absent, or surface/source-event validation fails.
*/
async traceEvent(request: SessionEventTraceRequest, signal?: AbortSignal): Promise<SessionEventTraceObservation>
/**
* Read one full event plus a bounded raw-log context window.
* @param request - target session/seq and context sizes.
* @param signal - optional cancellation for persisted source resolution.
* @returns cloned target and neighboring events.
*/
async readEvent(request: SessionEventReadRequest, signal?: AbortSignal): Promise<SessionEventWindow>