session.ts 6.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. /**
  2. * The outward session face. Feature packages never see the concrete Session
  3. * class: components read lifecycle state through `useSession` (the
  4. * ObservableSnapshot half), and orchestration code calls the behavior verbs
  5. * below — nothing else. Widening this interface is the explicit act of
  6. * widening what features may do to a session (and what every test fixture
  7. * must stub); implementation-internal entry points (history staging, wire-frame
  8. * dispatch) stay on the class, invisible out here.
  9. */
  10. import type { AttachmentIdType, ImageAttachmentRef } from '@deepseek-ai/dsh-attachment'
  11. import type { MessageId } from '@deepseek-ai/dsh-llm/brand'
  12. import type { SessionId } from '@deepseek-ai/dsh-session/types'
  13. import type { RemoteResult } from '@deepseek-ai/dsh-typert-protocol'
  14. import type { ObservableSnapshot } from '@deepseek-ai/dsh-client-store'
  15. import type { PromptContentPart, QueueAction, SessionRequestId } from '../../types.ts'
  16. import type { PendingSubmissionImage, SessionSnapshot } from './snapshot.ts'
  17. /**
  18. * Why a local submission echo left the snapshot: `observed` when its durable
  19. * `user/message` event or host queue occurrence arrived (with the admitted
  20. * image references in prompt order), `failed` when the prompt was rejected,
  21. * threw, or was aborted before acceptance.
  22. */
  23. export type PendingSubmissionRetirement =
  24. | { readonly reason: 'observed'; readonly attachments: readonly ImageAttachmentRef[] }
  25. | { readonly reason: 'failed' }
  26. /** Input registering one local submission echo ahead of its prompt call. */
  27. export interface BeginSubmissionInput {
  28. /** Delivery mode used with the upcoming prompt. */
  29. readonly mode: 'queue' | 'steer'
  30. /** Prompt text exactly as the upcoming prompt will send it. */
  31. readonly text: string
  32. /** Ordered image previews matching the upcoming prompt's image parts. */
  33. readonly images: readonly PendingSubmissionImage[]
  34. /** Settlement callback fired exactly once when the echo retires. */
  35. readonly onRetire?: (retirement: PendingSubmissionRetirement) => void
  36. }
  37. /** One registered submission echo: the identity its prompt must carry, and the pre-prompt escape hatch. */
  38. export interface SubmissionHandle {
  39. /** The prompt RPC identity; pass it to {@link ISession.prompt}. */
  40. readonly requestId: SessionRequestId
  41. /** Retire the echo as failed when the caller cannot reach prompt() (serialization failure); no-op after any other settlement. */
  42. abandon(): void
  43. }
  44. /** Key-addressed projection read face (the useProjection resolution path; see ProjectionValueStore). */
  45. export interface ProjectionsFace {
  46. /**
  47. * The identity-stable bare observable for one projection key (absence is
  48. * an `undefined` snapshot, never a missing face).
  49. * @param key - projection key.
  50. * @returns the key's value face.
  51. */
  52. faceOf(key: string): ObservableSnapshot<unknown>
  53. }
  54. /** Identity plus the behavior verbs features may invoke on a session. */
  55. export interface ISession {
  56. /** The session's host identity (agent id — same axis). */
  57. readonly sessionId: SessionId
  58. /** Host-computed projection values by key (the useProjection seat). */
  59. readonly projections: ProjectionsFace
  60. /**
  61. * Register one local submission echo in `snapshot.pendingSubmissions`,
  62. * synchronously, before the caller serializes and sends the prompt. The
  63. * echo retires when a durable `user/message` event or queue occurrence
  64. * carrying the returned identity arrives, or when the identified prompt
  65. * call fails.
  66. * @param input - echo content and the optional settlement callback.
  67. * @returns the minted identity for {@link prompt} plus the pre-prompt abandon path.
  68. */
  69. beginSubmission(input: BeginSubmissionInput): SubmissionHandle
  70. /**
  71. * Send a prompt into the session.
  72. * @param content - text plus browser-owned temporary image uploads.
  73. * @param mode - 'queue' appends a turn; 'steer' interrupts the running one.
  74. * @param signal - optional caller cancellation for the complete admission round-trip.
  75. * @param requestId - identity from {@link beginSubmission}; a failed identified prompt retires its echo.
  76. * @returns acceptance, or the business error (also mirrored into snapshot.promptError).
  77. */
  78. prompt(
  79. content: PromptContentPart[],
  80. mode: 'queue' | 'steer',
  81. signal?: AbortSignal,
  82. requestId?: SessionRequestId,
  83. ): Promise<RemoteResult<{ accepted: true }>>
  84. /**
  85. * Resolve one durable image referenced by this session.
  86. * @param attachmentId - opaque id found in the folded session log.
  87. * @returns the authenticated reference and decoded bytes.
  88. */
  89. readAttachment(
  90. attachmentId: AttachmentIdType,
  91. ): Promise<RemoteResult<{ attachment: ImageAttachmentRef; data: Uint8Array }>>
  92. /**
  93. * Apply one edit, remove, or strict steer action to a still-pending queue occurrence.
  94. * @param itemId - agent-owned inbox occurrence identity.
  95. * @param action - requested queue operation.
  96. * @returns acceptance, or a business/transport error.
  97. */
  98. updateQueue(itemId: MessageId, action: QueueAction): Promise<RemoteResult<{ accepted: true }>>
  99. /**
  100. * Cancel the running turn. Pending queued work remains and resumes in FIFO
  101. * order after the Host reaches cancellation quiescence.
  102. * @returns acceptance, or the business error.
  103. */
  104. cancel(): Promise<RemoteResult<{ accepted: true }>>
  105. /**
  106. * Rename this session (explicit user title; pins it against automatic
  107. * regeneration).
  108. * @param title - raw title text (the host normalizes acceptance).
  109. * @returns the normalized accepted title and its event seq, or the business error.
  110. */
  111. rename(title: string): Promise<RemoteResult<{ title: string; seq: number }>>
  112. /**
  113. * Extend the history window backwards (older messages pagination).
  114. * @returns completion; failures land in snapshot.openState/loadingOlder.
  115. */
  116. loadOlder(): Promise<void>
  117. /**
  118. * Page history backwards until the window covers `seq` (inclusive) — the
  119. * turn-jump loader. Repeated calls while a jump is paging lower its shared
  120. * target and return the in-flight completion; `snapshot.loadingOlder` is
  121. * the busy signal for the whole jump.
  122. * @param seq - durable event seq the window must reach (a turn's `turn/start` seq).
  123. * @returns completion once covered, exhausted, superseded, or failed soft.
  124. */
  125. loadThrough(seq: number): Promise<void>
  126. /**
  127. * Execute one slash-command line against this session's agent — pure
  128. * admission semantics (the host executor durably logs the lifecycle).
  129. * @param line - the full command line, leading slash included.
  130. * @returns the admission result, or the Remote face's error branch.
  131. */
  132. command(line: string): Promise<RemoteResult<{ matched: boolean }>>
  133. }
  134. /**
  135. * The full outward face: behavior verbs plus the Session lifecycle read side
  136. * (the `useSession` hook source). This is the type carried by
  137. * `SessionBinding.session` and the provide channel.
  138. */
  139. export type SessionFace = ISession & ObservableSnapshot<SessionSnapshot>