refactor(api): converge the Remote failure vocabulary and client surface

Single RemoteError with a merge-extensible, domain-prefixed code map;
owners throw at the failure point; streams surface marked failures;
clients consume ctx.remote directly with isRemoteFailure as the only
discrimination point and construct no failure instances.
This commit is contained in:
imccyu committed 2026-08-28 22:37:36 +08:00
1 parent 12d7b4ed0c
commit 804b1ffbfc
252 files changed
+3182 -3832

No files matched your search

@@ -1,29 +0,0 @@
/** Client operation results spanning the Session and subagent Remote calls. */
import type { RpcError } from '@deepseek-ai/dsh-client-connection/client'
import type { SubagentControlError } from '@deepseek-ai/dsh-subagent/client'
import type { SessionError } from '../../types.ts'
/** Failure surfaced by the Client Session object layer. */
export type ClientFailure = RpcError | SessionError | SubagentControlError
/** Success or failure returned by a Client Session operation. */
export type ClientResult<T> =
| { readonly ok: true; readonly value: T }
| { readonly ok: false; readonly error: ClientFailure }
/**
* Fold a rejected carrier operation into the Client Session failure vocabulary.
* @param error - rejection from a Remote or local carrier call.
* @returns the failure branch of a Client Session result.
*/
export function transportResult<T>(error: unknown): ClientResult<T> {
return {
ok: false,
error: {
code: 'internal',
message: error instanceof Error ? error.message : String(error),
details: {},
},
}
}
@@ -13,7 +13,6 @@ import type { SessionId } from '@deepseek-ai/dsh-session/types'
import type { RemoteResult } from '@deepseek-ai/dsh-typert-protocol'
import type { ObservableSnapshot } from '@deepseek-ai/dsh-client-store'
import type { PromptContentPart, QueueAction, SessionRequestId } from '../../types.ts'
import type { ClientResult } from './result.ts'
import type { PendingSubmissionImage, SessionSnapshot } from './snapshot.ts'
/**
@@ -84,7 +83,7 @@ export interface ISession {
mode: 'queue' | 'steer',
signal?: AbortSignal,
requestId?: SessionRequestId,
): Promise<ClientResult<{ accepted: true }>>
): Promise<RemoteResult<{ accepted: true }>>
/**
* Resolve one durable image referenced by this session.
* @param attachmentId - opaque id found in the folded session log.
@@ -92,27 +91,27 @@ export interface ISession {
*/
readAttachment(
attachmentId: AttachmentIdType,
): Promise<ClientResult<{ attachment: ImageAttachmentRef; data: Uint8Array }>>
): Promise<RemoteResult<{ attachment: ImageAttachmentRef; data: Uint8Array }>>
/**
* Apply one edit, remove, or strict steer action to a still-pending queue occurrence.
* @param itemId - agent-owned inbox occurrence identity.
* @param action - requested queue operation.
* @returns acceptance, or a business/transport error.
*/
updateQueue(itemId: MessageId, action: QueueAction): Promise<ClientResult<{ accepted: true }>>
updateQueue(itemId: MessageId, action: QueueAction): Promise<RemoteResult<{ accepted: true }>>
/**
* Cancel the running turn. Pending queued work remains and resumes in FIFO
* order after the Host reaches cancellation quiescence.
* @returns acceptance, or the business error.
*/
cancel(): Promise<ClientResult<{ accepted: true }>>
cancel(): Promise<RemoteResult<{ accepted: true }>>
/**
* Rename this session (explicit user title; pins it against automatic
* regeneration).
* @param title - raw title text (the host normalizes acceptance).
* @returns the normalized accepted title and its event seq, or the business error.
*/
rename(title: string): Promise<ClientResult<{ title: string; seq: number }>>
rename(title: string): Promise<RemoteResult<{ title: string; seq: number }>>
/**
* Extend the history window backwards (older messages pagination).
* @returns completion; failures land in snapshot.openState/loadingOlder.
@@ -8,10 +8,10 @@ import type { Context } from '@deepseek-ai/cordis'
import type { SubagentAddress } from '@deepseek-ai/dsh-subagent/client'
import type { SessionId } from '@deepseek-ai/dsh-session/types'
import type { WorkspaceId } from '@deepseek-ai/dsh-workspace/types'
import type { RemoteResult } from '@deepseek-ai/dsh-typert-protocol'
import type { AgentContext } from '../scope.ts'
import type { SessionSearchResultItem } from '../sessions/manager.ts'
import type { SessionBinding, SessionListState } from '../sessions/service.ts'
import type { ClientResult } from './result.ts'
import type { SessionFace } from './session.ts'
import type { ObservableSnapshot } from '@deepseek-ai/dsh-client-store'
@@ -83,7 +83,7 @@ export interface ISessions {
search(
query: string,
signal: AbortSignal,
): Promise<ClientResult<{ items: SessionSearchResultItem[]; hasMore: boolean }>>
): Promise<RemoteResult<{ items: SessionSearchResultItem[]; hasMore: boolean }>>
/**
* Fork a session from a completed-turn prefix of the source; on resolution
* the child is in the list store and `open()` can target it.
@@ -3,8 +3,8 @@ import type { ContentBlock } from '@deepseek-ai/dsh-llm/types'
import type { MessageId } from '@deepseek-ai/dsh-llm/brand'
import type { SessionId } from '@deepseek-ai/dsh-session/types'
import type { SubagentAddress } from '@deepseek-ai/dsh-subagent/client'
import type { RemoteFailure } from '@deepseek-ai/dsh-typert-protocol'
import type { SessionRequestId } from '../../types.ts'
import type { ClientFailure } from './result.ts'
/** One transient inbox occurrence from the authoritative queue snapshot. */
export interface QueuedMessage {
@@ -53,7 +53,7 @@ export type OpenState = 'cold' | 'loading' | 'open' | 'error'
/** Send/stop failure surfaced by Session consumers. */
export interface PromptError {
readonly op: 'send' | 'stop'
readonly error: ClientFailure
readonly error: RemoteFailure
}
/** Immutable Session lifecycle and control snapshot. */
@@ -70,7 +70,7 @@ export interface SessionSnapshot {
} | null
readonly removed: boolean
readonly openState: OpenState
readonly openError: ClientFailure | null
readonly openError: RemoteFailure | null
readonly hasMore: boolean
readonly loadingOlder: boolean
readonly promptError: PromptError | null