Merge origin/master into worktree/continue-generation-after-failure
This commit is contained in:
commit
2fb4ea0bec
1063 files changed
+21746
-10156
No files matched your search
@@ -6,7 +6,7 @@ import type { Context } from '@deepseek-ai/cordis'
|
||||
import type {} from '@deepseek-ai/dsh-agent-preset-registry'
|
||||
import type { ImageAttachmentLimits } from '@deepseek-ai/dsh-attachment'
|
||||
import type { Session, SessionEvent, SessionHeader, SessionId } from '@deepseek-ai/dsh-session'
|
||||
import type { ProjectionSnapshot } from '@deepseek-ai/dsh-session-projection'
|
||||
import type { ProjectionHandle, ProjectionSnapshot } from '@deepseek-ai/dsh-session-projection'
|
||||
import type {} from '@deepseek-ai/dsh-session-projection-cache'
|
||||
import { SessionQueryError, type SessionRecord, type SessionSearchCursor } from '@deepseek-ai/dsh-session-query'
|
||||
import { RemoteError } from '@deepseek-ai/dsh-typert-protocol'
|
||||
@@ -76,6 +76,8 @@ export function truncateUnicodeCodePoints(value: string, maximum: number): strin
|
||||
|
||||
/** Owns list projection registration, bounded cold summaries, and authorized search. */
|
||||
export class ApiSessionList {
|
||||
private listMetadata!: ProjectionHandle<SessionListMetadata>
|
||||
|
||||
/**
|
||||
* @param ctx - Host context carrying Session, query, persistence, and projection services.
|
||||
* @param workSliceMs - Resolved positive integral list-work budget in milliseconds.
|
||||
@@ -87,7 +89,7 @@ export class ApiSessionList {
|
||||
* @returns when all required registrations are ready.
|
||||
*/
|
||||
async initialize(): Promise<void> {
|
||||
await this.ctx.sessionProjections.register<'sessionListMetadata', SessionListMetadata>({
|
||||
this.listMetadata = await this.ctx.sessionProjections.register<'sessionListMetadata', SessionListMetadata>({
|
||||
key: 'sessionListMetadata',
|
||||
stateSchema: sessionListMetadataSchema,
|
||||
init: () => ({ blank: true, lastPromptAt: null }),
|
||||
@@ -111,19 +113,25 @@ export class ApiSessionList {
|
||||
|
||||
/**
|
||||
* Build one current attached-Session summary.
|
||||
* Blankness and recency come from the `sessionListMetadata` handle; projection
|
||||
* hints carry every summary key computed through `snapshot`. The first call
|
||||
* for a Session computes these projections over its whole in-memory log, and
|
||||
* later calls advance them incrementally. The handle read and the hint with
|
||||
* the same key come from one cell; the handle read does not depend on any
|
||||
* other unit's view.
|
||||
* @param session - attached Session to summarize.
|
||||
* @returns current list metadata and available projections.
|
||||
*/
|
||||
summaryFor(session: Session): SessionSummary {
|
||||
const metadata = this.listMetadata.stateOf(session)
|
||||
const projections = this.projectionsFor(session.header, session)
|
||||
const metadata = projections?.values.sessionListMetadata
|
||||
return {
|
||||
sessionId: session.id,
|
||||
updatedAt: updatedAt(session.header, metadata),
|
||||
agentAvailable: this.ctx.agents.get(session.id)?.session === session,
|
||||
formatStatus: 'current',
|
||||
running: this.ctx.agents.get(session.id)?.status === 'running',
|
||||
blank: metadata?.blank ?? session.seq === 0,
|
||||
blank: metadata.blank,
|
||||
...listFields(session.header),
|
||||
...(projections === undefined ? {} : { projections }),
|
||||
}
|
||||
@@ -304,9 +312,9 @@ export class ApiSessionList {
|
||||
// itself summary-excluded.
|
||||
const keys = this.ctx.sessionProjections.summaryKeys()
|
||||
if (session !== undefined) {
|
||||
// The live registry computed the block for this Session: its watermark
|
||||
// The live registry computes the block for this Session: its watermark
|
||||
// shares the sequence space of the Session's baselines and frames.
|
||||
return hintsOf('sequenced', this.ctx.sessionProjections.cachedSnapshot(session, keys))
|
||||
return hintsOf('sequenced', this.ctx.sessionProjections.snapshot(session, keys))
|
||||
}
|
||||
// A cold row reads the persisted cache by header alone; the cache serves
|
||||
// seeded and unseeded lifecycles alike because a listing never seeds a
|
||||
@@ -334,8 +342,8 @@ function hintsOf(
|
||||
block: ProjectionSnapshot | undefined,
|
||||
): SessionProjectionHints | undefined {
|
||||
if (block === undefined || Object.keys(block.values).length === 0) return undefined
|
||||
// Listing hints contain every summary wire value the source currently holds
|
||||
// but remain partial: missing cells and cache rows are never materialized here.
|
||||
// Listing hints contain every summary wire value the source holds; cached
|
||||
// hints remain partial because missing cache rows are never folded here.
|
||||
return { kind, asOfSeq: block.asOfSeq, values: block.values }
|
||||
}
|
||||
|
||||
|
||||
@@ -38,9 +38,10 @@ export interface SessionListMetadata {
|
||||
}
|
||||
|
||||
/**
|
||||
* Every available summary wire value a Session-list row carries as partial,
|
||||
* possibly stale hints. The block omits the keys whose unit declares
|
||||
* `summary: false`. `kind` and `asOfSeq` are independent facts: `kind` says
|
||||
* Summary wire values a Session-list row carries. A `sequenced` block carries
|
||||
* every summary key computed at its `asOfSeq`; a `cached` block carries the
|
||||
* values the persisted cache holds and may omit keys or trail the Session.
|
||||
* The block omits the keys whose unit declares `summary: false`. `kind` and `asOfSeq` are independent facts: `kind` says
|
||||
* which sequence space `asOfSeq` belongs to, and therefore how a client may
|
||||
* merge the block; `asOfSeq` is the producer's watermark in that space.
|
||||
*/
|
||||
|
||||
Reference in new issue
Block a user